Skip to content

Commit 11a3f5a

Browse files
author
Leon Romanovsky
committed
RDMA/mlx5: Fix crash while accessing garbage pointer and freed memory
The failure in rereg_mr flow caused to set garbage value (error value) into mr->umem pointer. This pointer is accessed at the release stage and it causes to the following crash. There is not enough to simply change umem to point to NULL, because the MR struct is needed to be accessed during MR deregistration phase, so delay kfree too. [ 6.237617] BUG: unable to handle kernel NULL pointer dereference a 0000000000000228 [ 6.238756] IP: ib_dereg_mr+0xd/0x30 [ 6.239264] PGD 80000000167eb067 P4D 80000000167eb067 PUD 167f9067 PMD 0 [ 6.240320] Oops: 0000 [#1] SMP PTI [ 6.240782] CPU: 0 PID: 367 Comm: dereg Not tainted 4.16.0-rc1-00029-gc198fafe0453 torvalds#183 [ 6.242120] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.7.5-0-ge51488c-20140602_164612-nilsson.home.kraxel.org 04/01/2014 [ 6.244504] RIP: 0010:ib_dereg_mr+0xd/0x30 [ 6.245253] RSP: 0018:ffffaf5d001d7d68 EFLAGS: 00010246 [ 6.246100] RAX: 0000000000000000 RBX: ffff95d4172daf00 RCX: 0000000000000000 [ 6.247414] RDX: 00000000ffffffff RSI: 0000000000000001 RDI: ffff95d41a317600 [ 6.248591] RBP: 0000000000000001 R08: 0000000000000000 R09: 0000000000000000 [ 6.249810] R10: ffff95d417033c10 R11: 0000000000000000 R12: ffff95d4172c3a80 [ 6.251121] R13: ffff95d4172c3720 R14: ffff95d4172c3a98 R15: 00000000ffffffff [ 6.252437] FS: 0000000000000000(0000) GS:ffff95d41fc00000(0000) knlGS:0000000000000000 [ 6.253887] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 6.254814] CR2: 0000000000000228 CR3: 00000000172b4000 CR4: 00000000000006b0 [ 6.255943] Call Trace: [ 6.256368] remove_commit_idr_uobject+0x1b/0x80 [ 6.257118] uverbs_cleanup_ucontext+0xe4/0x190 [ 6.257855] ib_uverbs_cleanup_ucontext.constprop.14+0x19/0x40 [ 6.258857] ib_uverbs_close+0x2a/0x100 [ 6.259494] __fput+0xca/0x1c0 [ 6.259938] task_work_run+0x84/0xa0 [ 6.260519] do_exit+0x312/0xb40 [ 6.261023] ? __do_page_fault+0x24d/0x490 [ 6.261707] do_group_exit+0x3a/0xa0 [ 6.262267] SyS_exit_group+0x10/0x10 [ 6.262802] do_syscall_64+0x75/0x180 [ 6.263391] entry_SYSCALL_64_after_hwframe+0x21/0x86 [ 6.264253] RIP: 0033:0x7f1b39c49488 [ 6.264827] RSP: 002b:00007ffe2de05b68 EFLAGS: 00000246 ORIG_RAX: 00000000000000e7 [ 6.266049] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f1b39c49488 [ 6.267187] RDX: 0000000000000000 RSI: 000000000000003c RDI: 0000000000000000 [ 6.268377] RBP: 00007f1b39f258e0 R08: 00000000000000e7 R09: ffffffffffffff98 [ 6.269640] R10: 00007f1b3a147260 R11: 0000000000000246 R12: 00007f1b39f258e0 [ 6.270783] R13: 00007f1b39f2ac20 R14: 0000000000000000 R15: 0000000000000000 [ 6.271943] Code: 74 07 31 d2 e9 25 d8 6c 00 b8 da ff ff ff c3 0f 1f 44 00 00 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 8b 07 53 48 8b 5f 08 <48> 8b 80 28 02 00 00 e8 f7 d7 6c 00 85 c0 75 04 3e ff 4b 18 5b [ 6.274927] RIP: ib_dereg_mr+0xd/0x30 RSP: ffffaf5d001d7d68 [ 6.275760] CR2: 0000000000000228 [ 6.276200] ---[ end trace a35641f1c474bd20 ]--- Fixes: e126ba9 ("mlx5: Add driver for Mellanox Connect-IB adapters") Cc: syzkaller <[email protected]> Cc: <[email protected]> Reported-by: Noa Osherovich <[email protected]> Signed-off-by: Leon Romanovsky <[email protected]>
1 parent e36d0bb commit 11a3f5a

File tree

1 file changed

+8
-4
lines changed
  • drivers/infiniband/hw/mlx5

1 file changed

+8
-4
lines changed

drivers/infiniband/hw/mlx5/mr.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -851,7 +851,8 @@ static int mr_umem_get(struct ib_pd *pd, u64 start, u64 length,
851851
*umem = ib_umem_get(pd->uobject->context, start, length,
852852
access_flags, 0);
853853
err = PTR_ERR_OR_ZERO(*umem);
854-
if (err < 0) {
854+
if (err) {
855+
*umem = NULL;
855856
mlx5_ib_err(dev, "umem get failed (%d)\n", err);
856857
return err;
857858
}
@@ -1427,6 +1428,7 @@ int mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags, u64 start,
14271428
if (err) {
14281429
mlx5_ib_warn(dev, "Failed to rereg UMR\n");
14291430
ib_umem_release(mr->umem);
1431+
mr->umem = NULL;
14301432
clean_mr(dev, mr);
14311433
return err;
14321434
}
@@ -1510,14 +1512,11 @@ static int clean_mr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr)
15101512
u32 key = mr->mmkey.key;
15111513

15121514
err = destroy_mkey(dev, mr);
1513-
kfree(mr);
15141515
if (err) {
15151516
mlx5_ib_warn(dev, "failed to destroy mkey 0x%x (%d)\n",
15161517
key, err);
15171518
return err;
15181519
}
1519-
} else {
1520-
mlx5_mr_cache_free(dev, mr);
15211520
}
15221521

15231522
return 0;
@@ -1560,6 +1559,11 @@ static int dereg_mr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr)
15601559
atomic_sub(npages, &dev->mdev->priv.reg_pages);
15611560
}
15621561

1562+
if (!mr->allocated_from_cache)
1563+
kfree(mr);
1564+
else
1565+
mlx5_mr_cache_free(dev, mr);
1566+
15631567
return 0;
15641568
}
15651569

0 commit comments

Comments
 (0)