summaryrefslogtreecommitdiffstats
path: root/sys/ofed
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2013-07-18 14:06:01 +0000
committerjhb <jhb@FreeBSD.org>2013-07-18 14:06:01 +0000
commit45bc92633de9aa07c98b009b403dd3f2ee1cdcb4 (patch)
tree53517fe73ddfbbe7695904e0147a7dc98f5c2a7e /sys/ofed
parent7315f75ab2c4c78e890de3bff455a50d13361ba8 (diff)
downloadFreeBSD-src-45bc92633de9aa07c98b009b403dd3f2ee1cdcb4.zip
FreeBSD-src-45bc92633de9aa07c98b009b403dd3f2ee1cdcb4.tar.gz
Rework the previous fix for the IB vs Ethernet sysctl handler to be more
generic and apply to all sysfs attributes: - Use sysctl_handle_string() instead of reimplementing it. - Remove trailing newline from the current value before passing it to userland and append a newline to the new string value before passing it to the attribute's store function. - Don't leak the temporary buffer if the first error check triggers. - Revert earlier change to mlx4 port mode handler. PR: kern/174213 Submitted by: Garrett Cooper Reviewed by: Shakar Klein @ Mellanox MFC after: 1 week
Diffstat (limited to 'sys/ofed')
-rw-r--r--sys/ofed/drivers/net/mlx4/main.c6
-rw-r--r--sys/ofed/include/linux/sysfs.h32
2 files changed, 18 insertions, 20 deletions
diff --git a/sys/ofed/drivers/net/mlx4/main.c b/sys/ofed/drivers/net/mlx4/main.c
index 11c451a..b0897bf 100644
--- a/sys/ofed/drivers/net/mlx4/main.c
+++ b/sys/ofed/drivers/net/mlx4/main.c
@@ -476,11 +476,11 @@ static ssize_t set_port_type(struct device *dev,
int i;
int err = 0;
- if (!strcmp(buf, "ib"))
+ if (!strcmp(buf, "ib\n"))
info->tmp_type = MLX4_PORT_TYPE_IB;
- else if (!strcmp(buf, "eth"))
+ else if (!strcmp(buf, "eth\n"))
info->tmp_type = MLX4_PORT_TYPE_ETH;
- else if (!strcmp(buf, "auto"))
+ else if (!strcmp(buf, "auto\n"))
info->tmp_type = MLX4_PORT_TYPE_AUTO;
else {
mlx4_err(mdev, "%s is not supported port type\n", buf);
diff --git a/sys/ofed/include/linux/sysfs.h b/sys/ofed/include/linux/sysfs.h
index ca2d71e..4a763c8 100644
--- a/sys/ofed/include/linux/sysfs.h
+++ b/sys/ofed/include/linux/sysfs.h
@@ -75,43 +75,41 @@ sysctl_handle_attr(SYSCTL_HANDLER_ARGS)
struct kobject *kobj;
struct attribute *attr;
const struct sysfs_ops *ops;
- void *buf;
+ char *buf;
int error;
ssize_t len;
kobj = arg1;
attr = (struct attribute *)arg2;
- buf = (void *)get_zeroed_page(GFP_KERNEL);
- len = 1; /* Copy out a NULL byte at least. */
if (kobj->ktype == NULL || kobj->ktype->sysfs_ops == NULL)
return (ENODEV);
- ops = kobj->ktype->sysfs_ops;
+ buf = (char *)get_zeroed_page(GFP_KERNEL);
if (buf == NULL)
return (ENOMEM);
+ ops = kobj->ktype->sysfs_ops;
if (ops->show) {
len = ops->show(kobj, attr, buf);
/*
- * It's valid not to have a 'show' so we just return 1 byte
- * of NULL.
+ * It's valid to not have a 'show' so just return an
+ * empty string.
*/
if (len < 0) {
error = -len;
- len = 1;
if (error != EIO)
goto out;
}
+
+ /* Trim trailing newline. */
+ len--;
+ buf[len] = '\0';
}
- error = SYSCTL_OUT(req, buf, len);
- if (error || !req->newptr || ops->store == NULL)
- goto out;
- len = req->newlen - req->newidx;
- if (len >= PAGE_SIZE)
- error = EINVAL;
- else
- error = SYSCTL_IN(req, buf, len);
- if (error)
+
+ /* Leave one trailing byte to append a newline. */
+ error = sysctl_handle_string(oidp, buf, PAGE_SIZE - 1, req);
+ if (error != 0 || req->newptr == NULL || ops->store == NULL)
goto out;
- ((char *)buf)[len] = '\0';
+ len = strlcat(buf, "\n", PAGE_SIZE);
+ KASSERT(len < PAGE_SIZE, ("new attribute truncated"));
len = ops->store(kobj, attr, buf, len);
if (len < 0)
error = -len;
OpenPOWER on IntegriCloud