From: Greg Kroah-Hartman Date: Tue, 3 Apr 2018 16:43:43 +0000 (+0200) Subject: 3.18-stable patches X-Git-Tag: v3.18.103~38 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a68229f4368a1ce19e947da0bbf68a973a36c48a;p=thirdparty%2Fkernel%2Fstable-queue.git 3.18-stable patches added patches: bluetooth-fix-missing-encryption-refresh-on-security-request.patch net-xfrm-use-preempt-safe-this_cpu_read-in-ipcomp_alloc_tfms.patch netfilter-bridge-ebt_among-add-more-missing-match-size-checks.patch netfilter-x_tables-add-and-use-xt_check_proc_name.patch xfrm-refuse-to-insert-32-bit-userspace-socket-policies-on-64-bit-systems.patch --- diff --git a/queue-3.18/bluetooth-fix-missing-encryption-refresh-on-security-request.patch b/queue-3.18/bluetooth-fix-missing-encryption-refresh-on-security-request.patch new file mode 100644 index 00000000000..1a81e76eea0 --- /dev/null +++ b/queue-3.18/bluetooth-fix-missing-encryption-refresh-on-security-request.patch @@ -0,0 +1,55 @@ +From 64e759f58f128730b97a3c3a26d283c075ad7c86 Mon Sep 17 00:00:00 2001 +From: Szymon Janc +Date: Mon, 26 Feb 2018 15:41:53 +0100 +Subject: Bluetooth: Fix missing encryption refresh on Security Request + +From: Szymon Janc + +commit 64e759f58f128730b97a3c3a26d283c075ad7c86 upstream. + +If Security Request is received on connection that is already encrypted +with sufficient security master should perform encryption key refresh +procedure instead of just ignoring Slave Security Request +(Core Spec 5.0 Vol 3 Part H 2.4.6). + +> ACL Data RX: Handle 3585 flags 0x02 dlen 6 + SMP: Security Request (0x0b) len 1 + Authentication requirement: Bonding, No MITM, SC, No Keypresses (0x09) +< HCI Command: LE Start Encryption (0x08|0x0019) plen 28 + Handle: 3585 + Random number: 0x0000000000000000 + Encrypted diversifier: 0x0000 + Long term key: 44264272a5c426a9e868f034cf0e69f3 +> HCI Event: Command Status (0x0f) plen 4 + LE Start Encryption (0x08|0x0019) ncmd 1 + Status: Success (0x00) +> HCI Event: Encryption Key Refresh Complete (0x30) plen 3 + Status: Success (0x00) + Handle: 3585 + +Signed-off-by: Szymon Janc +Signed-off-by: Marcel Holtmann +Signed-off-by: Greg Kroah-Hartman + +--- + net/bluetooth/smp.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/net/bluetooth/smp.c ++++ b/net/bluetooth/smp.c +@@ -1178,8 +1178,14 @@ static u8 smp_cmd_security_req(struct l2 + else + sec_level = authreq_to_seclevel(auth); + +- if (smp_sufficient_security(hcon, sec_level)) ++ if (smp_sufficient_security(hcon, sec_level)) { ++ /* If link is already encrypted with sufficient security we ++ * still need refresh encryption as per Core Spec 5.0 Vol 3, ++ * Part H 2.4.6 ++ */ ++ smp_ltk_encrypt(conn, hcon->sec_level); + return 0; ++ } + + if (sec_level > hcon->pending_sec_level) + hcon->pending_sec_level = sec_level; diff --git a/queue-3.18/net-xfrm-use-preempt-safe-this_cpu_read-in-ipcomp_alloc_tfms.patch b/queue-3.18/net-xfrm-use-preempt-safe-this_cpu_read-in-ipcomp_alloc_tfms.patch new file mode 100644 index 00000000000..3962c81aa64 --- /dev/null +++ b/queue-3.18/net-xfrm-use-preempt-safe-this_cpu_read-in-ipcomp_alloc_tfms.patch @@ -0,0 +1,95 @@ +From 0dcd7876029b58770f769cbb7b484e88e4a305e5 Mon Sep 17 00:00:00 2001 +From: Greg Hackmann +Date: Wed, 7 Mar 2018 14:42:53 -0800 +Subject: net: xfrm: use preempt-safe this_cpu_read() in ipcomp_alloc_tfms() + +From: Greg Hackmann + +commit 0dcd7876029b58770f769cbb7b484e88e4a305e5 upstream. + +f7c83bcbfaf5 ("net: xfrm: use __this_cpu_read per-cpu helper") added a +__this_cpu_read() call inside ipcomp_alloc_tfms(). + +At the time, __this_cpu_read() required the caller to either not care +about races or to handle preemption/interrupt issues. 3.15 tightened +the rules around some per-cpu operations, and now __this_cpu_read() +should never be used in a preemptible context. On 3.15 and later, we +need to use this_cpu_read() instead. + +syzkaller reported this leading to the following kernel BUG while +fuzzing sendmsg: + +BUG: using __this_cpu_read() in preemptible [00000000] code: repro/3101 +caller is ipcomp_init_state+0x185/0x990 +CPU: 3 PID: 3101 Comm: repro Not tainted 4.16.0-rc4-00123-g86f84779d8e9 #154 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014 +Call Trace: + dump_stack+0xb9/0x115 + check_preemption_disabled+0x1cb/0x1f0 + ipcomp_init_state+0x185/0x990 + ? __xfrm_init_state+0x876/0xc20 + ? lock_downgrade+0x5e0/0x5e0 + ipcomp4_init_state+0xaa/0x7c0 + __xfrm_init_state+0x3eb/0xc20 + xfrm_init_state+0x19/0x60 + pfkey_add+0x20df/0x36f0 + ? pfkey_broadcast+0x3dd/0x600 + ? pfkey_sock_destruct+0x340/0x340 + ? pfkey_seq_stop+0x80/0x80 + ? __skb_clone+0x236/0x750 + ? kmem_cache_alloc+0x1f6/0x260 + ? pfkey_sock_destruct+0x340/0x340 + ? pfkey_process+0x62a/0x6f0 + pfkey_process+0x62a/0x6f0 + ? pfkey_send_new_mapping+0x11c0/0x11c0 + ? mutex_lock_io_nested+0x1390/0x1390 + pfkey_sendmsg+0x383/0x750 + ? dump_sp+0x430/0x430 + sock_sendmsg+0xc0/0x100 + ___sys_sendmsg+0x6c8/0x8b0 + ? copy_msghdr_from_user+0x3b0/0x3b0 + ? pagevec_lru_move_fn+0x144/0x1f0 + ? find_held_lock+0x32/0x1c0 + ? do_huge_pmd_anonymous_page+0xc43/0x11e0 + ? lock_downgrade+0x5e0/0x5e0 + ? get_kernel_page+0xb0/0xb0 + ? _raw_spin_unlock+0x29/0x40 + ? do_huge_pmd_anonymous_page+0x400/0x11e0 + ? __handle_mm_fault+0x553/0x2460 + ? __fget_light+0x163/0x1f0 + ? __sys_sendmsg+0xc7/0x170 + __sys_sendmsg+0xc7/0x170 + ? SyS_shutdown+0x1a0/0x1a0 + ? __do_page_fault+0x5a0/0xca0 + ? lock_downgrade+0x5e0/0x5e0 + SyS_sendmsg+0x27/0x40 + ? __sys_sendmsg+0x170/0x170 + do_syscall_64+0x19f/0x640 + entry_SYSCALL_64_after_hwframe+0x42/0xb7 +RIP: 0033:0x7f0ee73dfb79 +RSP: 002b:00007ffe14fc15a8 EFLAGS: 00000207 ORIG_RAX: 000000000000002e +RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f0ee73dfb79 +RDX: 0000000000000000 RSI: 00000000208befc8 RDI: 0000000000000004 +RBP: 00007ffe14fc15b0 R08: 00007ffe14fc15c0 R09: 00007ffe14fc15c0 +R10: 0000000000000000 R11: 0000000000000207 R12: 0000000000400440 +R13: 00007ffe14fc16b0 R14: 0000000000000000 R15: 0000000000000000 + +Signed-off-by: Greg Hackmann +Signed-off-by: Steffen Klassert +Signed-off-by: Greg Kroah-Hartman + +--- + net/xfrm/xfrm_ipcomp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/xfrm/xfrm_ipcomp.c ++++ b/net/xfrm/xfrm_ipcomp.c +@@ -283,7 +283,7 @@ static struct crypto_comp * __percpu *ip + struct crypto_comp *tfm; + + /* This can be any valid CPU ID so we don't need locking. */ +- tfm = __this_cpu_read(*pos->tfms); ++ tfm = this_cpu_read(*pos->tfms); + + if (!strcmp(crypto_comp_name(tfm), alg_name)) { + pos->users++; diff --git a/queue-3.18/netfilter-bridge-ebt_among-add-more-missing-match-size-checks.patch b/queue-3.18/netfilter-bridge-ebt_among-add-more-missing-match-size-checks.patch new file mode 100644 index 00000000000..366408aed63 --- /dev/null +++ b/queue-3.18/netfilter-bridge-ebt_among-add-more-missing-match-size-checks.patch @@ -0,0 +1,99 @@ +From c8d70a700a5b486bfa8e5a7d33d805389f6e59f9 Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Fri, 9 Mar 2018 14:27:31 +0100 +Subject: netfilter: bridge: ebt_among: add more missing match size checks + +From: Florian Westphal + +commit c8d70a700a5b486bfa8e5a7d33d805389f6e59f9 upstream. + +ebt_among is special, it has a dynamic match size and is exempt +from the central size checks. + +commit c4585a2823edf ("bridge: ebt_among: add missing match size checks") +added validation for pool size, but missed fact that the macros +ebt_among_wh_src/dst can already return out-of-bound result because +they do not check value of wh_src/dst_ofs (an offset) vs. the size +of the match that userspace gave to us. + +v2: +check that offset has correct alignment. +Paolo Abeni points out that we should also check that src/dst +wormhash arrays do not overlap, and src + length lines up with +start of dst (or vice versa). +v3: compact wormhash_sizes_valid() part + +NB: Fixes tag is intentionally wrong, this bug exists from day +one when match was added for 2.6 kernel. Tag is there so stable +maintainers will notice this one too. + +Tested with same rules from the earlier patch. + +Fixes: c4585a2823edf ("bridge: ebt_among: add missing match size checks") +Reported-by: +Signed-off-by: Florian Westphal +Reviewed-by: Eric Dumazet +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/bridge/netfilter/ebt_among.c | 34 ++++++++++++++++++++++++++++++++++ + 1 file changed, 34 insertions(+) + +--- a/net/bridge/netfilter/ebt_among.c ++++ b/net/bridge/netfilter/ebt_among.c +@@ -177,6 +177,28 @@ static bool poolsize_invalid(const struc + return w && w->poolsize >= (INT_MAX / sizeof(struct ebt_mac_wormhash_tuple)); + } + ++static bool wormhash_offset_invalid(int off, unsigned int len) ++{ ++ if (off == 0) /* not present */ ++ return false; ++ ++ if (off < (int)sizeof(struct ebt_among_info) || ++ off % __alignof__(struct ebt_mac_wormhash)) ++ return true; ++ ++ off += sizeof(struct ebt_mac_wormhash); ++ ++ return off > len; ++} ++ ++static bool wormhash_sizes_valid(const struct ebt_mac_wormhash *wh, int a, int b) ++{ ++ if (a == 0) ++ a = sizeof(struct ebt_among_info); ++ ++ return ebt_mac_wormhash_size(wh) + a == b; ++} ++ + static int ebt_among_mt_check(const struct xt_mtchk_param *par) + { + const struct ebt_among_info *info = par->matchinfo; +@@ -189,6 +211,10 @@ static int ebt_among_mt_check(const stru + if (expected_length > em->match_size) + return -EINVAL; + ++ if (wormhash_offset_invalid(info->wh_dst_ofs, em->match_size) || ++ wormhash_offset_invalid(info->wh_src_ofs, em->match_size)) ++ return -EINVAL; ++ + wh_dst = ebt_among_wh_dst(info); + if (poolsize_invalid(wh_dst)) + return -EINVAL; +@@ -201,6 +227,14 @@ static int ebt_among_mt_check(const stru + if (poolsize_invalid(wh_src)) + return -EINVAL; + ++ if (info->wh_src_ofs < info->wh_dst_ofs) { ++ if (!wormhash_sizes_valid(wh_src, info->wh_src_ofs, info->wh_dst_ofs)) ++ return -EINVAL; ++ } else { ++ if (!wormhash_sizes_valid(wh_dst, info->wh_dst_ofs, info->wh_src_ofs)) ++ return -EINVAL; ++ } ++ + expected_length += ebt_mac_wormhash_size(wh_src); + + if (em->match_size != EBT_ALIGN(expected_length)) { diff --git a/queue-3.18/netfilter-x_tables-add-and-use-xt_check_proc_name.patch b/queue-3.18/netfilter-x_tables-add-and-use-xt_check_proc_name.patch new file mode 100644 index 00000000000..ddec6eda5f9 --- /dev/null +++ b/queue-3.18/netfilter-x_tables-add-and-use-xt_check_proc_name.patch @@ -0,0 +1,108 @@ +From b1d0a5d0cba4597c0394997b2d5fced3e3841b4e Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Sat, 10 Mar 2018 01:15:45 +0100 +Subject: netfilter: x_tables: add and use xt_check_proc_name + +From: Florian Westphal + +commit b1d0a5d0cba4597c0394997b2d5fced3e3841b4e upstream. + +recent and hashlimit both create /proc files, but only check that +name is 0 terminated. + +This can trigger WARN() from procfs when name is "" or "/". +Add helper for this and then use it for both. + +Cc: Eric Dumazet +Reported-by: Eric Dumazet +Reported-by: +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/netfilter/x_tables.h | 2 ++ + net/netfilter/x_tables.c | 30 ++++++++++++++++++++++++++++++ + net/netfilter/xt_hashlimit.c | 5 +++-- + net/netfilter/xt_recent.c | 6 +++--- + 4 files changed, 38 insertions(+), 5 deletions(-) + +--- a/include/linux/netfilter/x_tables.h ++++ b/include/linux/netfilter/x_tables.h +@@ -247,6 +247,8 @@ unsigned int *xt_alloc_entry_offsets(uns + bool xt_find_jump_offset(const unsigned int *offsets, + unsigned int target, unsigned int size); + ++int xt_check_proc_name(const char *name, unsigned int size); ++ + int xt_check_match(struct xt_mtchk_param *, unsigned int size, u_int8_t proto, + bool inv_proto); + int xt_check_target(struct xt_tgchk_param *, unsigned int size, u_int8_t proto, +--- a/net/netfilter/x_tables.c ++++ b/net/netfilter/x_tables.c +@@ -367,6 +367,36 @@ textify_hooks(char *buf, size_t size, un + return buf; + } + ++/** ++ * xt_check_proc_name - check that name is suitable for /proc file creation ++ * ++ * @name: file name candidate ++ * @size: length of buffer ++ * ++ * some x_tables modules wish to create a file in /proc. ++ * This function makes sure that the name is suitable for this ++ * purpose, it checks that name is NUL terminated and isn't a 'special' ++ * name, like "..". ++ * ++ * returns negative number on error or 0 if name is useable. ++ */ ++int xt_check_proc_name(const char *name, unsigned int size) ++{ ++ if (name[0] == '\0') ++ return -EINVAL; ++ ++ if (strnlen(name, size) == size) ++ return -ENAMETOOLONG; ++ ++ if (strcmp(name, ".") == 0 || ++ strcmp(name, "..") == 0 || ++ strchr(name, '/')) ++ return -EINVAL; ++ ++ return 0; ++} ++EXPORT_SYMBOL(xt_check_proc_name); ++ + int xt_check_match(struct xt_mtchk_param *par, + unsigned int size, u_int8_t proto, bool inv_proto) + { +--- a/net/netfilter/xt_hashlimit.c ++++ b/net/netfilter/xt_hashlimit.c +@@ -668,8 +668,9 @@ static int hashlimit_mt_check(const stru + + if (info->cfg.gc_interval == 0 || info->cfg.expire == 0) + return -EINVAL; +- if (info->name[sizeof(info->name)-1] != '\0') +- return -EINVAL; ++ ret = xt_check_proc_name(info->name, sizeof(info->name)); ++ if (ret) ++ return ret; + if (par->family == NFPROTO_IPV4) { + if (info->cfg.srcmask > 32 || info->cfg.dstmask > 32) + return -EINVAL; +--- a/net/netfilter/xt_recent.c ++++ b/net/netfilter/xt_recent.c +@@ -355,9 +355,9 @@ static int recent_mt_check(const struct + info->hit_count, ip_pkt_list_tot); + return -EINVAL; + } +- if (info->name[0] == '\0' || +- strnlen(info->name, XT_RECENT_NAME_LEN) == XT_RECENT_NAME_LEN) +- return -EINVAL; ++ ret = xt_check_proc_name(info->name, sizeof(info->name)); ++ if (ret) ++ return ret; + + mutex_lock(&recent_mutex); + t = recent_table_lookup(recent_net, info->name); diff --git a/queue-3.18/series b/queue-3.18/series index bb7e595e010..14739a3a13c 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -48,3 +48,8 @@ revert-led-core-fix-brightness-setting-when-setting-delay_off-0.patch xhci-fix-ring-leak-in-failure-path-of-xhci_alloc_virt_device.patch kprobes-x86-fix-to-set-rwx-bits-correctly-before-releasing-trampoline.patch xfrm_user-uncoditionally-validate-esn-replay-attribute-struct.patch +net-xfrm-use-preempt-safe-this_cpu_read-in-ipcomp_alloc_tfms.patch +xfrm-refuse-to-insert-32-bit-userspace-socket-policies-on-64-bit-systems.patch +netfilter-bridge-ebt_among-add-more-missing-match-size-checks.patch +netfilter-x_tables-add-and-use-xt_check_proc_name.patch +bluetooth-fix-missing-encryption-refresh-on-security-request.patch diff --git a/queue-3.18/xfrm-refuse-to-insert-32-bit-userspace-socket-policies-on-64-bit-systems.patch b/queue-3.18/xfrm-refuse-to-insert-32-bit-userspace-socket-policies-on-64-bit-systems.patch new file mode 100644 index 00000000000..ec0804ece43 --- /dev/null +++ b/queue-3.18/xfrm-refuse-to-insert-32-bit-userspace-socket-policies-on-64-bit-systems.patch @@ -0,0 +1,38 @@ +From 19d7df69fdb2636856dc8919de72fc1bf8f79598 Mon Sep 17 00:00:00 2001 +From: Steffen Klassert +Date: Thu, 1 Feb 2018 08:49:23 +0100 +Subject: xfrm: Refuse to insert 32 bit userspace socket policies on 64 bit systems + +From: Steffen Klassert + +commit 19d7df69fdb2636856dc8919de72fc1bf8f79598 upstream. + +We don't have a compat layer for xfrm, so userspace and kernel +structures have different sizes in this case. This results in +a broken configuration, so refuse to configure socket policies +when trying to insert from 32 bit userspace as we do it already +with policies inserted via netlink. + +Reported-and-tested-by: syzbot+e1a1577ca8bcb47b769a@syzkaller.appspotmail.com +Signed-off-by: Steffen Klassert +[use is_compat_task() - gregkh] +Signed-off-by: Greg Kroah-Hartman + +--- + net/xfrm/xfrm_state.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/net/xfrm/xfrm_state.c ++++ b/net/xfrm/xfrm_state.c +@@ -1845,6 +1845,11 @@ int xfrm_user_policy(struct sock *sk, in + struct xfrm_mgr *km; + struct xfrm_policy *pol = NULL; + ++#ifdef CONFIG_COMPAT ++ if (is_compat_task()) ++ return -EOPNOTSUPP; ++#endif ++ + if (!optval && !optlen) { + xfrm_sk_policy_insert(sk, XFRM_POLICY_IN, NULL); + xfrm_sk_policy_insert(sk, XFRM_POLICY_OUT, NULL);