From: Guangshuo Li <lgs201920130244@gmail.com>
To: Yishai Hadas <yishaih@nvidia.com>, Jason Gunthorpe <jgg@ziepe.ca>,
Leon Romanovsky <leon@kernel.org>,
Jack Morgenstein <jackm@dev.mellanox.co.il>,
Roland Dreier <roland@purestorage.com>,
linux-rdma@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: Guangshuo Li <lgs201920130244@gmail.com>
Subject: [PATCH v7] IB/mlx4: Fix refcount leak in add_port() error path
Date: Mon, 18 May 2026 10:19:10 +0800 [thread overview]
Message-ID: <20260518021910.972900-1-lgs201920130244@gmail.com> (raw)
After kobject_init_and_add(), the lifetime of the embedded struct
kobject is expected to be managed through the kobject core reference
counting.
In add_port(), failure paths after kobject_init_and_add() must not free
struct mlx4_port directly, because the embedded kobject is then managed
by the kobject core. Freeing it directly leaves the kobject reference
counting unbalanced and can lead to incorrect lifetime handling.
Allocate the pkey and gid attribute arrays before kobject_init_and_add(),
so failures before kobject initialization can be handled by directly
freeing the allocated memory. Once kobject_init_and_add() has been
called, unwind later failures by removing any successfully created sysfs
groups, calling kobject_del(), and then releasing the embedded kobject
with kobject_put().
Fixes: c1e7e466120b ("IB/mlx4: Add iov directory in sysfs under the ib device")
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
---
v7:
- remove already created sysfs groups on add_port() error paths before
deleting and putting the kobject
v6:
- drop the Cc stable tag
- allocate pkey and gid attribute arrays before kobject_init_and_add()
- keep the release callback unchanged by ensuring the attribute arrays
are initialized before kobject_init_and_add()
v5:
- split the add_port() error paths after kobject_init_and_add()
- call kobject_del() before kobject_put() for failures after
kobject_init_and_add() succeeds
v4:
- route all add_port() failures after kobject_init_and_add() through
a single kobject_put() based error path
- remove duplicated attribute array frees from add_port()
- keep mlx4_port_release() tolerant of partially initialized objects
v3:
- make mlx4_port_release() tolerate NULL attribute arrays
- drop the parent kobject reference on the kobject_init_and_add()
failure path before putting the embedded kobject
v2:
- note that the issue was identified by my static analysis tool
- and confirmed by manual review
drivers/infiniband/hw/mlx4/sysfs.c | 45 ++++++++++++++++++------------
1 file changed, 27 insertions(+), 18 deletions(-)
diff --git a/drivers/infiniband/hw/mlx4/sysfs.c b/drivers/infiniband/hw/mlx4/sysfs.c
index b8fa4ecfc961..e688ad66a895 100644
--- a/drivers/infiniband/hw/mlx4/sysfs.c
+++ b/drivers/infiniband/hw/mlx4/sysfs.c
@@ -636,12 +636,6 @@ static int add_port(struct mlx4_ib_dev *dev, int port_num, int slave)
p->port_num = port_num;
p->slave = slave;
- ret = kobject_init_and_add(&p->kobj, &port_type,
- kobject_get(dev->dev_ports_parent[slave]),
- "%d", port_num);
- if (ret)
- goto err_alloc;
-
p->pkey_group.name = "pkey_idx";
p->pkey_group.attrs =
alloc_group_attrs(show_port_pkey,
@@ -649,13 +643,9 @@ static int add_port(struct mlx4_ib_dev *dev, int port_num, int slave)
dev->dev->caps.pkey_table_len[port_num]);
if (!p->pkey_group.attrs) {
ret = -ENOMEM;
- goto err_alloc;
+ goto err_free_port;
}
- ret = sysfs_create_group(&p->kobj, &p->pkey_group);
- if (ret)
- goto err_free_pkey;
-
p->gid_group.name = "gid_idx";
p->gid_group.attrs = alloc_group_attrs(show_port_gid_idx, NULL, 1);
if (!p->gid_group.attrs) {
@@ -663,28 +653,47 @@ static int add_port(struct mlx4_ib_dev *dev, int port_num, int slave)
goto err_free_pkey;
}
+ ret = kobject_init_and_add(&p->kobj, &port_type,
+ kobject_get(dev->dev_ports_parent[slave]),
+ "%d", port_num);
+ if (ret)
+ goto err_put;
+
+ ret = sysfs_create_group(&p->kobj, &p->pkey_group);
+ if (ret)
+ goto err_del;
+
ret = sysfs_create_group(&p->kobj, &p->gid_group);
if (ret)
- goto err_free_gid;
+ goto err_remove_pkey;
ret = add_vf_smi_entries(p);
if (ret)
- goto err_free_gid;
+ goto err_remove_gid;
list_add_tail(&p->kobj.entry, &dev->pkeys.pkey_port_list[slave]);
return 0;
-err_free_gid:
- kfree(p->gid_group.attrs[0]);
- kfree(p->gid_group.attrs);
+err_remove_gid:
+ sysfs_remove_group(&p->kobj, &p->gid_group);
+
+err_remove_pkey:
+ sysfs_remove_group(&p->kobj, &p->pkey_group);
+
+err_del:
+ kobject_del(&p->kobj);
+
+err_put:
+ kobject_put(dev->dev_ports_parent[slave]);
+ kobject_put(&p->kobj);
+ return ret;
err_free_pkey:
for (i = 0; i < dev->dev->caps.pkey_table_len[port_num]; ++i)
kfree(p->pkey_group.attrs[i]);
kfree(p->pkey_group.attrs);
-err_alloc:
- kobject_put(dev->dev_ports_parent[slave]);
+err_free_port:
kfree(p);
return ret;
}
--
2.43.0
next reply other threads:[~2026-05-18 2:28 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-18 2:19 Guangshuo Li [this message]
2026-05-25 14:29 ` Jason Gunthorpe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260518021910.972900-1-lgs201920130244@gmail.com \
--to=lgs201920130244@gmail.com \
--cc=jackm@dev.mellanox.co.il \
--cc=jgg@ziepe.ca \
--cc=leon@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rdma@vger.kernel.org \
--cc=roland@purestorage.com \
--cc=yishaih@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®