提交 f68325a8 编写于 作者: J Jack Morgenstein 提交者: Yang Yingliang

IB/mlx4: Fix memory leak in add_gid error flow

commit eaad647e upstream.

In procedure mlx4_ib_add_gid(), if the driver is unable to update the FW
gid table, there is a memory leak in the driver's copy of the gid table:
the gid entry's context buffer is not freed.

If such an error occurs, free the entry's context buffer, and mark the
entry as available (by setting its context pointer to NULL).

Fixes: e26be1bf ("IB/mlx4: Implement ib_device callbacks")
Link: https://lore.kernel.org/r/20200115085050.73746-1-leon@kernel.orgSigned-off-by: NJack Morgenstein <jackm@dev.mellanox.co.il>
Reviewed-by: NParav Pandit <parav@mellanox.com>
Signed-off-by: NLeon Romanovsky <leonro@mellanox.com>
Signed-off-by: NJason Gunthorpe <jgg@mellanox.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 4f4e1ff3
...@@ -246,6 +246,13 @@ static int mlx4_ib_update_gids(struct gid_entry *gids, ...@@ -246,6 +246,13 @@ static int mlx4_ib_update_gids(struct gid_entry *gids,
return mlx4_ib_update_gids_v1(gids, ibdev, port_num); return mlx4_ib_update_gids_v1(gids, ibdev, port_num);
} }
static void free_gid_entry(struct gid_entry *entry)
{
memset(&entry->gid, 0, sizeof(entry->gid));
kfree(entry->ctx);
entry->ctx = NULL;
}
static int mlx4_ib_add_gid(const struct ib_gid_attr *attr, void **context) static int mlx4_ib_add_gid(const struct ib_gid_attr *attr, void **context)
{ {
struct mlx4_ib_dev *ibdev = to_mdev(attr->device); struct mlx4_ib_dev *ibdev = to_mdev(attr->device);
...@@ -306,6 +313,8 @@ static int mlx4_ib_add_gid(const struct ib_gid_attr *attr, void **context) ...@@ -306,6 +313,8 @@ static int mlx4_ib_add_gid(const struct ib_gid_attr *attr, void **context)
GFP_ATOMIC); GFP_ATOMIC);
if (!gids) { if (!gids) {
ret = -ENOMEM; ret = -ENOMEM;
*context = NULL;
free_gid_entry(&port_gid_table->gids[free]);
} else { } else {
for (i = 0; i < MLX4_MAX_PORT_GIDS; i++) { for (i = 0; i < MLX4_MAX_PORT_GIDS; i++) {
memcpy(&gids[i].gid, &port_gid_table->gids[i].gid, sizeof(union ib_gid)); memcpy(&gids[i].gid, &port_gid_table->gids[i].gid, sizeof(union ib_gid));
...@@ -317,6 +326,12 @@ static int mlx4_ib_add_gid(const struct ib_gid_attr *attr, void **context) ...@@ -317,6 +326,12 @@ static int mlx4_ib_add_gid(const struct ib_gid_attr *attr, void **context)
if (!ret && hw_update) { if (!ret && hw_update) {
ret = mlx4_ib_update_gids(gids, ibdev, attr->port_num); ret = mlx4_ib_update_gids(gids, ibdev, attr->port_num);
if (ret) {
spin_lock_bh(&iboe->lock);
*context = NULL;
free_gid_entry(&port_gid_table->gids[free]);
spin_unlock_bh(&iboe->lock);
}
kfree(gids); kfree(gids);
} }
...@@ -346,10 +361,7 @@ static int mlx4_ib_del_gid(const struct ib_gid_attr *attr, void **context) ...@@ -346,10 +361,7 @@ static int mlx4_ib_del_gid(const struct ib_gid_attr *attr, void **context)
if (!ctx->refcount) { if (!ctx->refcount) {
unsigned int real_index = ctx->real_index; unsigned int real_index = ctx->real_index;
memset(&port_gid_table->gids[real_index].gid, 0, free_gid_entry(&port_gid_table->gids[real_index]);
sizeof(port_gid_table->gids[real_index].gid));
kfree(port_gid_table->gids[real_index].ctx);
port_gid_table->gids[real_index].ctx = NULL;
hw_update = 1; hw_update = 1;
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册