From: Greg Kroah-Hartman Date: Tue, 3 Apr 2018 16:03:44 +0000 (+0200) Subject: 4.4-stable patches X-Git-Tag: v3.18.103~40 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=83ac1a27deb5ca560af6d106a5e044805cb0aaf3;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: arm64-avoid-overflow-in-va_start-and-page_offset.patch audit-add-tty-field-to-login-event.patch netfilter-ctnetlink-make-some-parameters-integer-to-avoid-enum-mismatch.patch rdma-ucma-check-af-family-prior-resolving-address.patch rdma-ucma-check-that-device-exists-prior-to-accessing-it.patch rdma-ucma-check-that-device-is-connected-prior-to-access-it.patch rdma-ucma-don-t-allow-join-attempts-for-unsupported-af-family.patch rdma-ucma-ensure-that-cm_id-exists-prior-to-access-it.patch rdma-ucma-fix-use-after-free-access-in-ucma_close.patch rdma-ucma-introduce-safer-rdma_addr_size-variants.patch selinux-remove-redundant-check-for-unknown-labeling-behavior.patch tty-provide-tty_name-even-without-config_tty.patch xfrm_user-uncoditionally-validate-esn-replay-attribute-struct.patch --- diff --git a/queue-4.4/arm64-avoid-overflow-in-va_start-and-page_offset.patch b/queue-4.4/arm64-avoid-overflow-in-va_start-and-page_offset.patch new file mode 100644 index 00000000000..2e7ac4453b0 --- /dev/null +++ b/queue-4.4/arm64-avoid-overflow-in-va_start-and-page_offset.patch @@ -0,0 +1,53 @@ +From 82cd588052815eb4146f9f7c5347ca5e32c56360 Mon Sep 17 00:00:00 2001 +From: Nick Desaulniers +Date: Thu, 3 Aug 2017 11:03:58 -0700 +Subject: arm64: avoid overflow in VA_START and PAGE_OFFSET + +From: Nick Desaulniers + +commit 82cd588052815eb4146f9f7c5347ca5e32c56360 upstream. + +The bitmask used to define these values produces overflow, as seen by +this compiler warning: + +arch/arm64/kernel/head.S:47:8: warning: + integer overflow in preprocessor expression + #elif (PAGE_OFFSET & 0x1fffff) != 0 + ^~~~~~~~~~~ +arch/arm64/include/asm/memory.h:52:46: note: + expanded from macro 'PAGE_OFFSET' + #define PAGE_OFFSET (UL(0xffffffffffffffff) << (VA_BITS - +1)) + ~~~~~~~~~~~~~~~~~~ ^ + +It would be preferrable to use GENMASK_ULL() instead, but it's not set +up to be used from assembly (the UL() macro token pastes UL suffixes +when not included in assembly sources). + +Suggested-by: Ard Biesheuvel +Suggested-by: Yury Norov +Suggested-by: Matthias Kaehlcke +Signed-off-by: Nick Desaulniers +Signed-off-by: Will Deacon +[natechancellor: KIMAGE_VADDR doesn't exist] +Signed-off-by: Nathan Chancellor +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/include/asm/memory.h | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/arch/arm64/include/asm/memory.h ++++ b/arch/arm64/include/asm/memory.h +@@ -49,8 +49,10 @@ + * and PAGE_OFFSET - it must be within 128MB of the kernel text. + */ + #define VA_BITS (CONFIG_ARM64_VA_BITS) +-#define VA_START (UL(0xffffffffffffffff) << VA_BITS) +-#define PAGE_OFFSET (UL(0xffffffffffffffff) << (VA_BITS - 1)) ++#define VA_START (UL(0xffffffffffffffff) - \ ++ (UL(1) << VA_BITS) + 1) ++#define PAGE_OFFSET (UL(0xffffffffffffffff) - \ ++ (UL(1) << (VA_BITS - 1)) + 1) + #define MODULES_END (PAGE_OFFSET) + #define MODULES_VADDR (MODULES_END - SZ_64M) + #define PCI_IO_END (MODULES_VADDR - SZ_2M) diff --git a/queue-4.4/audit-add-tty-field-to-login-event.patch b/queue-4.4/audit-add-tty-field-to-login-event.patch new file mode 100644 index 00000000000..233050eb236 --- /dev/null +++ b/queue-4.4/audit-add-tty-field-to-login-event.patch @@ -0,0 +1,152 @@ +From db0a6fb5d97afe01fd9c47d37c6daa82d4d4001d Mon Sep 17 00:00:00 2001 +From: Richard Guy Briggs +Date: Thu, 21 Apr 2016 14:14:01 -0400 +Subject: audit: add tty field to LOGIN event + +From: Richard Guy Briggs + +commit db0a6fb5d97afe01fd9c47d37c6daa82d4d4001d upstream. + +The tty field was missing from AUDIT_LOGIN events. + +Refactor code to create a new function audit_get_tty(), using it to +replace the call in audit_log_task_info() and to add it to +audit_log_set_loginuid(). Lock and bump the kref to protect it, adding +audit_put_tty() alias to decrement it. + +Signed-off-by: Richard Guy Briggs +Signed-off-by: Paul Moore +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/audit.h | 24 ++++++++++++++++++++++++ + kernel/audit.c | 18 +++++------------- + kernel/auditsc.c | 8 ++++++-- + 3 files changed, 35 insertions(+), 15 deletions(-) + +--- a/include/linux/audit.h ++++ b/include/linux/audit.h +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + #define AUDIT_INO_UNSET ((unsigned long)-1) + #define AUDIT_DEV_UNSET ((dev_t)-1) +@@ -239,6 +240,23 @@ static inline unsigned int audit_get_ses + return tsk->sessionid; + } + ++static inline struct tty_struct *audit_get_tty(struct task_struct *tsk) ++{ ++ struct tty_struct *tty = NULL; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&tsk->sighand->siglock, flags); ++ if (tsk->signal) ++ tty = tty_kref_get(tsk->signal->tty); ++ spin_unlock_irqrestore(&tsk->sighand->siglock, flags); ++ return tty; ++} ++ ++static inline void audit_put_tty(struct tty_struct *tty) ++{ ++ tty_kref_put(tty); ++} ++ + extern void __audit_ipc_obj(struct kern_ipc_perm *ipcp); + extern void __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, umode_t mode); + extern void __audit_bprm(struct linux_binprm *bprm); +@@ -410,6 +428,12 @@ static inline unsigned int audit_get_ses + { + return -1; + } ++static inline struct tty_struct *audit_get_tty(struct task_struct *tsk) ++{ ++ return NULL; ++} ++static inline void audit_put_tty(struct tty_struct *tty) ++{ } + static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp) + { } + static inline void audit_ipc_set_perm(unsigned long qbytes, uid_t uid, +--- a/kernel/audit.c ++++ b/kernel/audit.c +@@ -64,7 +64,6 @@ + #include + #endif + #include +-#include + #include + #include + +@@ -1876,21 +1875,14 @@ void audit_log_task_info(struct audit_bu + { + const struct cred *cred; + char comm[sizeof(tsk->comm)]; +- char *tty; ++ struct tty_struct *tty; + + if (!ab) + return; + + /* tsk == current */ + cred = current_cred(); +- +- spin_lock_irq(&tsk->sighand->siglock); +- if (tsk->signal && tsk->signal->tty && tsk->signal->tty->name) +- tty = tsk->signal->tty->name; +- else +- tty = "(none)"; +- spin_unlock_irq(&tsk->sighand->siglock); +- ++ tty = audit_get_tty(tsk); + audit_log_format(ab, + " ppid=%d pid=%d auid=%u uid=%u gid=%u" + " euid=%u suid=%u fsuid=%u" +@@ -1906,11 +1898,11 @@ void audit_log_task_info(struct audit_bu + from_kgid(&init_user_ns, cred->egid), + from_kgid(&init_user_ns, cred->sgid), + from_kgid(&init_user_ns, cred->fsgid), +- tty, audit_get_sessionid(tsk)); +- ++ tty ? tty_name(tty) : "(none)", ++ audit_get_sessionid(tsk)); ++ audit_put_tty(tty); + audit_log_format(ab, " comm="); + audit_log_untrustedstring(ab, get_task_comm(comm, tsk)); +- + audit_log_d_path_exe(ab, tsk->mm); + audit_log_task_context(ab); + } +--- a/kernel/auditsc.c ++++ b/kernel/auditsc.c +@@ -1976,6 +1976,7 @@ static void audit_log_set_loginuid(kuid_ + { + struct audit_buffer *ab; + uid_t uid, oldloginuid, loginuid; ++ struct tty_struct *tty; + + if (!audit_enabled) + return; +@@ -1983,14 +1984,17 @@ static void audit_log_set_loginuid(kuid_ + uid = from_kuid(&init_user_ns, task_uid(current)); + oldloginuid = from_kuid(&init_user_ns, koldloginuid); + loginuid = from_kuid(&init_user_ns, kloginuid), ++ tty = audit_get_tty(current); + + ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOGIN); + if (!ab) + return; + audit_log_format(ab, "pid=%d uid=%u", task_pid_nr(current), uid); + audit_log_task_context(ab); +- audit_log_format(ab, " old-auid=%u auid=%u old-ses=%u ses=%u res=%d", +- oldloginuid, loginuid, oldsessionid, sessionid, !rc); ++ audit_log_format(ab, " old-auid=%u auid=%u tty=%s old-ses=%u ses=%u res=%d", ++ oldloginuid, loginuid, tty ? tty_name(tty) : "(none)", ++ oldsessionid, sessionid, !rc); ++ audit_put_tty(tty); + audit_log_end(ab); + } + diff --git a/queue-4.4/netfilter-ctnetlink-make-some-parameters-integer-to-avoid-enum-mismatch.patch b/queue-4.4/netfilter-ctnetlink-make-some-parameters-integer-to-avoid-enum-mismatch.patch new file mode 100644 index 00000000000..7727eed5e10 --- /dev/null +++ b/queue-4.4/netfilter-ctnetlink-make-some-parameters-integer-to-avoid-enum-mismatch.patch @@ -0,0 +1,46 @@ +From a2b7cbdd2559aff06cebc28a7150f81c307a90d3 Mon Sep 17 00:00:00 2001 +From: Matthias Kaehlcke +Date: Wed, 19 Apr 2017 11:39:20 -0700 +Subject: netfilter: ctnetlink: Make some parameters integer to avoid enum mismatch + +From: Matthias Kaehlcke + +commit a2b7cbdd2559aff06cebc28a7150f81c307a90d3 upstream. + +Not all parameters passed to ctnetlink_parse_tuple() and +ctnetlink_exp_dump_tuple() match the enum type in the signatures of these +functions. Since this is intended change the argument type of to be an +unsigned integer value. + +Signed-off-by: Matthias Kaehlcke +Signed-off-by: Pablo Neira Ayuso +[natechancellor: ctnetlink_exp_dump_tuple is still inline] +Signed-off-by: Nathan Chancellor +Signed-off-by: Greg Kroah-Hartman +--- + net/netfilter/nf_conntrack_netlink.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +--- a/net/netfilter/nf_conntrack_netlink.c ++++ b/net/netfilter/nf_conntrack_netlink.c +@@ -999,9 +999,8 @@ static const struct nla_policy tuple_nla + + static int + ctnetlink_parse_tuple(const struct nlattr * const cda[], +- struct nf_conntrack_tuple *tuple, +- enum ctattr_type type, u_int8_t l3num, +- struct nf_conntrack_zone *zone) ++ struct nf_conntrack_tuple *tuple, u32 type, ++ u_int8_t l3num, struct nf_conntrack_zone *zone) + { + struct nlattr *tb[CTA_TUPLE_MAX+1]; + int err; +@@ -2416,7 +2415,7 @@ static struct nfnl_ct_hook ctnetlink_glu + static inline int + ctnetlink_exp_dump_tuple(struct sk_buff *skb, + const struct nf_conntrack_tuple *tuple, +- enum ctattr_expect type) ++ u32 type) + { + struct nlattr *nest_parms; + diff --git a/queue-4.4/rdma-ucma-check-af-family-prior-resolving-address.patch b/queue-4.4/rdma-ucma-check-af-family-prior-resolving-address.patch new file mode 100644 index 00000000000..ef46cd0310d --- /dev/null +++ b/queue-4.4/rdma-ucma-check-af-family-prior-resolving-address.patch @@ -0,0 +1,171 @@ +From 2975d5de6428ff6d9317e9948f0968f7d42e5d74 Mon Sep 17 00:00:00 2001 +From: Leon Romanovsky +Date: Thu, 15 Mar 2018 15:33:02 +0200 +Subject: RDMA/ucma: Check AF family prior resolving address + +From: Leon Romanovsky + +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 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: +Fixes: 75216638572f ("RDMA/cma: Export rdma cm interface to userspace") +Signed-off-by: Leon Romanovsky +Reviewed-by: Sean Hefty +Signed-off-by: Jason Gunthorpe +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -661,19 +661,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; + } diff --git a/queue-4.4/rdma-ucma-check-that-device-exists-prior-to-accessing-it.patch b/queue-4.4/rdma-ucma-check-that-device-exists-prior-to-accessing-it.patch new file mode 100644 index 00000000000..6a9839676bc --- /dev/null +++ b/queue-4.4/rdma-ucma-check-that-device-exists-prior-to-accessing-it.patch @@ -0,0 +1,43 @@ +From c8d3bcbfc5eab3f01cf373d039af725f3b488813 Mon Sep 17 00:00:00 2001 +From: Leon Romanovsky +Date: Sun, 25 Mar 2018 11:39:05 +0300 +Subject: RDMA/ucma: Check that device exists prior to accessing it + +From: Leon Romanovsky + +commit c8d3bcbfc5eab3f01cf373d039af725f3b488813 upstream. + +Ensure that device exists prior to accessing its properties. + +Reported-by: +Fixes: 75216638572f ("RDMA/cma: Export rdma cm interface to userspace") +Signed-off-by: Leon Romanovsky +Signed-off-by: Jason Gunthorpe +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -1316,7 +1316,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; +@@ -1325,7 +1325,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; + } diff --git a/queue-4.4/rdma-ucma-check-that-device-is-connected-prior-to-access-it.patch b/queue-4.4/rdma-ucma-check-that-device-is-connected-prior-to-access-it.patch new file mode 100644 index 00000000000..4267060dd49 --- /dev/null +++ b/queue-4.4/rdma-ucma-check-that-device-is-connected-prior-to-access-it.patch @@ -0,0 +1,89 @@ +From 4b658d1bbc16605330694bb3ef2570c465ef383d Mon Sep 17 00:00:00 2001 +From: Leon Romanovsky +Date: Sun, 25 Mar 2018 11:23:55 +0300 +Subject: RDMA/ucma: Check that device is connected prior to access it + +From: Leon Romanovsky + +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: +Signed-off-by: Leon Romanovsky +Signed-off-by: Jason Gunthorpe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/core/ucma.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/infiniband/core/ucma.c ++++ b/drivers/infiniband/core/ucma.c +@@ -1155,6 +1155,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; diff --git a/queue-4.4/rdma-ucma-don-t-allow-join-attempts-for-unsupported-af-family.patch b/queue-4.4/rdma-ucma-don-t-allow-join-attempts-for-unsupported-af-family.patch new file mode 100644 index 00000000000..4c61af46676 --- /dev/null +++ b/queue-4.4/rdma-ucma-don-t-allow-join-attempts-for-unsupported-af-family.patch @@ -0,0 +1,99 @@ +From 0c81ffc60d5280991773d17e84bda605387148b1 Mon Sep 17 00:00:00 2001 +From: Leon Romanovsky +Date: Tue, 13 Mar 2018 18:37:27 +0200 +Subject: RDMA/ucma: Don't allow join attempts for unsupported AF family + +From: Leon Romanovsky + +commit 0c81ffc60d5280991773d17e84bda605387148b1 upstream. + +Users can provide garbage while calling to ucma_join_ip_multicast(), +it will indirectly cause to rdma_addr_size() return 0, making the +call to ucma_process_join(), which had the right checks, but it is +better to check the input as early as possible. + +The following crash from syzkaller revealed it. + +kernel BUG at lib/string.c:1052! +invalid opcode: 0000 [#1] SMP KASAN Dumping ftrace buffer: + (ftrace buffer empty) +Modules linked in: +CPU: 0 PID: 4113 Comm: syz-executor0 Not tainted 4.16.0-rc5+ #261 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +RIP: 0010:fortify_panic+0x13/0x20 lib/string.c:1051 +RSP: 0018:ffff8801ca81f8f0 EFLAGS: 00010286 +RAX: 0000000000000022 RBX: 1ffff10039503f23 RCX: 0000000000000000 +RDX: 0000000000000022 RSI: 1ffff10039503ed3 RDI: ffffed0039503f12 +RBP: ffff8801ca81f8f0 R08: 0000000000000000 R09: 0000000000000000 +R10: 0000000000000006 R11: 0000000000000000 R12: ffff8801ca81f998 +R13: ffff8801ca81f938 R14: ffff8801ca81fa58 R15: 000000000000fa00 +FS: 0000000000000000(0000) GS:ffff8801db200000(0063) knlGS:000000000a12a900 +CS: 0010 DS: 002b ES: 002b CR0: 0000000080050033 +CR2: 0000000008138024 CR3: 00000001cbb58004 CR4: 00000000001606f0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +Call Trace: + memcpy include/linux/string.h:344 [inline] + ucma_join_ip_multicast+0x36b/0x3b0 drivers/infiniband/core/ucma.c:1421 + ucma_write+0x2d6/0x3d0 drivers/infiniband/core/ucma.c:1633 + __vfs_write+0xef/0x970 fs/read_write.c:480 + vfs_write+0x189/0x510 fs/read_write.c:544 + SYSC_write fs/read_write.c:589 [inline] + SyS_write+0xef/0x220 fs/read_write.c:581 + do_syscall_32_irqs_on arch/x86/entry/common.c:330 [inline] + do_fast_syscall_32+0x3ec/0xf9f arch/x86/entry/common.c:392 + entry_SYSENTER_compat+0x70/0x7f arch/x86/entry/entry_64_compat.S:139 +RIP: 0023:0xf7f9ec99 +RSP: 002b:00000000ff8172cc EFLAGS: 00000282 ORIG_RAX: 0000000000000004 +RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 0000000020000100 +RDX: 0000000000000063 RSI: 0000000000000000 RDI: 0000000000000000 +RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 +R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 +Code: 08 5b 41 5c 41 5d 41 5e 41 5f 5d c3 0f 0b 48 89 df e8 42 2c e3 fb eb de +55 48 89 fe 48 c7 c7 80 75 98 86 48 89 e5 e8 85 95 94 fb <0f> 0b 90 90 90 90 +90 90 90 90 90 90 90 55 48 89 e5 41 57 41 56 +RIP: fortify_panic+0x13/0x20 lib/string.c:1051 RSP: ffff8801ca81f8f0 + +Fixes: 5bc2b7b397b0 ("RDMA/ucma: Allow user space to specify AF_IB when joining multicast") +Reported-by: +Signed-off-by: Leon Romanovsky +Reviewed-by: Sean Hefty +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/core/ucma.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/drivers/infiniband/core/ucma.c ++++ b/drivers/infiniband/core/ucma.c +@@ -1345,7 +1345,7 @@ static ssize_t ucma_process_join(struct + return -ENOSPC; + + addr = (struct sockaddr *) &cmd->addr; +- if (cmd->reserved || !cmd->addr_size || (cmd->addr_size != rdma_addr_size(addr))) ++ if (cmd->reserved || (cmd->addr_size != rdma_addr_size(addr))) + return -EINVAL; + + ctx = ucma_get_ctx(file, cmd->id); +@@ -1405,6 +1405,9 @@ static ssize_t ucma_join_ip_multicast(st + join_cmd.uid = cmd.uid; + join_cmd.id = cmd.id; + join_cmd.addr_size = rdma_addr_size((struct sockaddr *) &cmd.addr); ++ if (!join_cmd.addr_size) ++ return -EINVAL; ++ + join_cmd.reserved = 0; + memcpy(&join_cmd.addr, &cmd.addr, join_cmd.addr_size); + +@@ -1420,6 +1423,9 @@ 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)) ++ return -EINVAL; ++ + return ucma_process_join(file, &cmd, out_len); + } + diff --git a/queue-4.4/rdma-ucma-ensure-that-cm_id-exists-prior-to-access-it.patch b/queue-4.4/rdma-ucma-ensure-that-cm_id-exists-prior-to-access-it.patch new file mode 100644 index 00000000000..1002ea7d2ed --- /dev/null +++ b/queue-4.4/rdma-ucma-ensure-that-cm_id-exists-prior-to-access-it.patch @@ -0,0 +1,129 @@ +From e8980d67d6017c8eee8f9c35f782c4bd68e004c9 Mon Sep 17 00:00:00 2001 +From: Leon Romanovsky +Date: Tue, 20 Mar 2018 17:05:13 +0200 +Subject: RDMA/ucma: Ensure that CM_ID exists prior to access it + +From: Leon Romanovsky + +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: +Signed-off-by: Leon Romanovsky +Signed-off-by: Jason Gunthorpe +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -131,7 +131,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; + } +@@ -453,6 +453,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; + +@@ -473,10 +474,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; + } + +@@ -486,10 +487,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); diff --git a/queue-4.4/rdma-ucma-fix-use-after-free-access-in-ucma_close.patch b/queue-4.4/rdma-ucma-fix-use-after-free-access-in-ucma_close.patch new file mode 100644 index 00000000000..58c4566cb11 --- /dev/null +++ b/queue-4.4/rdma-ucma-fix-use-after-free-access-in-ucma_close.patch @@ -0,0 +1,36 @@ +From ed65a4dc22083e73bac599ded6a262318cad7baf Mon Sep 17 00:00:00 2001 +From: Leon Romanovsky +Date: Mon, 19 Mar 2018 14:20:15 +0200 +Subject: RDMA/ucma: Fix use-after-free access in ucma_close + +From: Leon Romanovsky + +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: +Signed-off-by: Leon Romanovsky +Reviewed-by: Sean Hefty +Signed-off-by: Jason Gunthorpe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/core/ucma.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/infiniband/core/ucma.c ++++ b/drivers/infiniband/core/ucma.c +@@ -494,6 +494,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; + } diff --git a/queue-4.4/rdma-ucma-introduce-safer-rdma_addr_size-variants.patch b/queue-4.4/rdma-ucma-introduce-safer-rdma_addr_size-variants.patch new file mode 100644 index 00000000000..8fdbb95fb69 --- /dev/null +++ b/queue-4.4/rdma-ucma-introduce-safer-rdma_addr_size-variants.patch @@ -0,0 +1,186 @@ +From 84652aefb347297aa08e91e283adf7b18f77c2d5 Mon Sep 17 00:00:00 2001 +From: Roland Dreier +Date: Wed, 28 Mar 2018 11:27:22 -0700 +Subject: RDMA/ucma: Introduce safer rdma_addr_size() variants + +From: Roland Dreier + +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: +Signed-off-by: Roland Dreier +Signed-off-by: Jason Gunthorpe +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -86,6 +86,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 +@@ -629,6 +629,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); +@@ -642,22 +645,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; + } +@@ -667,23 +669,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; + } +@@ -693,24 +694,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; + } +@@ -1404,7 +1404,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; + +@@ -1423,7 +1423,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 +@@ -123,6 +123,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_dmac_by_grh(const union ib_gid *sgid, const union ib_gid *dgid, diff --git a/queue-4.4/selinux-remove-redundant-check-for-unknown-labeling-behavior.patch b/queue-4.4/selinux-remove-redundant-check-for-unknown-labeling-behavior.patch new file mode 100644 index 00000000000..710572487a1 --- /dev/null +++ b/queue-4.4/selinux-remove-redundant-check-for-unknown-labeling-behavior.patch @@ -0,0 +1,59 @@ +From 270e8573145a26de924e2dc644596332d400445b Mon Sep 17 00:00:00 2001 +From: Matthias Kaehlcke +Date: Fri, 19 May 2017 10:09:32 -0700 +Subject: selinux: Remove redundant check for unknown labeling behavior + +From: Matthias Kaehlcke + +commit 270e8573145a26de924e2dc644596332d400445b upstream. + +The check is already performed in ocontext_read() when the policy is +loaded. Removing the array also fixes the following warning when +building with clang: + +security/selinux/hooks.c:338:20: error: variable 'labeling_behaviors' + is not needed and will not be emitted + [-Werror,-Wunneeded-internal-declaration] + +Signed-off-by: Matthias Kaehlcke +Acked-by: Stephen Smalley +Signed-off-by: Paul Moore +[natechancellor: inode_doinit_with_dentry still present] +Signed-off-by: Nathan Chancellor +Signed-off-by: Greg Kroah-Hartman +--- + security/selinux/hooks.c | 16 ---------------- + 1 file changed, 16 deletions(-) + +--- a/security/selinux/hooks.c ++++ b/security/selinux/hooks.c +@@ -333,18 +333,6 @@ static void superblock_free_security(str + kfree(sbsec); + } + +-/* The file system's label must be initialized prior to use. */ +- +-static const char *labeling_behaviors[7] = { +- "uses xattr", +- "uses transition SIDs", +- "uses task SIDs", +- "uses genfs_contexts", +- "not configured for labeling", +- "uses mountpoint labeling", +- "uses native labeling", +-}; +- + static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry); + + static inline int inode_doinit(struct inode *inode) +@@ -456,10 +444,6 @@ static int sb_finish_set_opts(struct sup + } + } + +- if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors)) +- printk(KERN_ERR "SELinux: initialized (dev %s, type %s), unknown behavior\n", +- sb->s_id, sb->s_type->name); +- + sbsec->flags |= SE_SBINITIALIZED; + if (selinux_is_sblabel_mnt(sb)) + sbsec->flags |= SBLABEL_MNT; diff --git a/queue-4.4/series b/queue-4.4/series index c938f2dc423..2a9f3915d2a 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -21,3 +21,16 @@ selinux-remove-unnecessary-check-of-array-base-in-selinux_set_mapping.patch fs-compat-remove-warning-from-compatible_ioctl.patch jiffies.h-declare-jiffies-and-jiffies_64-with-____cacheline_aligned_in_smp.patch frv-declare-jiffies-to-be-located-in-the-.data-section.patch +audit-add-tty-field-to-login-event.patch +tty-provide-tty_name-even-without-config_tty.patch +netfilter-ctnetlink-make-some-parameters-integer-to-avoid-enum-mismatch.patch +selinux-remove-redundant-check-for-unknown-labeling-behavior.patch +arm64-avoid-overflow-in-va_start-and-page_offset.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-ucma-check-that-device-is-connected-prior-to-access-it.patch +rdma-ucma-check-that-device-exists-prior-to-accessing-it.patch +rdma-ucma-don-t-allow-join-attempts-for-unsupported-af-family.patch +rdma-ucma-introduce-safer-rdma_addr_size-variants.patch diff --git a/queue-4.4/tty-provide-tty_name-even-without-config_tty.patch b/queue-4.4/tty-provide-tty_name-even-without-config_tty.patch new file mode 100644 index 00000000000..afb96132b96 --- /dev/null +++ b/queue-4.4/tty-provide-tty_name-even-without-config_tty.patch @@ -0,0 +1,57 @@ +From 188e3c5cd2b672620291e64a21f1598fe91e40b6 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Wed, 27 Apr 2016 11:56:04 +0200 +Subject: tty: provide tty_name() even without CONFIG_TTY + +From: Arnd Bergmann + +commit 188e3c5cd2b672620291e64a21f1598fe91e40b6 upstream. + +The audit subsystem just started printing the name of the tty, +but that causes a build failure when CONFIG_TTY is disabled: + +kernel/built-in.o: In function `audit_log_task_info': +memremap.c:(.text+0x5e34c): undefined reference to `tty_name' +kernel/built-in.o: In function `audit_set_loginuid': +memremap.c:(.text+0x63b34): undefined reference to `tty_name' + +This adds tty_name() to the list of functions that are provided +as trivial stubs in that configuration. + +Signed-off-by: Arnd Bergmann +Fixes: db0a6fb5d97a ("audit: add tty field to LOGIN event") +Signed-off-by: Paul Moore +[natechancellor: tty_paranoia_check still exists] +Signed-off-by: Nathan Chancellor +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/tty.h | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/include/linux/tty.h ++++ b/include/linux/tty.h +@@ -372,6 +372,7 @@ extern void proc_clear_tty(struct task_s + extern struct tty_struct *get_current_tty(void); + /* tty_io.c */ + extern int __init tty_init(void); ++extern const char *tty_name(const struct tty_struct *tty); + #else + static inline void console_init(void) + { } +@@ -392,6 +393,8 @@ static inline struct tty_struct *get_cur + /* tty_io.c */ + static inline int __init tty_init(void) + { return 0; } ++static inline const char *tty_name(const struct tty_struct *tty) ++{ return "(none)"; } + #endif + + extern void tty_write_flush(struct tty_struct *); +@@ -420,7 +423,6 @@ static inline struct tty_struct *tty_kre + + extern int tty_paranoia_check(struct tty_struct *tty, struct inode *inode, + const char *routine); +-extern const char *tty_name(const struct tty_struct *tty); + extern void tty_wait_until_sent(struct tty_struct *tty, long timeout); + extern int __tty_check_change(struct tty_struct *tty, int sig); + extern int tty_check_change(struct tty_struct *tty); diff --git a/queue-4.4/xfrm_user-uncoditionally-validate-esn-replay-attribute-struct.patch b/queue-4.4/xfrm_user-uncoditionally-validate-esn-replay-attribute-struct.patch new file mode 100644 index 00000000000..fdb767de4a2 --- /dev/null +++ b/queue-4.4/xfrm_user-uncoditionally-validate-esn-replay-attribute-struct.patch @@ -0,0 +1,61 @@ +From d97ca5d714a5334aecadadf696875da40f1fbf3e Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Mon, 12 Feb 2018 14:42:01 +0100 +Subject: xfrm_user: uncoditionally validate esn replay attribute struct + +From: Florian Westphal + +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 +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 +Signed-off-by: Steffen Klassert +Signed-off-by: Greg Kroah-Hartman + +--- + 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))