From: Greg Kroah-Hartman Date: Sun, 20 May 2018 07:46:34 +0000 (+0200) Subject: 4.14-stable patches X-Git-Tag: v4.9.102~37 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e3e8d2007d3f2dc9e1413dcee88437218df9da27;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches added patches: netfilter-nf_socket-fix-out-of-bounds-access-in-nf_sk_lookup_slow_v-4-6.patch netfilter-nf_tables-can-t-fail-after-linking-rule-into-active-rule-list.patch netfilter-nf_tables-free-set-name-in-error-path.patch tee-shm-fix-use-after-free-via-temporarily-dropped-reference.patch --- diff --git a/queue-4.14/netfilter-nf_socket-fix-out-of-bounds-access-in-nf_sk_lookup_slow_v-4-6.patch b/queue-4.14/netfilter-nf_socket-fix-out-of-bounds-access-in-nf_sk_lookup_slow_v-4-6.patch new file mode 100644 index 00000000000..3ee045631e6 --- /dev/null +++ b/queue-4.14/netfilter-nf_socket-fix-out-of-bounds-access-in-nf_sk_lookup_slow_v-4-6.patch @@ -0,0 +1,80 @@ +From 32c1733f0dd4bd11d6e65512bf4dc337c0452c8e Mon Sep 17 00:00:00 2001 +From: Subash Abhinov Kasiviswanathan +Date: Thu, 22 Mar 2018 21:12:39 -0600 +Subject: netfilter: nf_socket: Fix out of bounds access in nf_sk_lookup_slow_v{4,6} + +From: Subash Abhinov Kasiviswanathan + +commit 32c1733f0dd4bd11d6e65512bf4dc337c0452c8e upstream. + +skb_header_pointer will copy data into a buffer if data is non linear, +otherwise it will return a pointer in the linear section of the data. +nf_sk_lookup_slow_v{4,6} always copies data of size udphdr but later +accesses memory within the size of tcphdr (th->doff) in case of TCP +packets. This causes a crash when running with KASAN with the following +call stack - + +BUG: KASAN: stack-out-of-bounds in xt_socket_lookup_slow_v4+0x524/0x718 +net/netfilter/xt_socket.c:178 +Read of size 2 at addr ffffffe3d417a87c by task syz-executor/28971 +CPU: 2 PID: 28971 Comm: syz-executor Tainted: G B W O 4.9.65+ #1 +Call trace: +[] dump_backtrace+0x0/0x428 arch/arm64/kernel/traps.c:76 +[] show_stack+0x28/0x38 arch/arm64/kernel/traps.c:226 +[] __dump_stack lib/dump_stack.c:15 [inline] +[] dump_stack+0xd4/0x124 lib/dump_stack.c:51 +[] print_address_description+0x68/0x258 mm/kasan/report.c:248 +[] kasan_report_error mm/kasan/report.c:347 [inline] +[] kasan_report.part.2+0x228/0x2f0 mm/kasan/report.c:371 +[] kasan_report+0x5c/0x70 mm/kasan/report.c:372 +[] check_memory_region_inline mm/kasan/kasan.c:308 [inline] +[] __asan_load2+0x84/0x98 mm/kasan/kasan.c:739 +[] __tcp_hdrlen include/linux/tcp.h:35 [inline] +[] xt_socket_lookup_slow_v4+0x524/0x718 net/netfilter/xt_socket.c:178 + +Fix this by copying data into appropriate size headers based on protocol. + +Fixes: a583636a83ea ("inet: refactor inet[6]_lookup functions to take skb") +Signed-off-by: Tejaswi Tanikella +Signed-off-by: Subash Abhinov Kasiviswanathan +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/ipv4/netfilter/nf_socket_ipv4.c | 6 ++++-- + net/ipv6/netfilter/nf_socket_ipv6.c | 6 ++++-- + 2 files changed, 8 insertions(+), 4 deletions(-) + +--- a/net/ipv4/netfilter/nf_socket_ipv4.c ++++ b/net/ipv4/netfilter/nf_socket_ipv4.c +@@ -108,10 +108,12 @@ struct sock *nf_sk_lookup_slow_v4(struct + int doff = 0; + + if (iph->protocol == IPPROTO_UDP || iph->protocol == IPPROTO_TCP) { +- struct udphdr _hdr, *hp; ++ struct tcphdr _hdr; ++ struct udphdr *hp; + + hp = skb_header_pointer(skb, ip_hdrlen(skb), +- sizeof(_hdr), &_hdr); ++ iph->protocol == IPPROTO_UDP ? ++ sizeof(*hp) : sizeof(_hdr), &_hdr); + if (hp == NULL) + return NULL; + +--- a/net/ipv6/netfilter/nf_socket_ipv6.c ++++ b/net/ipv6/netfilter/nf_socket_ipv6.c +@@ -116,9 +116,11 @@ struct sock *nf_sk_lookup_slow_v6(struct + } + + if (tproto == IPPROTO_UDP || tproto == IPPROTO_TCP) { +- struct udphdr _hdr, *hp; ++ struct tcphdr _hdr; ++ struct udphdr *hp; + +- hp = skb_header_pointer(skb, thoff, sizeof(_hdr), &_hdr); ++ hp = skb_header_pointer(skb, thoff, tproto == IPPROTO_UDP ? ++ sizeof(*hp) : sizeof(_hdr), &_hdr); + if (hp == NULL) + return NULL; + diff --git a/queue-4.14/netfilter-nf_tables-can-t-fail-after-linking-rule-into-active-rule-list.patch b/queue-4.14/netfilter-nf_tables-can-t-fail-after-linking-rule-into-active-rule-list.patch new file mode 100644 index 00000000000..9bcd096d9d0 --- /dev/null +++ b/queue-4.14/netfilter-nf_tables-can-t-fail-after-linking-rule-into-active-rule-list.patch @@ -0,0 +1,110 @@ +From 569ccae68b38654f04b6842b034aa33857f605fe Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Tue, 10 Apr 2018 09:30:27 +0200 +Subject: netfilter: nf_tables: can't fail after linking rule into active rule list + +From: Florian Westphal + +commit 569ccae68b38654f04b6842b034aa33857f605fe upstream. + +rules in nftables a free'd using kfree, but protected by rcu, i.e. we +must wait for a grace period to elapse. + +Normal removal patch does this, but nf_tables_newrule() doesn't obey +this rule during error handling. + +It calls nft_trans_rule_add() *after* linking rule, and, if that +fails to allocate memory, it unlinks the rule and then kfree() it -- +this is unsafe. + +Switch order -- first add rule to transaction list, THEN link it +to public list. + +Note: nft_trans_rule_add() uses GFP_KERNEL; it will not fail so this +is not a problem in practice (spotted only during code review). + +Fixes: 0628b123c96d12 ("netfilter: nfnetlink: add batch support and use it from nf_tables") +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/nf_tables_api.c | 59 ++++++++++++++++++++++-------------------- + 1 file changed, 32 insertions(+), 27 deletions(-) + +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -2344,41 +2344,46 @@ static int nf_tables_newrule(struct net + } + + if (nlh->nlmsg_flags & NLM_F_REPLACE) { +- if (nft_is_active_next(net, old_rule)) { +- trans = nft_trans_rule_add(&ctx, NFT_MSG_DELRULE, +- old_rule); +- if (trans == NULL) { +- err = -ENOMEM; +- goto err2; +- } +- nft_deactivate_next(net, old_rule); +- chain->use--; +- list_add_tail_rcu(&rule->list, &old_rule->list); +- } else { ++ if (!nft_is_active_next(net, old_rule)) { + err = -ENOENT; + goto err2; + } +- } else if (nlh->nlmsg_flags & NLM_F_APPEND) +- if (old_rule) +- list_add_rcu(&rule->list, &old_rule->list); +- else +- list_add_tail_rcu(&rule->list, &chain->rules); +- else { +- if (old_rule) +- list_add_tail_rcu(&rule->list, &old_rule->list); +- else +- list_add_rcu(&rule->list, &chain->rules); +- } ++ trans = nft_trans_rule_add(&ctx, NFT_MSG_DELRULE, ++ old_rule); ++ if (trans == NULL) { ++ err = -ENOMEM; ++ goto err2; ++ } ++ nft_deactivate_next(net, old_rule); ++ chain->use--; ++ ++ if (nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule) == NULL) { ++ err = -ENOMEM; ++ goto err2; ++ } + +- if (nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule) == NULL) { +- err = -ENOMEM; +- goto err3; ++ list_add_tail_rcu(&rule->list, &old_rule->list); ++ } else { ++ if (nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule) == NULL) { ++ err = -ENOMEM; ++ goto err2; ++ } ++ ++ if (nlh->nlmsg_flags & NLM_F_APPEND) { ++ if (old_rule) ++ list_add_rcu(&rule->list, &old_rule->list); ++ else ++ list_add_tail_rcu(&rule->list, &chain->rules); ++ } else { ++ if (old_rule) ++ list_add_tail_rcu(&rule->list, &old_rule->list); ++ else ++ list_add_rcu(&rule->list, &chain->rules); ++ } + } + chain->use++; + return 0; + +-err3: +- list_del_rcu(&rule->list); + err2: + nf_tables_rule_destroy(&ctx, rule); + err1: diff --git a/queue-4.14/netfilter-nf_tables-free-set-name-in-error-path.patch b/queue-4.14/netfilter-nf_tables-free-set-name-in-error-path.patch new file mode 100644 index 00000000000..7c0bff9761d --- /dev/null +++ b/queue-4.14/netfilter-nf_tables-free-set-name-in-error-path.patch @@ -0,0 +1,46 @@ +From 2f6adf481527c8ab8033c601f55bfb5b3712b2ac Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Tue, 10 Apr 2018 09:00:24 +0200 +Subject: netfilter: nf_tables: free set name in error path + +From: Florian Westphal + +commit 2f6adf481527c8ab8033c601f55bfb5b3712b2ac upstream. + +set->name must be free'd here in case ops->init fails. + +Fixes: 387454901bd6 ("netfilter: nf_tables: Allow set names of up to 255 chars") +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/nf_tables_api.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -3196,18 +3196,20 @@ static int nf_tables_newset(struct net * + + err = ops->init(set, &desc, nla); + if (err < 0) +- goto err2; ++ goto err3; + + err = nft_trans_set_add(&ctx, NFT_MSG_NEWSET, set); + if (err < 0) +- goto err3; ++ goto err4; + + list_add_tail_rcu(&set->list, &table->sets); + table->use++; + return 0; + +-err3: ++err4: + ops->destroy(set); ++err3: ++ kfree(set->name); + err2: + kvfree(set); + err1: diff --git a/queue-4.14/series b/queue-4.14/series index f9866842208..fb17bcbf6c5 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -14,3 +14,7 @@ kvm-arm-arm64-vgic-its-protect-kvm_read_guest-calls-with-srcu-lock.patch powerpc-don-t-preempt_disable-in-show_cpuinfo.patch vfio-ccw-fix-cleanup-if-cp_prefetch-fails.patch tracing-x86-xen-remove-zero-data-size-trace-events-trace_xen_mmu_flush_tlb-_all.patch +tee-shm-fix-use-after-free-via-temporarily-dropped-reference.patch +netfilter-nf_tables-free-set-name-in-error-path.patch +netfilter-nf_tables-can-t-fail-after-linking-rule-into-active-rule-list.patch +netfilter-nf_socket-fix-out-of-bounds-access-in-nf_sk_lookup_slow_v-4-6.patch diff --git a/queue-4.14/tee-shm-fix-use-after-free-via-temporarily-dropped-reference.patch b/queue-4.14/tee-shm-fix-use-after-free-via-temporarily-dropped-reference.patch new file mode 100644 index 00000000000..253e1bdb905 --- /dev/null +++ b/queue-4.14/tee-shm-fix-use-after-free-via-temporarily-dropped-reference.patch @@ -0,0 +1,39 @@ +From bb765d1c331f62b59049d35607ed2e365802bef9 Mon Sep 17 00:00:00 2001 +From: Jann Horn +Date: Wed, 4 Apr 2018 21:03:21 +0200 +Subject: tee: shm: fix use-after-free via temporarily dropped reference + +From: Jann Horn + +commit bb765d1c331f62b59049d35607ed2e365802bef9 upstream. + +Bump the file's refcount before moving the reference into the fd table, +not afterwards. The old code could drop the file's refcount to zero for a +short moment before calling get_file() via get_dma_buf(). + +This code can only be triggered on ARM systems that use Linaro's OP-TEE. + +Fixes: 967c9cca2cc5 ("tee: generic TEE subsystem") +Signed-off-by: Jann Horn +Signed-off-by: Jens Wiklander +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tee/tee_shm.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/tee/tee_shm.c ++++ b/drivers/tee/tee_shm.c +@@ -203,9 +203,10 @@ int tee_shm_get_fd(struct tee_shm *shm) + if ((shm->flags & req_flags) != req_flags) + return -EINVAL; + ++ get_dma_buf(shm->dmabuf); + fd = dma_buf_fd(shm->dmabuf, O_CLOEXEC); +- if (fd >= 0) +- get_dma_buf(shm->dmabuf); ++ if (fd < 0) ++ dma_buf_put(shm->dmabuf); + return fd; + } +