Thread (14 messages) 14 messages, 4 authors, 2018-09-08

Re: [PATCH v3 3/3] IB/ipoib: Log sysfs 'dev_id' accesses from userspace

From: Arseny Maslennikov <hidden>
Date: 2018-09-06 11:38:42
Also in: linux-rdma

On Wed, Sep 05, 2018 at 04:50:35PM +0300, Leon Romanovsky wrote:
On Mon, Sep 03, 2018 at 07:13:16PM +0300, Arseny Maslennikov wrote:
quoted
Signed-off-by: Arseny Maslennikov <redacted>
---
 drivers/infiniband/ulp/ipoib/ipoib_main.c | 38 +++++++++++++++++++++++
 1 file changed, 38 insertions(+)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 30f840f874b3..7386e5bde3d3 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -2386,6 +2386,42 @@ int ipoib_add_pkey_attr(struct net_device *dev)
 	return device_create_file(&dev->dev, &dev_attr_pkey);
 }

+/*
+ * We erroneously exposed the iface's port number in the dev_id
+ * sysfs field long after dev_port was introduced for that purpose[1],
+ * and we need to stop everyone from relying on that.
+ * Let's overload the shower routine for the dev_id file here
+ * to gently bring the issue up.
+ *
+ * [1] https://www.spinics.net/lists/netdev/msg272123.html
+ */
+static ssize_t dev_id_show(struct device *dev,
+			   struct device_attribute *attr, char *buf)
+{
+	struct net_device *ndev = to_net_dev(dev);
+	ssize_t ret = -EINVAL;
+
+	if (ndev->dev_id == ndev->dev_port) {
+		netdev_info_once(ndev,
+			"\"%s\" wants to know my dev_id. "
+			"Should it look at dev_port instead?\n",
+			current->comm);
+		netdev_info_once(ndev,
+			"See Documentation/ABI/testing/sysfs-class-net for more info.\n");
+	}
+
+	ret = sprintf(buf, "%#x\n", ndev->dev_id);
+
+	return ret;
+}
+static DEVICE_ATTR_RO(dev_id);
+
I don't see this field among exposed by IPoIB, why should we expose it now?
To deviate from standard netdev behaviour, which only prints the
field out. Doug wanted this to also print a deprecation message, and
netdev (obviously) does not do that. See below.
quoted
+int ipoib_intercept_dev_id_attr(struct net_device *dev)
+{
+	device_remove_file(&dev->dev, &dev_attr_dev_id);
+	return device_create_file(&dev->dev, &dev_attr_dev_id);
Why isn't enough to rely on netdev code?
Netdev code relies on macros around a *static* function 'netdev_show',
which is defined in net/core/net-sysfs.c; it is not listed in any header
files, and the macros aren't as well. This all leads me to believe it
was not really meant to be used from outside net/core/net-sysfs.

The only way we could use any netdev code here is to set up our own
handler (again), printk() a message, then call netdev_show — but we have
no access to it.

Of course, it also may be that I'm terribly missing a clue.
quoted
+}
+
 static struct net_device *ipoib_add_port(const char *format,
 					 struct ib_device *hca, u8 port)
 {
@@ -2427,6 +2463,8 @@ static struct net_device *ipoib_add_port(const char *format,
 	 */
 	ndev->priv_destructor = ipoib_intf_free;

+	if (ipoib_intercept_dev_id_attr(ndev))
+		goto sysfs_failed;
 	if (ipoib_cm_add_mode_attr(ndev))
 		goto sysfs_failed;
 	if (ipoib_add_pkey_attr(ndev))
--
2.19.0.rc1
  

Attachments

Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help