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"

Reply via email to