--- /dev/null
+From 9137108cc3d64ade13e753108ec611a0daed16a0 Mon Sep 17 00:00:00 2001
+From: Jason Gunthorpe <jgg@mellanox.com>
+Date: Thu, 22 Mar 2018 14:04:23 -0600
+Subject: RDMA/rdma_cm: Fix use after free race with process_one_req
+
+From: Jason Gunthorpe <jgg@mellanox.com>
+
+commit 9137108cc3d64ade13e753108ec611a0daed16a0 upstream.
+
+process_one_req() can race with rdma_addr_cancel():
+
+ CPU0 CPU1
+ ==== ====
+ process_one_work()
+ debug_work_deactivate(work);
+ process_one_req()
+ rdma_addr_cancel()
+ mutex_lock(&lock);
+ set_timeout(&req->work,..);
+ __queue_work()
+ debug_work_activate(work);
+ mutex_unlock(&lock);
+
+ mutex_lock(&lock);
+[..]
+ list_del(&req->list);
+ mutex_unlock(&lock);
+[..]
+
+ // ODEBUG explodes since the work is still queued.
+ kfree(req);
+
+Causing ODEBUG to detect the use after free:
+
+ODEBUG: free active (active state 0) object type: work_struct hint: process_one_req+0x0/0x6c0 include/net/dst.h:165
+WARNING: CPU: 0 PID: 79 at lib/debugobjects.c:291 debug_print_object+0x166/0x220 lib/debugobjects.c:288
+kvm: emulating exchange as write
+Kernel panic - not syncing: panic_on_warn set ...
+
+CPU: 0 PID: 79 Comm: kworker/u4:3 Not tainted 4.16.0-rc6+ #361
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+Workqueue: ib_addr process_one_req
+Call Trace:
+ __dump_stack lib/dump_stack.c:17 [inline]
+ dump_stack+0x194/0x24d lib/dump_stack.c:53
+ panic+0x1e4/0x41c kernel/panic.c:183
+ __warn+0x1dc/0x200 kernel/panic.c:547
+ report_bug+0x1f4/0x2b0 lib/bug.c:186
+ fixup_bug.part.11+0x37/0x80 arch/x86/kernel/traps.c:178
+ fixup_bug arch/x86/kernel/traps.c:247 [inline]
+ do_error_trap+0x2d7/0x3e0 arch/x86/kernel/traps.c:296
+ do_invalid_op+0x1b/0x20 arch/x86/kernel/traps.c:315
+ invalid_op+0x1b/0x40 arch/x86/entry/entry_64.S:986
+RIP: 0010:debug_print_object+0x166/0x220 lib/debugobjects.c:288
+RSP: 0000:ffff8801d966f210 EFLAGS: 00010086
+RAX: dffffc0000000008 RBX: 0000000000000003 RCX: ffffffff815acd6e
+RDX: 0000000000000000 RSI: 1ffff1003b2cddf2 RDI: 0000000000000000
+RBP: ffff8801d966f250 R08: 0000000000000000 R09: 1ffff1003b2cddc8
+R10: ffffed003b2cde71 R11: ffffffff86f39a98 R12: 0000000000000001
+R13: ffffffff86f15540 R14: ffffffff86408700 R15: ffffffff8147c0a0
+ __debug_check_no_obj_freed lib/debugobjects.c:745 [inline]
+ debug_check_no_obj_freed+0x662/0xf1f lib/debugobjects.c:774
+ kfree+0xc7/0x260 mm/slab.c:3799
+ process_one_req+0x2e7/0x6c0 drivers/infiniband/core/addr.c:592
+ process_one_work+0xc47/0x1bb0 kernel/workqueue.c:2113
+ worker_thread+0x223/0x1990 kernel/workqueue.c:2247
+ kthread+0x33c/0x400 kernel/kthread.c:238
+ ret_from_fork+0x3a/0x50 arch/x86/entry/entry_64.S:406
+
+Fixes: 5fff41e1f89d ("IB/core: Fix race condition in resolving IP to MAC")
+Reported-by: <syzbot+3b4acab09b6463472d0a@syzkaller.appspotmail.com>
+Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/core/addr.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/drivers/infiniband/core/addr.c
++++ b/drivers/infiniband/core/addr.c
+@@ -597,6 +597,15 @@ static void process_one_req(struct work_
+ list_del(&req->list);
+ mutex_unlock(&lock);
+
++ /*
++ * Although the work will normally have been canceled by the
++ * workqueue, it can still be requeued as long as it is on the
++ * req_list, so it could have been requeued before we grabbed &lock.
++ * We need to cancel it after it is removed from req_list to really be
++ * sure it is safe to free.
++ */
++ cancel_delayed_work(&req->work);
++
+ req->callback(req->status, (struct sockaddr *)&req->src_addr,
+ req->addr, req->context);
+ put_client(req->client);
--- /dev/null
+From 2975d5de6428ff6d9317e9948f0968f7d42e5d74 Mon Sep 17 00:00:00 2001
+From: Leon Romanovsky <leonro@mellanox.com>
+Date: Thu, 15 Mar 2018 15:33:02 +0200
+Subject: RDMA/ucma: Check AF family prior resolving address
+
+From: Leon Romanovsky <leonro@mellanox.com>
+
+commit 2975d5de6428ff6d9317e9948f0968f7d42e5d74 upstream.
+
+Garbage supplied by user will cause to UCMA module provide zero
+memory size for memcpy(), because it wasn't checked, it will
+produce unpredictable results in rdma_resolve_addr().
+
+[ 42.873814] BUG: KASAN: null-ptr-deref in rdma_resolve_addr+0xc8/0xfb0
+[ 42.874816] Write of size 28 at addr 00000000000000a0 by task resaddr/1044
+[ 42.876765]
+[ 42.876960] CPU: 1 PID: 1044 Comm: resaddr Not tainted 4.16.0-rc1-00057-gaa56a5293d7e #34
+[ 42.877840] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.11.0-0-g63451fca13-prebuilt.qemu-project.org 04/01/2014
+[ 42.879691] Call Trace:
+[ 42.880236] dump_stack+0x5c/0x77
+[ 42.880664] kasan_report+0x163/0x380
+[ 42.881354] ? rdma_resolve_addr+0xc8/0xfb0
+[ 42.881864] memcpy+0x34/0x50
+[ 42.882692] rdma_resolve_addr+0xc8/0xfb0
+[ 42.883366] ? deref_stack_reg+0x88/0xd0
+[ 42.883856] ? vsnprintf+0x31a/0x770
+[ 42.884686] ? rdma_bind_addr+0xc40/0xc40
+[ 42.885327] ? num_to_str+0x130/0x130
+[ 42.885773] ? deref_stack_reg+0x88/0xd0
+[ 42.886217] ? __read_once_size_nocheck.constprop.6+0x10/0x10
+[ 42.887698] ? unwind_get_return_address_ptr+0x50/0x50
+[ 42.888302] ? replace_slot+0x147/0x170
+[ 42.889176] ? delete_node+0x12c/0x340
+[ 42.890223] ? __radix_tree_lookup+0xa9/0x160
+[ 42.891196] ? ucma_resolve_ip+0xb7/0x110
+[ 42.891917] ucma_resolve_ip+0xb7/0x110
+[ 42.893003] ? ucma_resolve_addr+0x190/0x190
+[ 42.893531] ? _copy_from_user+0x5e/0x90
+[ 42.894204] ucma_write+0x174/0x1f0
+[ 42.895162] ? ucma_resolve_route+0xf0/0xf0
+[ 42.896309] ? dequeue_task_fair+0x67e/0xd90
+[ 42.897192] ? put_prev_entity+0x7d/0x170
+[ 42.897870] ? ring_buffer_record_is_on+0xd/0x20
+[ 42.898439] ? tracing_record_taskinfo_skip+0x20/0x50
+[ 42.899686] __vfs_write+0xc4/0x350
+[ 42.900142] ? kernel_read+0xa0/0xa0
+[ 42.900602] ? firmware_map_remove+0xdf/0xdf
+[ 42.901135] ? do_task_dead+0x5d/0x60
+[ 42.901598] ? do_exit+0xcc6/0x1220
+[ 42.902789] ? __fget+0xa8/0xf0
+[ 42.903190] vfs_write+0xf7/0x280
+[ 42.903600] SyS_write+0xa1/0x120
+[ 42.904206] ? SyS_read+0x120/0x120
+[ 42.905710] ? compat_start_thread+0x60/0x60
+[ 42.906423] ? SyS_read+0x120/0x120
+[ 42.908716] do_syscall_64+0xeb/0x250
+[ 42.910760] entry_SYSCALL_64_after_hwframe+0x21/0x86
+[ 42.912735] RIP: 0033:0x7f138b0afe99
+[ 42.914734] RSP: 002b:00007f138b799e98 EFLAGS: 00000287 ORIG_RAX: 0000000000000001
+[ 42.917134] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f138b0afe99
+[ 42.919487] RDX: 000000000000002e RSI: 0000000020000c40 RDI: 0000000000000004
+[ 42.922393] RBP: 00007f138b799ec0 R08: 00007f138b79a700 R09: 0000000000000000
+[ 42.925266] R10: 00007f138b79a700 R11: 0000000000000287 R12: 00007f138b799fc0
+[ 42.927570] R13: 0000000000000000 R14: 00007ffdbae757c0 R15: 00007f138b79a9c0
+[ 42.930047]
+[ 42.932681] Disabling lock debugging due to kernel taint
+[ 42.934795] BUG: unable to handle kernel NULL pointer dereference at 00000000000000a0
+[ 42.936939] IP: memcpy_erms+0x6/0x10
+[ 42.938864] PGD 80000001bea92067 P4D 80000001bea92067 PUD 1bea96067 PMD 0
+[ 42.941576] Oops: 0002 [#1] SMP KASAN PTI
+[ 42.943952] CPU: 1 PID: 1044 Comm: resaddr Tainted: G B 4.16.0-rc1-00057-gaa56a5293d7e #34
+[ 42.946964] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.11.0-0-g63451fca13-prebuilt.qemu-project.org 04/01/2014
+[ 42.952336] RIP: 0010:memcpy_erms+0x6/0x10
+[ 42.954707] RSP: 0018:ffff8801c8b479c8 EFLAGS: 00010286
+[ 42.957227] RAX: 00000000000000a0 RBX: ffff8801c8b47ba0 RCX: 000000000000001c
+[ 42.960543] RDX: 000000000000001c RSI: ffff8801c8b47bbc RDI: 00000000000000a0
+[ 42.963867] RBP: ffff8801c8b47b60 R08: 0000000000000000 R09: ffffed0039168ed1
+[ 42.967303] R10: 0000000000000001 R11: ffffed0039168ed0 R12: ffff8801c8b47bbc
+[ 42.970685] R13: 00000000000000a0 R14: 1ffff10039168f4a R15: 0000000000000000
+[ 42.973631] FS: 00007f138b79a700(0000) GS:ffff8801e5d00000(0000) knlGS:0000000000000000
+[ 42.976831] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 42.979239] CR2: 00000000000000a0 CR3: 00000001be908002 CR4: 00000000003606a0
+[ 42.982060] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+[ 42.984877] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+[ 42.988033] Call Trace:
+[ 42.990487] rdma_resolve_addr+0xc8/0xfb0
+[ 42.993202] ? deref_stack_reg+0x88/0xd0
+[ 42.996055] ? vsnprintf+0x31a/0x770
+[ 42.998707] ? rdma_bind_addr+0xc40/0xc40
+[ 43.000985] ? num_to_str+0x130/0x130
+[ 43.003410] ? deref_stack_reg+0x88/0xd0
+[ 43.006302] ? __read_once_size_nocheck.constprop.6+0x10/0x10
+[ 43.008780] ? unwind_get_return_address_ptr+0x50/0x50
+[ 43.011178] ? replace_slot+0x147/0x170
+[ 43.013517] ? delete_node+0x12c/0x340
+[ 43.016019] ? __radix_tree_lookup+0xa9/0x160
+[ 43.018755] ? ucma_resolve_ip+0xb7/0x110
+[ 43.021270] ucma_resolve_ip+0xb7/0x110
+[ 43.023968] ? ucma_resolve_addr+0x190/0x190
+[ 43.026312] ? _copy_from_user+0x5e/0x90
+[ 43.029384] ucma_write+0x174/0x1f0
+[ 43.031861] ? ucma_resolve_route+0xf0/0xf0
+[ 43.034782] ? dequeue_task_fair+0x67e/0xd90
+[ 43.037483] ? put_prev_entity+0x7d/0x170
+[ 43.040215] ? ring_buffer_record_is_on+0xd/0x20
+[ 43.042990] ? tracing_record_taskinfo_skip+0x20/0x50
+[ 43.045595] __vfs_write+0xc4/0x350
+[ 43.048624] ? kernel_read+0xa0/0xa0
+[ 43.051604] ? firmware_map_remove+0xdf/0xdf
+[ 43.055379] ? do_task_dead+0x5d/0x60
+[ 43.058000] ? do_exit+0xcc6/0x1220
+[ 43.060783] ? __fget+0xa8/0xf0
+[ 43.063133] vfs_write+0xf7/0x280
+[ 43.065677] SyS_write+0xa1/0x120
+[ 43.068647] ? SyS_read+0x120/0x120
+[ 43.071179] ? compat_start_thread+0x60/0x60
+[ 43.074025] ? SyS_read+0x120/0x120
+[ 43.076705] do_syscall_64+0xeb/0x250
+[ 43.079006] entry_SYSCALL_64_after_hwframe+0x21/0x86
+[ 43.081606] RIP: 0033:0x7f138b0afe99
+[ 43.083679] RSP: 002b:00007f138b799e98 EFLAGS: 00000287 ORIG_RAX: 0000000000000001
+[ 43.086802] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f138b0afe99
+[ 43.089989] RDX: 000000000000002e RSI: 0000000020000c40 RDI: 0000000000000004
+[ 43.092866] RBP: 00007f138b799ec0 R08: 00007f138b79a700 R09: 0000000000000000
+[ 43.096233] R10: 00007f138b79a700 R11: 0000000000000287 R12: 00007f138b799fc0
+[ 43.098913] R13: 0000000000000000 R14: 00007ffdbae757c0 R15: 00007f138b79a9c0
+[ 43.101809] Code: 90 90 90 90 90 eb 1e 0f 1f 00 48 89 f8 48 89 d1 48
+c1 e9 03 83 e2 07 f3 48 a5 89 d1 f3 a4 c3 66 0f 1f 44 00 00 48 89 f8 48
+89 d1 <f3> a4 c3 0f 1f 80 00 00 00 00 48 89 f8 48 83 fa 20 72 7e 40 38
+[ 43.107950] RIP: memcpy_erms+0x6/0x10 RSP: ffff8801c8b479c8
+
+Reported-by: <syzbot+1d8c43206853b369d00c@syzkaller.appspotmail.com>
+Fixes: 75216638572f ("RDMA/cma: Export rdma cm interface to userspace")
+Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
+Reviewed-by: Sean Hefty <sean.hefty@intel.com>
+Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/core/ucma.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+--- a/drivers/infiniband/core/ucma.c
++++ b/drivers/infiniband/core/ucma.c
+@@ -664,19 +664,23 @@ static ssize_t ucma_resolve_ip(struct uc
+ int in_len, int out_len)
+ {
+ struct rdma_ucm_resolve_ip cmd;
++ struct sockaddr *src, *dst;
+ struct ucma_context *ctx;
+ int ret;
+
+ if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+ return -EFAULT;
+
++ src = (struct sockaddr *) &cmd.src_addr;
++ dst = (struct sockaddr *) &cmd.dst_addr;
++ if (!rdma_addr_size(src) || !rdma_addr_size(dst))
++ return -EINVAL;
++
+ ctx = ucma_get_ctx(file, cmd.id);
+ if (IS_ERR(ctx))
+ return PTR_ERR(ctx);
+
+- ret = rdma_resolve_addr(ctx->cm_id, (struct sockaddr *) &cmd.src_addr,
+- (struct sockaddr *) &cmd.dst_addr,
+- cmd.timeout_ms);
++ ret = rdma_resolve_addr(ctx->cm_id, src, dst, cmd.timeout_ms);
+ ucma_put_ctx(ctx);
+ return ret;
+ }
--- /dev/null
+From c8d3bcbfc5eab3f01cf373d039af725f3b488813 Mon Sep 17 00:00:00 2001
+From: Leon Romanovsky <leonro@mellanox.com>
+Date: Sun, 25 Mar 2018 11:39:05 +0300
+Subject: RDMA/ucma: Check that device exists prior to accessing it
+
+From: Leon Romanovsky <leonro@mellanox.com>
+
+commit c8d3bcbfc5eab3f01cf373d039af725f3b488813 upstream.
+
+Ensure that device exists prior to accessing its properties.
+
+Reported-by: <syzbot+71655d44855ac3e76366@syzkaller.appspotmail.com>
+Fixes: 75216638572f ("RDMA/cma: Export rdma cm interface to userspace")
+Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
+Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/core/ucma.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/infiniband/core/ucma.c
++++ b/drivers/infiniband/core/ucma.c
+@@ -1335,7 +1335,7 @@ static ssize_t ucma_notify(struct ucma_f
+ {
+ struct rdma_ucm_notify cmd;
+ struct ucma_context *ctx;
+- int ret;
++ int ret = -EINVAL;
+
+ if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+ return -EFAULT;
+@@ -1344,7 +1344,9 @@ static ssize_t ucma_notify(struct ucma_f
+ if (IS_ERR(ctx))
+ return PTR_ERR(ctx);
+
+- ret = rdma_notify(ctx->cm_id, (enum ib_event_type) cmd.event);
++ if (ctx->cm_id->device)
++ ret = rdma_notify(ctx->cm_id, (enum ib_event_type)cmd.event);
++
+ ucma_put_ctx(ctx);
+ return ret;
+ }
--- /dev/null
+From 4b658d1bbc16605330694bb3ef2570c465ef383d Mon Sep 17 00:00:00 2001
+From: Leon Romanovsky <leonro@mellanox.com>
+Date: Sun, 25 Mar 2018 11:23:55 +0300
+Subject: RDMA/ucma: Check that device is connected prior to access it
+
+From: Leon Romanovsky <leonro@mellanox.com>
+
+commit 4b658d1bbc16605330694bb3ef2570c465ef383d upstream.
+
+Add missing check that device is connected prior to access it.
+
+[ 55.358652] BUG: KASAN: null-ptr-deref in rdma_init_qp_attr+0x4a/0x2c0
+[ 55.359389] Read of size 8 at addr 00000000000000b0 by task qp/618
+[ 55.360255]
+[ 55.360432] CPU: 1 PID: 618 Comm: qp Not tainted 4.16.0-rc1-00071-gcaf61b1b8b88 #91
+[ 55.361693] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.11.0-0-g63451fca13-prebuilt.qemu-project.org 04/01/2014
+[ 55.363264] Call Trace:
+[ 55.363833] dump_stack+0x5c/0x77
+[ 55.364215] kasan_report+0x163/0x380
+[ 55.364610] ? rdma_init_qp_attr+0x4a/0x2c0
+[ 55.365238] rdma_init_qp_attr+0x4a/0x2c0
+[ 55.366410] ucma_init_qp_attr+0x111/0x200
+[ 55.366846] ? ucma_notify+0xf0/0xf0
+[ 55.367405] ? _get_random_bytes+0xea/0x1b0
+[ 55.367846] ? urandom_read+0x2f0/0x2f0
+[ 55.368436] ? kmem_cache_alloc_trace+0xd2/0x1e0
+[ 55.369104] ? refcount_inc_not_zero+0x9/0x60
+[ 55.369583] ? refcount_inc+0x5/0x30
+[ 55.370155] ? rdma_create_id+0x215/0x240
+[ 55.370937] ? _copy_to_user+0x4f/0x60
+[ 55.371620] ? mem_cgroup_commit_charge+0x1f5/0x290
+[ 55.372127] ? _copy_from_user+0x5e/0x90
+[ 55.372720] ucma_write+0x174/0x1f0
+[ 55.373090] ? ucma_close_id+0x40/0x40
+[ 55.373805] ? __lru_cache_add+0xa8/0xd0
+[ 55.374403] __vfs_write+0xc4/0x350
+[ 55.374774] ? kernel_read+0xa0/0xa0
+[ 55.375173] ? fsnotify+0x899/0x8f0
+[ 55.375544] ? fsnotify_unmount_inodes+0x170/0x170
+[ 55.376689] ? __fsnotify_update_child_dentry_flags+0x30/0x30
+[ 55.377522] ? handle_mm_fault+0x174/0x320
+[ 55.378169] vfs_write+0xf7/0x280
+[ 55.378864] SyS_write+0xa1/0x120
+[ 55.379270] ? SyS_read+0x120/0x120
+[ 55.379643] ? mm_fault_error+0x180/0x180
+[ 55.380071] ? task_work_run+0x7d/0xd0
+[ 55.380910] ? __task_pid_nr_ns+0x120/0x140
+[ 55.381366] ? SyS_read+0x120/0x120
+[ 55.381739] do_syscall_64+0xeb/0x250
+[ 55.382143] entry_SYSCALL_64_after_hwframe+0x21/0x86
+[ 55.382841] RIP: 0033:0x7fc2ef803e99
+[ 55.383227] RSP: 002b:00007fffcc5f3be8 EFLAGS: 00000217 ORIG_RAX: 0000000000000001
+[ 55.384173] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fc2ef803e99
+[ 55.386145] RDX: 0000000000000057 RSI: 0000000020000080 RDI: 0000000000000003
+[ 55.388418] RBP: 00007fffcc5f3c00 R08: 0000000000000000 R09: 0000000000000000
+[ 55.390542] R10: 0000000000000000 R11: 0000000000000217 R12: 0000000000400480
+[ 55.392916] R13: 00007fffcc5f3cf0 R14: 0000000000000000 R15: 0000000000000000
+[ 55.521088] Code: e5 4d 1e ff 48 89 df 44 0f b6 b3 b8 01 00 00 e8 65 50 1e ff 4c 8b 2b 49
+8d bd b0 00 00 00 e8 56 50 1e ff 41 0f b6 c6 48 c1 e0 04 <49> 03 85 b0 00 00 00 48 8d 78 08
+48 89 04 24 e8 3a 4f 1e ff 48
+[ 55.525980] RIP: rdma_init_qp_attr+0x52/0x2c0 RSP: ffff8801e2c2f9d8
+[ 55.532648] CR2: 00000000000000b0
+[ 55.534396] ---[ end trace 70cee64090251c0b ]---
+
+Fixes: 75216638572f ("RDMA/cma: Export rdma cm interface to userspace")
+Fixes: d541e45500bd ("IB/core: Convert ah_attr from OPA to IB when copying to user")
+Reported-by: <syzbot+7b62c837c2516f8f38c8@syzkaller.appspotmail.com>
+Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
+Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/core/ucma.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/infiniband/core/ucma.c
++++ b/drivers/infiniband/core/ucma.c
+@@ -1165,6 +1165,11 @@ static ssize_t ucma_init_qp_attr(struct
+ if (IS_ERR(ctx))
+ return PTR_ERR(ctx);
+
++ if (!ctx->cm_id->device) {
++ ret = -EINVAL;
++ goto out;
++ }
++
+ resp.qp_attr_mask = 0;
+ memset(&qp_attr, 0, sizeof qp_attr);
+ qp_attr.qp_state = cmd.qp_state;
--- /dev/null
+From e8980d67d6017c8eee8f9c35f782c4bd68e004c9 Mon Sep 17 00:00:00 2001
+From: Leon Romanovsky <leonro@mellanox.com>
+Date: Tue, 20 Mar 2018 17:05:13 +0200
+Subject: RDMA/ucma: Ensure that CM_ID exists prior to access it
+
+From: Leon Romanovsky <leonro@mellanox.com>
+
+commit e8980d67d6017c8eee8f9c35f782c4bd68e004c9 upstream.
+
+Prior to access UCMA commands, the context should be initialized
+and connected to CM_ID with ucma_create_id(). In case user skips
+this step, he can provide non-valid ctx without CM_ID and cause
+to multiple NULL dereferences.
+
+Also there are situations where the create_id can be raced with
+other user access, ensure that the context is only shared to
+other threads once it is fully initialized to avoid the races.
+
+[ 109.088108] BUG: unable to handle kernel NULL pointer dereference at 0000000000000020
+[ 109.090315] IP: ucma_connect+0x138/0x1d0
+[ 109.092595] PGD 80000001dc02d067 P4D 80000001dc02d067 PUD 1da9ef067 PMD 0
+[ 109.095384] Oops: 0000 [#1] SMP KASAN PTI
+[ 109.097834] CPU: 0 PID: 663 Comm: uclose Tainted: G B 4.16.0-rc1-00062-g2975d5de6428 #45
+[ 109.100816] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.11.0-0-g63451fca13-prebuilt.qemu-project.org 04/01/2014
+[ 109.105943] RIP: 0010:ucma_connect+0x138/0x1d0
+[ 109.108850] RSP: 0018:ffff8801c8567a80 EFLAGS: 00010246
+[ 109.111484] RAX: 0000000000000000 RBX: 1ffff100390acf50 RCX: ffffffff9d7812e2
+[ 109.114496] RDX: 1ffffffff3f507a5 RSI: 0000000000000297 RDI: 0000000000000297
+[ 109.117490] RBP: ffff8801daa15600 R08: 0000000000000000 R09: ffffed00390aceeb
+[ 109.120429] R10: 0000000000000001 R11: ffffed00390aceea R12: 0000000000000000
+[ 109.123318] R13: 0000000000000120 R14: ffff8801de6459c0 R15: 0000000000000118
+[ 109.126221] FS: 00007fabb68d6700(0000) GS:ffff8801e5c00000(0000) knlGS:0000000000000000
+[ 109.129468] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 109.132523] CR2: 0000000000000020 CR3: 00000001d45d8003 CR4: 00000000003606b0
+[ 109.135573] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+[ 109.138716] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+[ 109.142057] Call Trace:
+[ 109.144160] ? ucma_listen+0x110/0x110
+[ 109.146386] ? wake_up_q+0x59/0x90
+[ 109.148853] ? futex_wake+0x10b/0x2a0
+[ 109.151297] ? save_stack+0x89/0xb0
+[ 109.153489] ? _copy_from_user+0x5e/0x90
+[ 109.155500] ucma_write+0x174/0x1f0
+[ 109.157933] ? ucma_resolve_route+0xf0/0xf0
+[ 109.160389] ? __mod_node_page_state+0x1d/0x80
+[ 109.162706] __vfs_write+0xc4/0x350
+[ 109.164911] ? kernel_read+0xa0/0xa0
+[ 109.167121] ? path_openat+0x1b10/0x1b10
+[ 109.169355] ? fsnotify+0x899/0x8f0
+[ 109.171567] ? fsnotify_unmount_inodes+0x170/0x170
+[ 109.174145] ? __fget+0xa8/0xf0
+[ 109.177110] vfs_write+0xf7/0x280
+[ 109.179532] SyS_write+0xa1/0x120
+[ 109.181885] ? SyS_read+0x120/0x120
+[ 109.184482] ? compat_start_thread+0x60/0x60
+[ 109.187124] ? SyS_read+0x120/0x120
+[ 109.189548] do_syscall_64+0xeb/0x250
+[ 109.192178] entry_SYSCALL_64_after_hwframe+0x21/0x86
+[ 109.194725] RIP: 0033:0x7fabb61ebe99
+[ 109.197040] RSP: 002b:00007fabb68d5e98 EFLAGS: 00000202 ORIG_RAX: 0000000000000001
+[ 109.200294] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fabb61ebe99
+[ 109.203399] RDX: 0000000000000120 RSI: 00000000200001c0 RDI: 0000000000000004
+[ 109.206548] RBP: 00007fabb68d5ec0 R08: 0000000000000000 R09: 0000000000000000
+[ 109.209902] R10: 0000000000000000 R11: 0000000000000202 R12: 00007fabb68d5fc0
+[ 109.213327] R13: 0000000000000000 R14: 00007fff40ab2430 R15: 00007fabb68d69c0
+[ 109.216613] Code: 88 44 24 2c 0f b6 84 24 6e 01 00 00 88 44 24 2d 0f
+b6 84 24 69 01 00 00 88 44 24 2e 8b 44 24 60 89 44 24 30 e8 da f6 06 ff
+31 c0 <66> 41 83 7c 24 20 1b 75 04 8b 44 24 64 48 8d 74 24 20 4c 89 e7
+[ 109.223602] RIP: ucma_connect+0x138/0x1d0 RSP: ffff8801c8567a80
+[ 109.226256] CR2: 0000000000000020
+
+Fixes: 75216638572f ("RDMA/cma: Export rdma cm interface to userspace")
+Reported-by: <syzbot+36712f50b0552615bf59@syzkaller.appspotmail.com>
+Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
+Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/core/ucma.c | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+--- a/drivers/infiniband/core/ucma.c
++++ b/drivers/infiniband/core/ucma.c
+@@ -132,7 +132,7 @@ static inline struct ucma_context *_ucma
+ ctx = idr_find(&ctx_idr, id);
+ if (!ctx)
+ ctx = ERR_PTR(-ENOENT);
+- else if (ctx->file != file)
++ else if (ctx->file != file || !ctx->cm_id)
+ ctx = ERR_PTR(-EINVAL);
+ return ctx;
+ }
+@@ -456,6 +456,7 @@ static ssize_t ucma_create_id(struct ucm
+ struct rdma_ucm_create_id cmd;
+ struct rdma_ucm_create_id_resp resp;
+ struct ucma_context *ctx;
++ struct rdma_cm_id *cm_id;
+ enum ib_qp_type qp_type;
+ int ret;
+
+@@ -476,10 +477,10 @@ static ssize_t ucma_create_id(struct ucm
+ return -ENOMEM;
+
+ ctx->uid = cmd.uid;
+- ctx->cm_id = rdma_create_id(current->nsproxy->net_ns,
+- ucma_event_handler, ctx, cmd.ps, qp_type);
+- if (IS_ERR(ctx->cm_id)) {
+- ret = PTR_ERR(ctx->cm_id);
++ cm_id = rdma_create_id(current->nsproxy->net_ns,
++ ucma_event_handler, ctx, cmd.ps, qp_type);
++ if (IS_ERR(cm_id)) {
++ ret = PTR_ERR(cm_id);
+ goto err1;
+ }
+
+@@ -489,10 +490,12 @@ static ssize_t ucma_create_id(struct ucm
+ ret = -EFAULT;
+ goto err2;
+ }
++
++ ctx->cm_id = cm_id;
+ return 0;
+
+ err2:
+- rdma_destroy_id(ctx->cm_id);
++ rdma_destroy_id(cm_id);
+ err1:
+ mutex_lock(&mut);
+ idr_remove(&ctx_idr, ctx->id);
--- /dev/null
+From ed65a4dc22083e73bac599ded6a262318cad7baf Mon Sep 17 00:00:00 2001
+From: Leon Romanovsky <leonro@mellanox.com>
+Date: Mon, 19 Mar 2018 14:20:15 +0200
+Subject: RDMA/ucma: Fix use-after-free access in ucma_close
+
+From: Leon Romanovsky <leonro@mellanox.com>
+
+commit ed65a4dc22083e73bac599ded6a262318cad7baf upstream.
+
+The error in ucma_create_id() left ctx in the list of contexts belong
+to ucma file descriptor. The attempt to close this file descriptor causes
+to use-after-free accesses while iterating over such list.
+
+Fixes: 75216638572f ("RDMA/cma: Export rdma cm interface to userspace")
+Reported-by: <syzbot+dcfd344365a56fbebd0f@syzkaller.appspotmail.com>
+Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
+Reviewed-by: Sean Hefty <sean.hefty@intel.com>
+Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/core/ucma.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/infiniband/core/ucma.c
++++ b/drivers/infiniband/core/ucma.c
+@@ -497,6 +497,9 @@ err1:
+ mutex_lock(&mut);
+ idr_remove(&ctx_idr, ctx->id);
+ mutex_unlock(&mut);
++ mutex_lock(&file->mut);
++ list_del(&ctx->list);
++ mutex_unlock(&file->mut);
+ kfree(ctx);
+ return ret;
+ }
--- /dev/null
+From 84652aefb347297aa08e91e283adf7b18f77c2d5 Mon Sep 17 00:00:00 2001
+From: Roland Dreier <roland@purestorage.com>
+Date: Wed, 28 Mar 2018 11:27:22 -0700
+Subject: RDMA/ucma: Introduce safer rdma_addr_size() variants
+
+From: Roland Dreier <roland@purestorage.com>
+
+commit 84652aefb347297aa08e91e283adf7b18f77c2d5 upstream.
+
+There are several places in the ucma ABI where userspace can pass in a
+sockaddr but set the address family to AF_IB. When that happens,
+rdma_addr_size() will return a size bigger than sizeof struct sockaddr_in6,
+and the ucma kernel code might end up copying past the end of a buffer
+not sized for a struct sockaddr_ib.
+
+Fix this by introducing new variants
+
+ int rdma_addr_size_in6(struct sockaddr_in6 *addr);
+ int rdma_addr_size_kss(struct __kernel_sockaddr_storage *addr);
+
+that are type-safe for the types used in the ucma ABI and return 0 if the
+size computed is bigger than the size of the type passed in. We can use
+these new variants to check what size userspace has passed in before
+copying any addresses.
+
+Reported-by: <syzbot+6800425d54ed3ed8135d@syzkaller.appspotmail.com>
+Signed-off-by: Roland Dreier <roland@purestorage.com>
+Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/core/addr.c | 16 ++++++++++++++++
+ drivers/infiniband/core/ucma.c | 34 +++++++++++++++++-----------------
+ include/rdma/ib_addr.h | 2 ++
+ 3 files changed, 35 insertions(+), 17 deletions(-)
+
+--- a/drivers/infiniband/core/addr.c
++++ b/drivers/infiniband/core/addr.c
+@@ -207,6 +207,22 @@ int rdma_addr_size(struct sockaddr *addr
+ }
+ EXPORT_SYMBOL(rdma_addr_size);
+
++int rdma_addr_size_in6(struct sockaddr_in6 *addr)
++{
++ int ret = rdma_addr_size((struct sockaddr *) addr);
++
++ return ret <= sizeof(*addr) ? ret : 0;
++}
++EXPORT_SYMBOL(rdma_addr_size_in6);
++
++int rdma_addr_size_kss(struct __kernel_sockaddr_storage *addr)
++{
++ int ret = rdma_addr_size((struct sockaddr *) addr);
++
++ return ret <= sizeof(*addr) ? ret : 0;
++}
++EXPORT_SYMBOL(rdma_addr_size_kss);
++
+ static struct rdma_addr_client self;
+
+ void rdma_addr_register_client(struct rdma_addr_client *client)
+--- a/drivers/infiniband/core/ucma.c
++++ b/drivers/infiniband/core/ucma.c
+@@ -632,6 +632,9 @@ static ssize_t ucma_bind_ip(struct ucma_
+ if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+ return -EFAULT;
+
++ if (!rdma_addr_size_in6(&cmd.addr))
++ return -EINVAL;
++
+ ctx = ucma_get_ctx(file, cmd.id);
+ if (IS_ERR(ctx))
+ return PTR_ERR(ctx);
+@@ -645,22 +648,21 @@ static ssize_t ucma_bind(struct ucma_fil
+ int in_len, int out_len)
+ {
+ struct rdma_ucm_bind cmd;
+- struct sockaddr *addr;
+ struct ucma_context *ctx;
+ int ret;
+
+ if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+ return -EFAULT;
+
+- addr = (struct sockaddr *) &cmd.addr;
+- if (cmd.reserved || !cmd.addr_size || (cmd.addr_size != rdma_addr_size(addr)))
++ if (cmd.reserved || !cmd.addr_size ||
++ cmd.addr_size != rdma_addr_size_kss(&cmd.addr))
+ return -EINVAL;
+
+ ctx = ucma_get_ctx(file, cmd.id);
+ if (IS_ERR(ctx))
+ return PTR_ERR(ctx);
+
+- ret = rdma_bind_addr(ctx->cm_id, addr);
++ ret = rdma_bind_addr(ctx->cm_id, (struct sockaddr *) &cmd.addr);
+ ucma_put_ctx(ctx);
+ return ret;
+ }
+@@ -670,23 +672,22 @@ static ssize_t ucma_resolve_ip(struct uc
+ int in_len, int out_len)
+ {
+ struct rdma_ucm_resolve_ip cmd;
+- struct sockaddr *src, *dst;
+ struct ucma_context *ctx;
+ int ret;
+
+ if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+ return -EFAULT;
+
+- src = (struct sockaddr *) &cmd.src_addr;
+- dst = (struct sockaddr *) &cmd.dst_addr;
+- if (!rdma_addr_size(src) || !rdma_addr_size(dst))
++ if (!rdma_addr_size_in6(&cmd.src_addr) ||
++ !rdma_addr_size_in6(&cmd.dst_addr))
+ return -EINVAL;
+
+ ctx = ucma_get_ctx(file, cmd.id);
+ if (IS_ERR(ctx))
+ return PTR_ERR(ctx);
+
+- ret = rdma_resolve_addr(ctx->cm_id, src, dst, cmd.timeout_ms);
++ ret = rdma_resolve_addr(ctx->cm_id, (struct sockaddr *) &cmd.src_addr,
++ (struct sockaddr *) &cmd.dst_addr, cmd.timeout_ms);
+ ucma_put_ctx(ctx);
+ return ret;
+ }
+@@ -696,24 +697,23 @@ static ssize_t ucma_resolve_addr(struct
+ int in_len, int out_len)
+ {
+ struct rdma_ucm_resolve_addr cmd;
+- struct sockaddr *src, *dst;
+ struct ucma_context *ctx;
+ int ret;
+
+ if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+ return -EFAULT;
+
+- src = (struct sockaddr *) &cmd.src_addr;
+- dst = (struct sockaddr *) &cmd.dst_addr;
+- if (cmd.reserved || (cmd.src_size && (cmd.src_size != rdma_addr_size(src))) ||
+- !cmd.dst_size || (cmd.dst_size != rdma_addr_size(dst)))
++ if (cmd.reserved ||
++ (cmd.src_size && (cmd.src_size != rdma_addr_size_kss(&cmd.src_addr))) ||
++ !cmd.dst_size || (cmd.dst_size != rdma_addr_size_kss(&cmd.dst_addr)))
+ return -EINVAL;
+
+ ctx = ucma_get_ctx(file, cmd.id);
+ if (IS_ERR(ctx))
+ return PTR_ERR(ctx);
+
+- ret = rdma_resolve_addr(ctx->cm_id, src, dst, cmd.timeout_ms);
++ ret = rdma_resolve_addr(ctx->cm_id, (struct sockaddr *) &cmd.src_addr,
++ (struct sockaddr *) &cmd.dst_addr, cmd.timeout_ms);
+ ucma_put_ctx(ctx);
+ return ret;
+ }
+@@ -1432,7 +1432,7 @@ static ssize_t ucma_join_ip_multicast(st
+ join_cmd.response = cmd.response;
+ join_cmd.uid = cmd.uid;
+ join_cmd.id = cmd.id;
+- join_cmd.addr_size = rdma_addr_size((struct sockaddr *) &cmd.addr);
++ join_cmd.addr_size = rdma_addr_size_in6(&cmd.addr);
+ if (!join_cmd.addr_size)
+ return -EINVAL;
+
+@@ -1451,7 +1451,7 @@ static ssize_t ucma_join_multicast(struc
+ if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+ return -EFAULT;
+
+- if (!rdma_addr_size((struct sockaddr *)&cmd.addr))
++ if (!rdma_addr_size_kss(&cmd.addr))
+ return -EINVAL;
+
+ return ucma_process_join(file, &cmd, out_len);
+--- a/include/rdma/ib_addr.h
++++ b/include/rdma/ib_addr.h
+@@ -129,6 +129,8 @@ int rdma_copy_addr(struct rdma_dev_addr
+ const unsigned char *dst_dev_addr);
+
+ int rdma_addr_size(struct sockaddr *addr);
++int rdma_addr_size_in6(struct sockaddr_in6 *addr);
++int rdma_addr_size_kss(struct __kernel_sockaddr_storage *addr);
+
+ int rdma_addr_find_smac_by_sgid(union ib_gid *sgid, u8 *smac, u16 *vlan_id);
+ int rdma_addr_find_l2_eth_by_grh(const union ib_gid *sgid,
powerpc-64s-fix-lost-pending-interrupt-due-to-race-causing-lost-update-to-irq_happened.patch
powerpc-64s-fix-i-side-slb-miss-bad-address-handler-saving-nonvolatile-gprs.patch
partitions-msdos-unable-to-mount-ufs-44bsd-partitions.patch
+xfrm_user-uncoditionally-validate-esn-replay-attribute-struct.patch
+rdma-ucma-check-af-family-prior-resolving-address.patch
+rdma-ucma-fix-use-after-free-access-in-ucma_close.patch
+rdma-ucma-ensure-that-cm_id-exists-prior-to-access-it.patch
+rdma-rdma_cm-fix-use-after-free-race-with-process_one_req.patch
+rdma-ucma-check-that-device-is-connected-prior-to-access-it.patch
+rdma-ucma-check-that-device-exists-prior-to-accessing-it.patch
+rdma-ucma-introduce-safer-rdma_addr_size-variants.patch
--- /dev/null
+From d97ca5d714a5334aecadadf696875da40f1fbf3e Mon Sep 17 00:00:00 2001
+From: Florian Westphal <fw@strlen.de>
+Date: Mon, 12 Feb 2018 14:42:01 +0100
+Subject: xfrm_user: uncoditionally validate esn replay attribute struct
+
+From: Florian Westphal <fw@strlen.de>
+
+commit d97ca5d714a5334aecadadf696875da40f1fbf3e upstream.
+
+The sanity test added in ecd7918745234 can be bypassed, validation
+only occurs if XFRM_STATE_ESN flag is set, but rest of code doesn't care
+and just checks if the attribute itself is present.
+
+So always validate. Alternative is to reject if we have the attribute
+without the flag but that would change abi.
+
+Reported-by: syzbot+0ab777c27d2bb7588f73@syzkaller.appspotmail.com
+Cc: Mathias Krause <minipli@googlemail.com>
+Fixes: ecd7918745234 ("xfrm_user: ensure user supplied esn replay window is valid")
+Fixes: d8647b79c3b7e ("xfrm: Add user interface for esn and big anti-replay windows")
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/xfrm/xfrm_user.c | 21 ++++++++-------------
+ 1 file changed, 8 insertions(+), 13 deletions(-)
+
+--- a/net/xfrm/xfrm_user.c
++++ b/net/xfrm/xfrm_user.c
+@@ -121,22 +121,17 @@ static inline int verify_replay(struct x
+ struct nlattr *rt = attrs[XFRMA_REPLAY_ESN_VAL];
+ struct xfrm_replay_state_esn *rs;
+
+- if (p->flags & XFRM_STATE_ESN) {
+- if (!rt)
+- return -EINVAL;
+-
+- rs = nla_data(rt);
++ if (!rt)
++ return (p->flags & XFRM_STATE_ESN) ? -EINVAL : 0;
+
+- if (rs->bmp_len > XFRMA_REPLAY_ESN_MAX / sizeof(rs->bmp[0]) / 8)
+- return -EINVAL;
++ rs = nla_data(rt);
+
+- if (nla_len(rt) < xfrm_replay_state_esn_len(rs) &&
+- nla_len(rt) != sizeof(*rs))
+- return -EINVAL;
+- }
++ if (rs->bmp_len > XFRMA_REPLAY_ESN_MAX / sizeof(rs->bmp[0]) / 8)
++ return -EINVAL;
+
+- if (!rt)
+- return 0;
++ if (nla_len(rt) < xfrm_replay_state_esn_len(rs) &&
++ nla_len(rt) != sizeof(*rs))
++ return -EINVAL;
+
+ /* As only ESP and AH support ESN feature. */
+ if ((p->id.proto != IPPROTO_ESP) && (p->id.proto != IPPROTO_AH))