diff options
author | Leon Romanovsky <leonro@mellanox.com> | 2018-03-11 13:51:32 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-04-29 11:31:57 +0200 |
commit | 9ffa6fb2583b2c9afdb83c14948a9e3e2192bf1f (patch) | |
tree | f6d60e79bfc426df2f5f26eaca6264d0f4afa1f9 /drivers/infiniband | |
parent | 9acdfe4eecf29d38fd7c7d342b120f430c950400 (diff) |
RDMA/mlx5: Fix NULL dereference while accessing XRC_TGT QPs
commit 75a4598209cbe45540baa316c3b51d9db222e96e upstream.
mlx5 modify_qp() relies on FW that the error will be thrown if wrong
state is supplied. The missing check in FW causes the following crash
while using XRC_TGT QPs.
[ 14.769632] BUG: unable to handle kernel NULL pointer dereference at (null)
[ 14.771085] IP: mlx5_ib_modify_qp+0xf60/0x13f0
[ 14.771894] PGD 800000001472e067 P4D 800000001472e067 PUD 14529067 PMD 0
[ 14.773126] Oops: 0002 [#1] SMP PTI
[ 14.773763] CPU: 0 PID: 365 Comm: ubsan Not tainted 4.16.0-rc1-00038-g8151138c0793 #119
[ 14.775192] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.7.5-0-ge51488c-20140602_164612-nilsson.home.kraxel.org 04/01/2014
[ 14.777522] RIP: 0010:mlx5_ib_modify_qp+0xf60/0x13f0
[ 14.778417] RSP: 0018:ffffbf48001c7bd8 EFLAGS: 00010246
[ 14.779346] RAX: 0000000000000000 RBX: ffff9a8f9447d400 RCX: 0000000000000000
[ 14.780643] RDX: 0000000000000000 RSI: 000000000000000a RDI: 0000000000000000
[ 14.781930] RBP: 0000000000000000 R08: 00000000000217b0 R09: ffffffffbc9c1504
[ 14.783214] R10: fffff4a180519480 R11: ffff9a8f94523600 R12: ffff9a8f9493e240
[ 14.784507] R13: ffff9a8f9447d738 R14: 000000000000050a R15: 0000000000000000
[ 14.785800] FS: 00007f545b466700(0000) GS:ffff9a8f9fc00000(0000) knlGS:0000000000000000
[ 14.787073] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 14.787792] CR2: 0000000000000000 CR3: 00000000144be000 CR4: 00000000000006b0
[ 14.788689] Call Trace:
[ 14.789007] _ib_modify_qp+0x71/0x120
[ 14.789475] modify_qp.isra.20+0x207/0x2f0
[ 14.790010] ib_uverbs_modify_qp+0x90/0xe0
[ 14.790532] ib_uverbs_write+0x1d2/0x3c0
[ 14.791049] ? __handle_mm_fault+0x93c/0xe40
[ 14.791644] __vfs_write+0x36/0x180
[ 14.792096] ? handle_mm_fault+0xc1/0x210
[ 14.792601] vfs_write+0xad/0x1e0
[ 14.793018] SyS_write+0x52/0xc0
[ 14.793422] do_syscall_64+0x75/0x180
[ 14.793888] entry_SYSCALL_64_after_hwframe+0x21/0x86
[ 14.794527] RIP: 0033:0x7f545ad76099
[ 14.794975] RSP: 002b:00007ffd78787468 EFLAGS: 00000287 ORIG_RAX: 0000000000000001
[ 14.795958] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f545ad76099
[ 14.797075] RDX: 0000000000000078 RSI: 0000000020009000 RDI: 0000000000000003
[ 14.798140] RBP: 00007ffd78787470 R08: 00007ffd78787480 R09: 00007ffd78787480
[ 14.799207] R10: 00007ffd78787480 R11: 0000000000000287 R12: 00005599ada98760
[ 14.800277] R13: 00007ffd78787560 R14: 0000000000000000 R15: 0000000000000000
[ 14.801341] Code: 4c 8b 1c 24 48 8b 83 70 02 00 00 48 c7 83 cc 02 00
00 00 00 00 00 48 c7 83 24 03 00 00 00 00 00 00 c7 83 2c 03 00 00 00 00
00 00 <c7> 00 00 00 00 00 48 8b 83 70 02 00 00 c7 40 04 00 00 00 00 4c
[ 14.804012] RIP: mlx5_ib_modify_qp+0xf60/0x13f0 RSP: ffffbf48001c7bd8
[ 14.804838] CR2: 0000000000000000
[ 14.805288] ---[ end trace 3f1da0df5c8b7c37 ]---
Cc: syzkaller <syzkaller@googlegroups.com>
Reported-by: Maor Gottlieb <maorg@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/hw/mlx5/qp.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index 403df3591d29..5b8909d1b55e 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c @@ -2848,7 +2848,8 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp, * If we moved a kernel QP to RESET, clean up all old CQ * entries and reinitialize the QP. */ - if (new_state == IB_QPS_RESET && !ibqp->uobject) { + if (new_state == IB_QPS_RESET && + !ibqp->uobject && ibqp->qp_type != IB_QPT_XRC_TGT) { mlx5_ib_cq_clean(recv_cq, base->mqp.qpn, ibqp->srq ? to_msrq(ibqp->srq) : NULL); if (send_cq != recv_cq) |