[PATCH rdma-next] RDMA/core: Fix resolve_prepare_src error cleanup

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Patrisious Haddad <phaddad@xxxxxxxxxx>

resolve_prepare_src() changes the destination address of the id,
regardless of success, and on failure zeroes it out.

Instead on function failure keep the original destination address
of the id.

Since the id could have been already added to the cm id tree and
zeroing its destination address, could result in a key mismatch or
multiple ids having the same key(zero) in the tree which could lead to:

BUG: KASAN: slab-out-of-bounds in compare_netdev_and_ip.isra.0+0x25/0x120 drivers/infiniband/core/cma.c:473
Read of size 4 at addr ffff88800920d9e4 by task syz-executor.4/14865

CPU: 2 PID: 14865 Comm: syz-executor.4 Not tainted 5.19.0-rc2 #21
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
Call Trace:
 <TASK>
 __dump_stack lib/dump_stack.c:88 [inline]
 dump_stack_lvl+0x6e/0x91 lib/dump_stack.c:106
 print_address_description mm/kasan/report.c:313 [inline]
 print_report.cold+0xff/0x68e mm/kasan/report.c:429
 kasan_report+0xa8/0x130 mm/kasan/report.c:491
 compare_netdev_and_ip.isra.0+0x25/0x120 drivers/infiniband/core/cma.c:473
 cma_add_id_to_tree drivers/infiniband/core/cma.c:506 [inline]
 rdma_resolve_route+0xbc4/0x1560 drivers/infiniband/core/cma.c:3303
 ucma_resolve_route+0xe4/0x150 drivers/infiniband/core/ucma.c:746
 ucma_write+0x19f/0x280 drivers/infiniband/core/ucma.c:1744
 vfs_write fs/read_write.c:589 [inline]
 vfs_write+0x181/0x580 fs/read_write.c:571
 ksys_write+0x1a1/0x1e0 fs/read_write.c:644
 do_syscall_x64 arch/x86/entry/common.c:50 [inline]
 do_syscall_64+0x3d/0x90 arch/x86/entry/common.c:80
 entry_SYSCALL_64_after_hwframe+0x46/0xb0
RIP: 0033:0x7f2afbe8c89d
Code: 02 b8 ff ff ff ff c3 66 0f 1f 44 00 00 f3 0f 1e fa 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:00007f2afcf1ec28 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
RAX: ffffffffffffffda RBX: 00007f2afbfabf60 RCX: 00007f2afbe8c89d
RDX: 0000000000000010 RSI: 0000000020000100 RDI: 0000000000000003
RBP: 00007f2afbef910d R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007ffcdc77c66f R14: 00007f2afbfabf60 R15: 00007f2afcf1edc0
 </TASK>

Fixes: 19b752a19dce ("IB/cma: Allow port reuse for rdma_id")
Signed-off-by: Patrisious Haddad <phaddad@xxxxxxxxxx>
Reviewed-by: Maor Gottlieb <maorg@xxxxxxxxxx>
Reported-by: Wei Chen <harperchen1110@xxxxxxxxx>
Signed-off-by: Leon Romanovsky <leonro@xxxxxxxxxx>
---
 drivers/infiniband/core/cma.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 1fca0a24f30f..2d4c391e36a9 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -3584,8 +3584,11 @@ static int resolve_prepare_src(struct rdma_id_private *id_priv,
 			       struct sockaddr *src_addr,
 			       const struct sockaddr *dst_addr)
 {
+	struct sockaddr org_addr = {};
 	int ret;
 
+	memcpy(&org_addr, cma_dst_addr(id_priv),
+	       rdma_addr_size(cma_dst_addr(id_priv)));
 	memcpy(cma_dst_addr(id_priv), dst_addr, rdma_addr_size(dst_addr));
 	if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_ADDR_QUERY)) {
 		/* For a well behaved ULP state will be RDMA_CM_IDLE */
@@ -3608,7 +3611,7 @@ static int resolve_prepare_src(struct rdma_id_private *id_priv,
 err_state:
 	cma_comp_exch(id_priv, RDMA_CM_ADDR_QUERY, RDMA_CM_ADDR_BOUND);
 err_dst:
-	memset(cma_dst_addr(id_priv), 0, rdma_addr_size(dst_addr));
+	memcpy(cma_dst_addr(id_priv), &org_addr, rdma_addr_size(&org_addr));
 	return ret;
 }
 
-- 
2.38.1




[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux