Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 18 Jul 2013 14:06:01 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r253449 - in head/sys/ofed: drivers/net/mlx4 include/linux
Message-ID:  <201307181406.r6IE61Xo043113@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201307181406.r6IE61Xo043113>