* [PATCH rdma-next 0/3] Various fixes in RDMA/core
@ 2022-01-18 7:34 Leon Romanovsky
2022-01-18 7:35 ` [PATCH rdma-next 1/3] RDMA/cma: Use correct address when leaving multicast group Leon Romanovsky
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Leon Romanovsky @ 2022-01-18 7:34 UTC (permalink / raw)
To: Jason Gunthorpe; +Cc: Leon Romanovsky, linux-kernel, linux-rdma, Maor Gottlieb
From: Leon Romanovsky <leonro@nvidia.com>
Hi,
This is compilation of unrelated fixes, one is an outcome of syzkaller
report and other two were found in our regression.
Thanks
Leon Romanovsky (1):
RDMA/ucma: Protect mc during concurrent multicast leaves
Maor Gottlieb (2):
RDMA/cma: Use correct address when leaving multicast group
RDMA/core: Set MR type in ib_reg_user_mr
drivers/infiniband/core/cma.c | 61 ++++++++++++++++-----------------
drivers/infiniband/core/ucma.c | 34 ++++++++++++------
drivers/infiniband/core/verbs.c | 1 +
3 files changed, 54 insertions(+), 42 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH rdma-next 1/3] RDMA/cma: Use correct address when leaving multicast group
2022-01-18 7:34 [PATCH rdma-next 0/3] Various fixes in RDMA/core Leon Romanovsky
@ 2022-01-18 7:35 ` Leon Romanovsky
2022-01-28 15:35 ` Jason Gunthorpe
2022-01-18 7:35 ` [PATCH rdma-next 2/3] RDMA/ucma: Protect mc during concurrent multicast leaves Leon Romanovsky
` (2 subsequent siblings)
3 siblings, 1 reply; 6+ messages in thread
From: Leon Romanovsky @ 2022-01-18 7:35 UTC (permalink / raw)
To: Jason Gunthorpe; +Cc: Maor Gottlieb, linux-kernel, linux-rdma
From: Maor Gottlieb <maorg@nvidia.com>
In RoCE we should use cma_iboe_set_mgid and not cma_set_mgid to generate
the mgid, otherwise we will try to remove incorrect address.
Fixes: b5de0c60cc30 ("RDMA/cma: Fix use after free race in roce multicast join")
Signed-off-by: Maor Gottlieb <maorg@nvidia.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
---
drivers/infiniband/core/cma.c | 61 +++++++++++++++++------------------
1 file changed, 30 insertions(+), 31 deletions(-)
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 27a00ce2e101..69c9a12dd14e 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -1830,6 +1830,31 @@ static void cma_release_port(struct rdma_id_private *id_priv)
mutex_unlock(&lock);
}
+static void cma_iboe_set_mgid(struct sockaddr *addr, union ib_gid *mgid,
+ enum ib_gid_type gid_type)
+{
+ struct sockaddr_in *sin = (struct sockaddr_in *)addr;
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
+
+ if (!cma_any_addr(addr) && addr->sa_family == AF_INET6) {
+ memcpy(mgid, &sin6->sin6_addr, sizeof(*mgid));
+ return;
+ }
+
+ memset(mgid, 0, sizeof(*mgid));
+ if (cma_any_addr(addr))
+ return;
+
+ /* AF_INET4 */
+ if (gid_type != IB_GID_TYPE_ROCE_UDP_ENCAP) {
+ mgid->raw[0] = 0xff;
+ mgid->raw[1] = 0x0e;
+ }
+ mgid->raw[10] = 0xff;
+ mgid->raw[11] = 0xff;
+ *(__be32 *)(&mgid->raw[12]) = sin->sin_addr.s_addr;
+}
+
static void destroy_mc(struct rdma_id_private *id_priv,
struct cma_multicast *mc)
{
@@ -1847,10 +1872,13 @@ static void destroy_mc(struct rdma_id_private *id_priv,
ndev = dev_get_by_index(dev_addr->net,
dev_addr->bound_dev_if);
if (ndev) {
+ enum ib_gid_type gid_type;
union ib_gid mgid;
- cma_set_mgid(id_priv, (struct sockaddr *)&mc->addr,
- &mgid);
+ gid_type = cma_get_default_gid_type(
+ id_priv->cma_dev, id_priv->id.port_num);
+ cma_iboe_set_mgid((struct sockaddr *)&mc->addr, &mgid,
+ gid_type);
if (!send_only)
cma_igmp_send(ndev, &mgid, false);
@@ -4702,35 +4730,6 @@ static int cma_join_ib_multicast(struct rdma_id_private *id_priv,
return PTR_ERR_OR_ZERO(mc->sa_mc);
}
-static void cma_iboe_set_mgid(struct sockaddr *addr, union ib_gid *mgid,
- enum ib_gid_type gid_type)
-{
- struct sockaddr_in *sin = (struct sockaddr_in *)addr;
- struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
-
- if (cma_any_addr(addr)) {
- memset(mgid, 0, sizeof *mgid);
- } else if (addr->sa_family == AF_INET6) {
- memcpy(mgid, &sin6->sin6_addr, sizeof *mgid);
- } else {
- mgid->raw[0] =
- (gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP) ? 0 : 0xff;
- mgid->raw[1] =
- (gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP) ? 0 : 0x0e;
- mgid->raw[2] = 0;
- mgid->raw[3] = 0;
- mgid->raw[4] = 0;
- mgid->raw[5] = 0;
- mgid->raw[6] = 0;
- mgid->raw[7] = 0;
- mgid->raw[8] = 0;
- mgid->raw[9] = 0;
- mgid->raw[10] = 0xff;
- mgid->raw[11] = 0xff;
- *(__be32 *)(&mgid->raw[12]) = sin->sin_addr.s_addr;
- }
-}
-
static int cma_iboe_join_multicast(struct rdma_id_private *id_priv,
struct cma_multicast *mc)
{
--
2.34.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH rdma-next 2/3] RDMA/ucma: Protect mc during concurrent multicast leaves
2022-01-18 7:34 [PATCH rdma-next 0/3] Various fixes in RDMA/core Leon Romanovsky
2022-01-18 7:35 ` [PATCH rdma-next 1/3] RDMA/cma: Use correct address when leaving multicast group Leon Romanovsky
@ 2022-01-18 7:35 ` Leon Romanovsky
2022-01-18 7:35 ` [PATCH rdma-next 3/3] RDMA/core: Set MR type in ib_reg_user_mr Leon Romanovsky
2022-01-28 15:40 ` [PATCH rdma-next 0/3] Various fixes in RDMA/core Jason Gunthorpe
3 siblings, 0 replies; 6+ messages in thread
From: Leon Romanovsky @ 2022-01-18 7:35 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: Leon Romanovsky, linux-kernel, linux-rdma, Maor Gottlieb,
syzbot+e3f96c43d19782dd14a7
From: Leon Romanovsky <leonro@nvidia.com>
Partially revert the commit mentioned in the Fixes line to make sure
that allocation and erasing multicast struct are locked.
==================================================================
BUG: KASAN: use-after-free in ucma_cleanup_multicast drivers/infiniband/core/ucma.c:491 [inline]
BUG: KASAN: use-after-free in ucma_destroy_private_ctx+0x914/0xb70 drivers/infiniband/core/ucma.c:579
Read of size 8 at addr ffff88801bb74b00 by task syz-executor.1/25529
CPU: 0 PID: 25529 Comm: syz-executor.1 Not tainted 5.16.0-rc7-syzkaller #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
Call Trace:
<TASK>
__dump_stack lib/dump_stack.c:88 [inline]
dump_stack_lvl+0xcd/0x134 lib/dump_stack.c:106
print_address_description.constprop.0.cold+0x8d/0x320 mm/kasan/report.c:247
__kasan_report mm/kasan/report.c:433 [inline]
kasan_report.cold+0x83/0xdf mm/kasan/report.c:450
ucma_cleanup_multicast drivers/infiniband/core/ucma.c:491 [inline]
ucma_destroy_private_ctx+0x914/0xb70 drivers/infiniband/core/ucma.c:579
ucma_destroy_id+0x1e6/0x280 drivers/infiniband/core/ucma.c:614
ucma_write+0x25c/0x350 drivers/infiniband/core/ucma.c:1732
vfs_write+0x28e/0xae0 fs/read_write.c:588
ksys_write+0x1ee/0x250 fs/read_write.c:643
do_syscall_x64 arch/x86/entry/common.c:50 [inline]
do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80
entry_SYSCALL_64_after_hwframe+0x44/0xae
RIP: 0033:0x7f2fcd207e99
Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b
4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 bc ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f2fcbb7d168 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
RAX: ffffffffffffffda RBX: 00007f2fcd31af60 RCX: 00007f2fcd207e99
RDX: 0000000000000018 RSI: 00000000200000c0 RDI: 0000000000000004
RBP: 00007f2fcd261ff1 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007fff66a135bf R14: 00007f2fcbb7d300 R15: 0000000000022000
</TASK>
Fixes: 95fe51096b7a ("RDMA/ucma: Remove mc_list and rely on xarray")
Reported-by: syzbot+e3f96c43d19782dd14a7@syzkaller.appspotmail.com
Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Maor Gottlieb <maorg@nvidia.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
---
drivers/infiniband/core/ucma.c | 34 +++++++++++++++++++++++-----------
1 file changed, 23 insertions(+), 11 deletions(-)
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index 2b72c4fa9550..9d6ac9dff39a 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -95,6 +95,7 @@ struct ucma_context {
u64 uid;
struct list_head list;
+ struct list_head mc_list;
struct work_struct close_work;
};
@@ -105,6 +106,7 @@ struct ucma_multicast {
u64 uid;
u8 join_state;
+ struct list_head list;
struct sockaddr_storage addr;
};
@@ -198,6 +200,7 @@ static struct ucma_context *ucma_alloc_ctx(struct ucma_file *file)
INIT_WORK(&ctx->close_work, ucma_close_id);
init_completion(&ctx->comp);
+ INIT_LIST_HEAD(&ctx->mc_list);
/* So list_del() will work if we don't do ucma_finish_ctx() */
INIT_LIST_HEAD(&ctx->list);
ctx->file = file;
@@ -484,19 +487,19 @@ static ssize_t ucma_create_id(struct ucma_file *file, const char __user *inbuf,
static void ucma_cleanup_multicast(struct ucma_context *ctx)
{
- struct ucma_multicast *mc;
- unsigned long index;
+ struct ucma_multicast *mc, *tmp;
- xa_for_each(&multicast_table, index, mc) {
- if (mc->ctx != ctx)
- continue;
+ xa_lock(&multicast_table);
+ list_for_each_entry_safe(mc, tmp, &ctx->mc_list, list) {
+ list_del(&mc->list);
/*
* At this point mc->ctx->ref is 0 so the mc cannot leave the
* lock on the reader and this is enough serialization
*/
- xa_erase(&multicast_table, index);
+ __xa_erase(&multicast_table, mc->id);
kfree(mc);
}
+ xa_unlock(&multicast_table);
}
static void ucma_cleanup_mc_events(struct ucma_multicast *mc)
@@ -1469,12 +1472,16 @@ static ssize_t ucma_process_join(struct ucma_file *file,
mc->uid = cmd->uid;
memcpy(&mc->addr, addr, cmd->addr_size);
- if (xa_alloc(&multicast_table, &mc->id, NULL, xa_limit_32b,
+ xa_lock(&multicast_table);
+ if (__xa_alloc(&multicast_table, &mc->id, NULL, xa_limit_32b,
GFP_KERNEL)) {
ret = -ENOMEM;
goto err_free_mc;
}
+ list_add_tail(&mc->list, &ctx->mc_list);
+ xa_unlock(&multicast_table);
+
mutex_lock(&ctx->mutex);
ret = rdma_join_multicast(ctx->cm_id, (struct sockaddr *)&mc->addr,
join_state, mc);
@@ -1500,8 +1507,11 @@ static ssize_t ucma_process_join(struct ucma_file *file,
mutex_unlock(&ctx->mutex);
ucma_cleanup_mc_events(mc);
err_xa_erase:
- xa_erase(&multicast_table, mc->id);
+ xa_lock(&multicast_table);
+ list_del(&mc->list);
+ __xa_erase(&multicast_table, mc->id);
err_free_mc:
+ xa_unlock(&multicast_table);
kfree(mc);
err_put_ctx:
ucma_put_ctx(ctx);
@@ -1569,15 +1579,17 @@ static ssize_t ucma_leave_multicast(struct ucma_file *file,
mc = ERR_PTR(-EINVAL);
else if (!refcount_inc_not_zero(&mc->ctx->ref))
mc = ERR_PTR(-ENXIO);
- else
- __xa_erase(&multicast_table, mc->id);
- xa_unlock(&multicast_table);
if (IS_ERR(mc)) {
+ xa_unlock(&multicast_table);
ret = PTR_ERR(mc);
goto out;
}
+ list_del(&mc->list);
+ __xa_erase(&multicast_table, mc->id);
+ xa_unlock(&multicast_table);
+
mutex_lock(&mc->ctx->mutex);
rdma_leave_multicast(mc->ctx->cm_id, (struct sockaddr *) &mc->addr);
mutex_unlock(&mc->ctx->mutex);
--
2.34.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH rdma-next 3/3] RDMA/core: Set MR type in ib_reg_user_mr
2022-01-18 7:34 [PATCH rdma-next 0/3] Various fixes in RDMA/core Leon Romanovsky
2022-01-18 7:35 ` [PATCH rdma-next 1/3] RDMA/cma: Use correct address when leaving multicast group Leon Romanovsky
2022-01-18 7:35 ` [PATCH rdma-next 2/3] RDMA/ucma: Protect mc during concurrent multicast leaves Leon Romanovsky
@ 2022-01-18 7:35 ` Leon Romanovsky
2022-01-28 15:40 ` [PATCH rdma-next 0/3] Various fixes in RDMA/core Jason Gunthorpe
3 siblings, 0 replies; 6+ messages in thread
From: Leon Romanovsky @ 2022-01-18 7:35 UTC (permalink / raw)
To: Jason Gunthorpe; +Cc: Maor Gottlieb, linux-kernel, linux-rdma
From: Maor Gottlieb <maorg@nvidia.com>
Add missing assignment of MR type to IB_MR_TYPE_USER.
Fixes: 33006bd4f37f ("IB/core: Introduce ib_reg_user_mr")
Signed-off-by: Maor Gottlieb <maorg@nvidia.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
---
drivers/infiniband/core/verbs.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index c18634bec212..e821dc94a43e 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -2153,6 +2153,7 @@ struct ib_mr *ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
return mr;
mr->device = pd->device;
+ mr->type = IB_MR_TYPE_USER;
mr->pd = pd;
mr->dm = NULL;
atomic_inc(&pd->usecnt);
--
2.34.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH rdma-next 1/3] RDMA/cma: Use correct address when leaving multicast group
2022-01-18 7:35 ` [PATCH rdma-next 1/3] RDMA/cma: Use correct address when leaving multicast group Leon Romanovsky
@ 2022-01-28 15:35 ` Jason Gunthorpe
0 siblings, 0 replies; 6+ messages in thread
From: Jason Gunthorpe @ 2022-01-28 15:35 UTC (permalink / raw)
To: Leon Romanovsky; +Cc: Maor Gottlieb, linux-kernel, linux-rdma
On Tue, Jan 18, 2022 at 09:35:00AM +0200, Leon Romanovsky wrote:
> From: Maor Gottlieb <maorg@nvidia.com>
>
> In RoCE we should use cma_iboe_set_mgid and not cma_set_mgid to generate
> the mgid, otherwise we will try to remove incorrect address.
>
> Fixes: b5de0c60cc30 ("RDMA/cma: Fix use after free race in roce multicast join")
> Signed-off-by: Maor Gottlieb <maorg@nvidia.com>
> Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
> ---
> drivers/infiniband/core/cma.c | 61 +++++++++++++++++------------------
> 1 file changed, 30 insertions(+), 31 deletions(-)
I didn't like this one so much and changed it into this:
@@ -67,8 +67,8 @@ static const char * const cma_events[] = {
[RDMA_CM_EVENT_TIMEWAIT_EXIT] = "timewait exit",
};
-static void cma_set_mgid(struct rdma_id_private *id_priv, struct sockaddr *addr,
- union ib_gid *mgid);
+static void cma_iboe_set_mgid(struct sockaddr *addr, union ib_gid *mgid,
+ enum ib_gid_type gid_type);
const char *__attribute_const__ rdma_event_msg(enum rdma_cm_event_type event)
{
@@ -1846,17 +1846,19 @@ static void destroy_mc(struct rdma_id_private *id_priv,
if (dev_addr->bound_dev_if)
ndev = dev_get_by_index(dev_addr->net,
dev_addr->bound_dev_if);
- if (ndev) {
+ if (ndev && !send_only) {
+ enum ib_gid_type gid_type;
union ib_gid mgid;
- cma_set_mgid(id_priv, (struct sockaddr *)&mc->addr,
- &mgid);
-
- if (!send_only)
- cma_igmp_send(ndev, &mgid, false);
-
- dev_put(ndev);
+ gid_type = id_priv->cma_dev->default_gid_type
+ [id_priv->id.port_num -
+ rdma_start_port(
+ id_priv->cma_dev->device)];
+ cma_iboe_set_mgid((struct sockaddr *)&mc->addr, &mgid,
+ gid_type);
+ cma_igmp_send(ndev, &mgid, false);
}
+ dev_put(ndev);
cancel_work_sync(&mc->iboe_join.work);
}
Thanks,
Jason
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH rdma-next 0/3] Various fixes in RDMA/core
2022-01-18 7:34 [PATCH rdma-next 0/3] Various fixes in RDMA/core Leon Romanovsky
` (2 preceding siblings ...)
2022-01-18 7:35 ` [PATCH rdma-next 3/3] RDMA/core: Set MR type in ib_reg_user_mr Leon Romanovsky
@ 2022-01-28 15:40 ` Jason Gunthorpe
3 siblings, 0 replies; 6+ messages in thread
From: Jason Gunthorpe @ 2022-01-28 15:40 UTC (permalink / raw)
To: Leon Romanovsky; +Cc: Leon Romanovsky, linux-kernel, linux-rdma, Maor Gottlieb
On Tue, Jan 18, 2022 at 09:34:59AM +0200, Leon Romanovsky wrote:
> From: Leon Romanovsky <leonro@nvidia.com>
>
> Hi,
>
> This is compilation of unrelated fixes, one is an outcome of syzkaller
> report and other two were found in our regression.
>
> Thanks
>
> Leon Romanovsky (1):
> RDMA/ucma: Protect mc during concurrent multicast leaves
>
> Maor Gottlieb (2):
> RDMA/cma: Use correct address when leaving multicast group
Applied to for-rc
> RDMA/core: Set MR type in ib_reg_user_mr
Applied to for-next
Thanks,
Jason
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2022-01-28 15:40 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-18 7:34 [PATCH rdma-next 0/3] Various fixes in RDMA/core Leon Romanovsky
2022-01-18 7:35 ` [PATCH rdma-next 1/3] RDMA/cma: Use correct address when leaving multicast group Leon Romanovsky
2022-01-28 15:35 ` Jason Gunthorpe
2022-01-18 7:35 ` [PATCH rdma-next 2/3] RDMA/ucma: Protect mc during concurrent multicast leaves Leon Romanovsky
2022-01-18 7:35 ` [PATCH rdma-next 3/3] RDMA/core: Set MR type in ib_reg_user_mr Leon Romanovsky
2022-01-28 15:40 ` [PATCH rdma-next 0/3] Various fixes in RDMA/core Jason Gunthorpe
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.