Author: jhb Date: Thu Jul 18 14:06:01 2013 New Revision: 253449 URL: http://svnweb.freebsd.org/changeset/base/253449
Log: 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 Modified: head/sys/ofed/drivers/net/mlx4/main.c head/sys/ofed/include/linux/sysfs.h Modified: head/sys/ofed/drivers/net/mlx4/main.c ============================================================================== --- head/sys/ofed/drivers/net/mlx4/main.c Thu Jul 18 07:43:55 2013 (r253448) +++ head/sys/ofed/drivers/net/mlx4/main.c Thu Jul 18 14:06:01 2013 (r253449) @@ -476,11 +476,11 @@ static ssize_t set_port_type(struct devi 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); Modified: head/sys/ofed/include/linux/sysfs.h ============================================================================== --- head/sys/ofed/include/linux/sysfs.h Thu Jul 18 07:43:55 2013 (r253448) +++ head/sys/ofed/include/linux/sysfs.h Thu Jul 18 14:06:01 2013 (r253449) @@ -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; _______________________________________________ svn-src-head@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"