From: Guangshuo Li <lgs201920130244@gmail.com>
To: Yishai Hadas <yishaih@nvidia.com>, Jason Gunthorpe <jgg@ziepe.ca>,
Leon Romanovsky <leon@kernel.org>,
Roland Dreier <roland@purestorage.com>,
Jack Morgenstein <jackm@dev.mellanox.co.il>,
linux-rdma@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: Guangshuo Li <lgs201920130244@gmail.com>, stable@vger.kernel.org
Subject: [PATCH v5] IB/mlx4: Fix refcount leak in add_port() error path
Date: Mon, 11 May 2026 20:16:49 +0800 [thread overview]
Message-ID: <20260511121649.770529-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(), several failure paths after kobject_init_and_add() free
struct mlx4_port directly instead of releasing the embedded kobject with
kobject_put(). This leaves the kobject reference count unbalanced and can
lead to incorrect lifetime handling.
Fix this by routing the kobject_init_and_add() failure path through
kobject_put(), and by calling kobject_del() before kobject_put() on
later failure paths after the kobject has been successfully added. Since
the release callback may now be called for partially initialized
mlx4_port objects, make mlx4_port_release() tolerate NULL attribute
arrays.
The duplicated attribute array frees in add_port() are removed, as the
release callback now handles them.
Fixes: c1e7e466120b ("IB/mlx4: Add iov directory in sysfs under the ib device")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
---
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 | 44 ++++++++++++++----------------
1 file changed, 21 insertions(+), 23 deletions(-)
diff --git a/drivers/infiniband/hw/mlx4/sysfs.c b/drivers/infiniband/hw/mlx4/sysfs.c
index b8fa4ecfc961..224a6a1c289d 100644
--- a/drivers/infiniband/hw/mlx4/sysfs.c
+++ b/drivers/infiniband/hw/mlx4/sysfs.c
@@ -380,12 +380,17 @@ static void mlx4_port_release(struct kobject *kobj)
struct attribute *a;
int i;
- for (i = 0; (a = p->pkey_group.attrs[i]); ++i)
- kfree(a);
- kfree(p->pkey_group.attrs);
- for (i = 0; (a = p->gid_group.attrs[i]); ++i)
- kfree(a);
- kfree(p->gid_group.attrs);
+ if (p->pkey_group.attrs) {
+ for (i = 0; (a = p->pkey_group.attrs[i]); ++i)
+ kfree(a);
+ kfree(p->pkey_group.attrs);
+ }
+
+ if (p->gid_group.attrs) {
+ for (i = 0; (a = p->gid_group.attrs[i]); ++i)
+ kfree(a);
+ kfree(p->gid_group.attrs);
+ }
kfree(p);
}
@@ -623,7 +628,6 @@ static void remove_vf_smi_entries(struct mlx4_port *p)
static int add_port(struct mlx4_ib_dev *dev, int port_num, int slave)
{
struct mlx4_port *p;
- int i;
int ret;
int is_eth = rdma_port_get_link_layer(&dev->ib_dev, port_num) ==
IB_LINK_LAYER_ETHERNET;
@@ -640,7 +644,7 @@ static int add_port(struct mlx4_ib_dev *dev, int port_num, int slave)
kobject_get(dev->dev_ports_parent[slave]),
"%d", port_num);
if (ret)
- goto err_alloc;
+ goto err_put;
p->pkey_group.name = "pkey_idx";
p->pkey_group.attrs =
@@ -649,43 +653,37 @@ 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_del;
}
ret = sysfs_create_group(&p->kobj, &p->pkey_group);
if (ret)
- goto err_free_pkey;
+ goto err_del;
p->gid_group.name = "gid_idx";
p->gid_group.attrs = alloc_group_attrs(show_port_gid_idx, NULL, 1);
if (!p->gid_group.attrs) {
ret = -ENOMEM;
- goto err_free_pkey;
+ goto err_del;
}
ret = sysfs_create_group(&p->kobj, &p->gid_group);
if (ret)
- goto err_free_gid;
+ goto err_del;
ret = add_vf_smi_entries(p);
if (ret)
- goto err_free_gid;
+ goto err_del;
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_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_del:
+ kobject_del(&p->kobj);
-err_alloc:
+err_put:
kobject_put(dev->dev_ports_parent[slave]);
- kfree(p);
+ kobject_put(&p->kobj);
return ret;
}
--
2.43.0
next reply other threads:[~2026-05-11 12:19 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-11 12:16 Guangshuo Li [this message]
2026-05-14 7:10 ` [PATCH v5] IB/mlx4: Fix refcount leak in add_port() error path Leon Romanovsky
2026-05-14 11:17 ` Guangshuo Li
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=20260511121649.770529-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=stable@vger.kernel.org \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.