From: Greg Kroah-Hartman Date: Tue, 13 Mar 2018 11:15:18 +0000 (+0100) Subject: 4.15-stable patches X-Git-Tag: v4.14.27~16 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d3c2d83639d2897a4763ecfdc202353f90ec33ce;p=thirdparty%2Fkernel%2Fstable-queue.git 4.15-stable patches added patches: netfilter-add-back-stackpointer-size-checks.patch netfilter-bridge-ebt_among-add-missing-match-size-checks.patch netfilter-ebtables-config_compat-don-t-trust-userland-offsets.patch netfilter-idletimer-be-syzkaller-friendly.patch netfilter-ipt_clusterip-fix-a-race-condition-of-proc-file-creation.patch netfilter-ipv6-fix-use-after-free-write-in-nf_nat_ipv6_manip_pkt.patch netfilter-nat-cope-with-negative-port-range.patch netfilter-use-skb_to_full_sk-in-ip6_route_me_harder.patch netfilter-x_tables-fix-missing-timer-initialization-in-xt_led.patch netfilter-xt_hashlimit-fix-lock-imbalance.patch --- diff --git a/queue-4.15/netfilter-add-back-stackpointer-size-checks.patch b/queue-4.15/netfilter-add-back-stackpointer-size-checks.patch new file mode 100644 index 00000000000..69162a211e0 --- /dev/null +++ b/queue-4.15/netfilter-add-back-stackpointer-size-checks.patch @@ -0,0 +1,81 @@ +From 57ebd808a97d7c5b1e1afb937c2db22beba3c1f8 Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Wed, 7 Feb 2018 13:46:25 +0100 +Subject: netfilter: add back stackpointer size checks + +From: Florian Westphal + +commit 57ebd808a97d7c5b1e1afb937c2db22beba3c1f8 upstream. + +The rationale for removing the check is only correct for rulesets +generated by ip(6)tables. + +In iptables, a jump can only occur to a user-defined chain, i.e. +because we size the stack based on number of user-defined chains we +cannot exceed stack size. + +However, the underlying binary format has no such restriction, +and the validation step only ensures that the jump target is a +valid rule start point. + +IOW, its possible to build a rule blob that has no user-defined +chains but does contain a jump. + +If this happens, no jump stack gets allocated and crash occurs +because no jumpstack was allocated. + +Fixes: 7814b6ec6d0d6 ("netfilter: xtables: don't save/restore jumpstack offset") +Reported-by: syzbot+e783f671527912cd9403@syzkaller.appspotmail.com +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/ipv4/netfilter/arp_tables.c | 4 ++++ + net/ipv4/netfilter/ip_tables.c | 7 ++++++- + net/ipv6/netfilter/ip6_tables.c | 4 ++++ + 3 files changed, 14 insertions(+), 1 deletion(-) + +--- a/net/ipv4/netfilter/arp_tables.c ++++ b/net/ipv4/netfilter/arp_tables.c +@@ -257,6 +257,10 @@ unsigned int arpt_do_table(struct sk_buf + } + if (table_base + v + != arpt_next_entry(e)) { ++ if (unlikely(stackidx >= private->stacksize)) { ++ verdict = NF_DROP; ++ break; ++ } + jumpstack[stackidx++] = e; + } + +--- a/net/ipv4/netfilter/ip_tables.c ++++ b/net/ipv4/netfilter/ip_tables.c +@@ -335,8 +335,13 @@ ipt_do_table(struct sk_buff *skb, + continue; + } + if (table_base + v != ipt_next_entry(e) && +- !(e->ip.flags & IPT_F_GOTO)) ++ !(e->ip.flags & IPT_F_GOTO)) { ++ if (unlikely(stackidx >= private->stacksize)) { ++ verdict = NF_DROP; ++ break; ++ } + jumpstack[stackidx++] = e; ++ } + + e = get_entry(table_base, v); + continue; +--- a/net/ipv6/netfilter/ip6_tables.c ++++ b/net/ipv6/netfilter/ip6_tables.c +@@ -357,6 +357,10 @@ ip6t_do_table(struct sk_buff *skb, + } + if (table_base + v != ip6t_next_entry(e) && + !(e->ipv6.flags & IP6T_F_GOTO)) { ++ if (unlikely(stackidx >= private->stacksize)) { ++ verdict = NF_DROP; ++ break; ++ } + jumpstack[stackidx++] = e; + } + diff --git a/queue-4.15/netfilter-bridge-ebt_among-add-missing-match-size-checks.patch b/queue-4.15/netfilter-bridge-ebt_among-add-missing-match-size-checks.patch new file mode 100644 index 00000000000..0895207cf74 --- /dev/null +++ b/queue-4.15/netfilter-bridge-ebt_among-add-missing-match-size-checks.patch @@ -0,0 +1,73 @@ +From c4585a2823edf4d1326da44d1524ecbfda26bb37 Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Mon, 19 Feb 2018 03:01:45 +0100 +Subject: netfilter: bridge: ebt_among: add missing match size checks + +From: Florian Westphal + +commit c4585a2823edf4d1326da44d1524ecbfda26bb37 upstream. + +ebt_among is special, it has a dynamic match size and is exempt +from the central size checks. + +Therefore it must check that the size of the match structure +provided from userspace is sane by making sure em->match_size +is at least the minimum size of the expected structure. + +The module has such a check, but its only done after accessing +a structure that might be out of bounds. + +tested with: ebtables -A INPUT ... \ +--among-dst fe:fe:fe:fe:fe:fe +--among-dst fe:fe:fe:fe:fe:fe --among-src fe:fe:fe:fe:ff:f,fe:fe:fe:fe:fe:fb,fe:fe:fe:fe:fc:fd,fe:fe:fe:fe:fe:fd,fe:fe:fe:fe:fe:fe +--among-src fe:fe:fe:fe:ff:f,fe:fe:fe:fe:fe:fa,fe:fe:fe:fe:fe:fd,fe:fe:fe:fe:fe:fe,fe:fe:fe:fe:fe:fe + +Reported-by: +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/bridge/netfilter/ebt_among.c | 21 +++++++++++++++++++-- + 1 file changed, 19 insertions(+), 2 deletions(-) + +--- a/net/bridge/netfilter/ebt_among.c ++++ b/net/bridge/netfilter/ebt_among.c +@@ -172,18 +172,35 @@ ebt_among_mt(const struct sk_buff *skb, + return true; + } + ++static bool poolsize_invalid(const struct ebt_mac_wormhash *w) ++{ ++ return w && w->poolsize >= (INT_MAX / sizeof(struct ebt_mac_wormhash_tuple)); ++} ++ + static int ebt_among_mt_check(const struct xt_mtchk_param *par) + { + const struct ebt_among_info *info = par->matchinfo; + const struct ebt_entry_match *em = + container_of(par->matchinfo, const struct ebt_entry_match, data); +- int expected_length = sizeof(struct ebt_among_info); ++ unsigned int expected_length = sizeof(struct ebt_among_info); + const struct ebt_mac_wormhash *wh_dst, *wh_src; + int err; + ++ if (expected_length > em->match_size) ++ return -EINVAL; ++ + wh_dst = ebt_among_wh_dst(info); +- wh_src = ebt_among_wh_src(info); ++ if (poolsize_invalid(wh_dst)) ++ return -EINVAL; ++ + expected_length += ebt_mac_wormhash_size(wh_dst); ++ if (expected_length > em->match_size) ++ return -EINVAL; ++ ++ wh_src = ebt_among_wh_src(info); ++ if (poolsize_invalid(wh_src)) ++ return -EINVAL; ++ + expected_length += ebt_mac_wormhash_size(wh_src); + + if (em->match_size != EBT_ALIGN(expected_length)) { diff --git a/queue-4.15/netfilter-ebtables-config_compat-don-t-trust-userland-offsets.patch b/queue-4.15/netfilter-ebtables-config_compat-don-t-trust-userland-offsets.patch new file mode 100644 index 00000000000..f12df177468 --- /dev/null +++ b/queue-4.15/netfilter-ebtables-config_compat-don-t-trust-userland-offsets.patch @@ -0,0 +1,58 @@ +From b71812168571fa55e44cdd0254471331b9c4c4c6 Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Mon, 19 Feb 2018 01:24:15 +0100 +Subject: netfilter: ebtables: CONFIG_COMPAT: don't trust userland offsets + +From: Florian Westphal + +commit b71812168571fa55e44cdd0254471331b9c4c4c6 upstream. + +We need to make sure the offsets are not out of range of the +total size. +Also check that they are in ascending order. + +The WARN_ON triggered by syzkaller (it sets panic_on_warn) is +changed to also bail out, no point in continuing parsing. + +Briefly tested with simple ruleset of +-A INPUT --limit 1/s' --log +plus jump to custom chains using 32bit ebtables binary. + +Reported-by: +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/bridge/netfilter/ebtables.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +--- a/net/bridge/netfilter/ebtables.c ++++ b/net/bridge/netfilter/ebtables.c +@@ -2053,7 +2053,9 @@ static int ebt_size_mwt(struct compat_eb + if (match_kern) + match_kern->match_size = ret; + +- WARN_ON(type == EBT_COMPAT_TARGET && size_left); ++ if (WARN_ON(type == EBT_COMPAT_TARGET && size_left)) ++ return -EINVAL; ++ + match32 = (struct compat_ebt_entry_mwt *) buf; + } + +@@ -2109,6 +2111,15 @@ static int size_entry_mwt(struct ebt_ent + * + * offsets are relative to beginning of struct ebt_entry (i.e., 0). + */ ++ for (i = 0; i < 4 ; ++i) { ++ if (offsets[i] >= *total) ++ return -EINVAL; ++ if (i == 0) ++ continue; ++ if (offsets[i-1] > offsets[i]) ++ return -EINVAL; ++ } ++ + for (i = 0, j = 1 ; j < 4 ; j++, i++) { + struct compat_ebt_entry_mwt *match32; + unsigned int size; diff --git a/queue-4.15/netfilter-idletimer-be-syzkaller-friendly.patch b/queue-4.15/netfilter-idletimer-be-syzkaller-friendly.patch new file mode 100644 index 00000000000..de4f7f8b67f --- /dev/null +++ b/queue-4.15/netfilter-idletimer-be-syzkaller-friendly.patch @@ -0,0 +1,125 @@ +From cfc2c740533368b96e2be5e0a4e8c3cace7d9814 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Fri, 16 Feb 2018 19:36:28 -0800 +Subject: netfilter: IDLETIMER: be syzkaller friendly + +From: Eric Dumazet + +commit cfc2c740533368b96e2be5e0a4e8c3cace7d9814 upstream. + +We had one report from syzkaller [1] + +First issue is that INIT_WORK() should be done before mod_timer() +or we risk timer being fired too soon, even with a 1 second timer. + +Second issue is that we need to reject too big info->timeout +to avoid overflows in msecs_to_jiffies(info->timeout * 1000), or +risk looping, if result after overflow is 0. + +[1] +WARNING: CPU: 1 PID: 5129 at kernel/workqueue.c:1444 __queue_work+0xdf4/0x1230 kernel/workqueue.c:1444 +Kernel panic - not syncing: panic_on_warn set ... + +CPU: 1 PID: 5129 Comm: syzkaller159866 Not tainted 4.16.0-rc1+ #230 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +Call Trace: + + __dump_stack lib/dump_stack.c:17 [inline] + dump_stack+0x194/0x257 lib/dump_stack.c:53 + panic+0x1e4/0x41c kernel/panic.c:183 + __warn+0x1dc/0x200 kernel/panic.c:547 + report_bug+0x211/0x2d0 lib/bug.c:184 + 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+0x22/0x40 arch/x86/entry/entry_64.S:988 +RIP: 0010:__queue_work+0xdf4/0x1230 kernel/workqueue.c:1444 +RSP: 0018:ffff8801db507538 EFLAGS: 00010006 +RAX: ffff8801aeb46080 RBX: ffff8801db530200 RCX: ffffffff81481404 +RDX: 0000000000000100 RSI: ffffffff86b42640 RDI: 0000000000000082 +RBP: ffff8801db507758 R08: 1ffff1003b6a0de5 R09: 000000000000000c +R10: ffff8801db5073f0 R11: 0000000000000020 R12: 1ffff1003b6a0eb6 +R13: ffff8801b1067ae0 R14: 00000000000001f8 R15: dffffc0000000000 + queue_work_on+0x16a/0x1c0 kernel/workqueue.c:1488 + queue_work include/linux/workqueue.h:488 [inline] + schedule_work include/linux/workqueue.h:546 [inline] + idletimer_tg_expired+0x44/0x60 net/netfilter/xt_IDLETIMER.c:116 + call_timer_fn+0x228/0x820 kernel/time/timer.c:1326 + expire_timers kernel/time/timer.c:1363 [inline] + __run_timers+0x7ee/0xb70 kernel/time/timer.c:1666 + run_timer_softirq+0x4c/0x70 kernel/time/timer.c:1692 + __do_softirq+0x2d7/0xb85 kernel/softirq.c:285 + invoke_softirq kernel/softirq.c:365 [inline] + irq_exit+0x1cc/0x200 kernel/softirq.c:405 + exiting_irq arch/x86/include/asm/apic.h:541 [inline] + smp_apic_timer_interrupt+0x16b/0x700 arch/x86/kernel/apic/apic.c:1052 + apic_timer_interrupt+0xa9/0xb0 arch/x86/entry/entry_64.S:829 + +RIP: 0010:arch_local_irq_restore arch/x86/include/asm/paravirt.h:777 [inline] +RIP: 0010:__raw_spin_unlock_irqrestore include/linux/spinlock_api_smp.h:160 [inline] +RIP: 0010:_raw_spin_unlock_irqrestore+0x5e/0xba kernel/locking/spinlock.c:184 +RSP: 0018:ffff8801c20173c8 EFLAGS: 00000282 ORIG_RAX: ffffffffffffff12 +RAX: dffffc0000000000 RBX: 0000000000000282 RCX: 0000000000000006 +RDX: 1ffffffff0d592cd RSI: 1ffff10035d68d23 RDI: 0000000000000282 +RBP: ffff8801c20173d8 R08: 1ffff10038402e47 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff8820e5c8 +R13: ffff8801b1067ad8 R14: ffff8801aea7c268 R15: ffff8801aea7c278 + __debug_object_init+0x235/0x1040 lib/debugobjects.c:378 + debug_object_init+0x17/0x20 lib/debugobjects.c:391 + __init_work+0x2b/0x60 kernel/workqueue.c:506 + idletimer_tg_create net/netfilter/xt_IDLETIMER.c:152 [inline] + idletimer_tg_checkentry+0x691/0xb00 net/netfilter/xt_IDLETIMER.c:213 + xt_check_target+0x22c/0x7d0 net/netfilter/x_tables.c:850 + check_target net/ipv6/netfilter/ip6_tables.c:533 [inline] + find_check_entry.isra.7+0x935/0xcf0 net/ipv6/netfilter/ip6_tables.c:575 + translate_table+0xf52/0x1690 net/ipv6/netfilter/ip6_tables.c:744 + do_replace net/ipv6/netfilter/ip6_tables.c:1160 [inline] + do_ip6t_set_ctl+0x370/0x5f0 net/ipv6/netfilter/ip6_tables.c:1686 + nf_sockopt net/netfilter/nf_sockopt.c:106 [inline] + nf_setsockopt+0x67/0xc0 net/netfilter/nf_sockopt.c:115 + ipv6_setsockopt+0x10b/0x130 net/ipv6/ipv6_sockglue.c:927 + udpv6_setsockopt+0x45/0x80 net/ipv6/udp.c:1422 + sock_common_setsockopt+0x95/0xd0 net/core/sock.c:2976 + SYSC_setsockopt net/socket.c:1850 [inline] + SyS_setsockopt+0x189/0x360 net/socket.c:1829 + do_syscall_64+0x282/0x940 arch/x86/entry/common.c:287 + +Fixes: 0902b469bd25 ("netfilter: xtables: idletimer target implementation") +Signed-off-by: Eric Dumazet +Reported-by: syzkaller +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/xt_IDLETIMER.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/net/netfilter/xt_IDLETIMER.c ++++ b/net/netfilter/xt_IDLETIMER.c +@@ -146,11 +146,11 @@ static int idletimer_tg_create(struct id + timer_setup(&info->timer->timer, idletimer_tg_expired, 0); + info->timer->refcnt = 1; + ++ INIT_WORK(&info->timer->work, idletimer_tg_work); ++ + mod_timer(&info->timer->timer, + msecs_to_jiffies(info->timeout * 1000) + jiffies); + +- INIT_WORK(&info->timer->work, idletimer_tg_work); +- + return 0; + + out_free_attr: +@@ -191,7 +191,10 @@ static int idletimer_tg_checkentry(const + pr_debug("timeout value is zero\n"); + return -EINVAL; + } +- ++ if (info->timeout >= INT_MAX / 1000) { ++ pr_debug("timeout value is too big\n"); ++ return -EINVAL; ++ } + if (info->label[0] == '\0' || + strnlen(info->label, + MAX_IDLETIMER_LABEL_SIZE) == MAX_IDLETIMER_LABEL_SIZE) { diff --git a/queue-4.15/netfilter-ipt_clusterip-fix-a-race-condition-of-proc-file-creation.patch b/queue-4.15/netfilter-ipt_clusterip-fix-a-race-condition-of-proc-file-creation.patch new file mode 100644 index 00000000000..08d845a5f48 --- /dev/null +++ b/queue-4.15/netfilter-ipt_clusterip-fix-a-race-condition-of-proc-file-creation.patch @@ -0,0 +1,64 @@ +From b3e456fce9f51d6276e576d00271e2813c1b8b67 Mon Sep 17 00:00:00 2001 +From: Cong Wang +Date: Wed, 7 Feb 2018 21:59:17 -0800 +Subject: netfilter: ipt_CLUSTERIP: fix a race condition of proc file creation + +From: Cong Wang + +commit b3e456fce9f51d6276e576d00271e2813c1b8b67 upstream. + +There is a race condition between clusterip_config_entry_put() +and clusterip_config_init(), after we release the spinlock in +clusterip_config_entry_put(), a new proc file with a same IP could +be created immediately since it is already removed from the configs +list, therefore it triggers this warning: + +------------[ cut here ]------------ +proc_dir_entry 'ipt_CLUSTERIP/172.20.0.170' already registered +WARNING: CPU: 1 PID: 4152 at fs/proc/generic.c:330 proc_register+0x2a4/0x370 fs/proc/generic.c:329 +Kernel panic - not syncing: panic_on_warn set ... + +As a quick fix, just move the proc_remove() inside the spinlock. + +Reported-by: +Fixes: 6c5d5cfbe3c5 ("netfilter: ipt_CLUSTERIP: check duplicate config when initializing") +Tested-by: Paolo Abeni +Cc: Xin Long +Cc: Pablo Neira Ayuso +Signed-off-by: Cong Wang +Reviewed-by: Xin Long +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/ipv4/netfilter/ipt_CLUSTERIP.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c ++++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c +@@ -107,12 +107,6 @@ clusterip_config_entry_put(struct net *n + + local_bh_disable(); + if (refcount_dec_and_lock(&c->entries, &cn->lock)) { +- list_del_rcu(&c->list); +- spin_unlock(&cn->lock); +- local_bh_enable(); +- +- unregister_netdevice_notifier(&c->notifier); +- + /* In case anyone still accesses the file, the open/close + * functions are also incrementing the refcount on their own, + * so it's safe to remove the entry even if it's in use. */ +@@ -120,6 +114,12 @@ clusterip_config_entry_put(struct net *n + if (cn->procdir) + proc_remove(c->pde); + #endif ++ list_del_rcu(&c->list); ++ spin_unlock(&cn->lock); ++ local_bh_enable(); ++ ++ unregister_netdevice_notifier(&c->notifier); ++ + return; + } + local_bh_enable(); diff --git a/queue-4.15/netfilter-ipv6-fix-use-after-free-write-in-nf_nat_ipv6_manip_pkt.patch b/queue-4.15/netfilter-ipv6-fix-use-after-free-write-in-nf_nat_ipv6_manip_pkt.patch new file mode 100644 index 00000000000..b31dd54381c --- /dev/null +++ b/queue-4.15/netfilter-ipv6-fix-use-after-free-write-in-nf_nat_ipv6_manip_pkt.patch @@ -0,0 +1,35 @@ +From b078556aecd791b0e5cb3a59f4c3a14273b52121 Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Mon, 19 Feb 2018 08:10:17 +0100 +Subject: netfilter: ipv6: fix use-after-free Write in nf_nat_ipv6_manip_pkt + +From: Florian Westphal + +commit b078556aecd791b0e5cb3a59f4c3a14273b52121 upstream. + +l4proto->manip_pkt() can cause reallocation of skb head so pointer +to the ipv6 header must be reloaded. + +Reported-and-tested-by: +Fixes: 58a317f1061c89 ("netfilter: ipv6: add IPv6 NAT support") +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/ipv6/netfilter/nf_nat_l3proto_ipv6.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c ++++ b/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c +@@ -99,6 +99,10 @@ static bool nf_nat_ipv6_manip_pkt(struct + !l4proto->manip_pkt(skb, &nf_nat_l3proto_ipv6, iphdroff, hdroff, + target, maniptype)) + return false; ++ ++ /* must reload, offset might have changed */ ++ ipv6h = (void *)skb->data + iphdroff; ++ + manip_addr: + if (maniptype == NF_NAT_MANIP_SRC) + ipv6h->saddr = target->src.u3.in6; diff --git a/queue-4.15/netfilter-nat-cope-with-negative-port-range.patch b/queue-4.15/netfilter-nat-cope-with-negative-port-range.patch new file mode 100644 index 00000000000..7389b3b21bd --- /dev/null +++ b/queue-4.15/netfilter-nat-cope-with-negative-port-range.patch @@ -0,0 +1,116 @@ +From db57ccf0f2f4624b4c4758379f8165277504fbd7 Mon Sep 17 00:00:00 2001 +From: Paolo Abeni +Date: Wed, 14 Feb 2018 17:21:19 +0100 +Subject: netfilter: nat: cope with negative port range + +From: Paolo Abeni + +commit db57ccf0f2f4624b4c4758379f8165277504fbd7 upstream. + +syzbot reported a division by 0 bug in the netfilter nat code: + +divide error: 0000 [#1] SMP KASAN +Dumping ftrace buffer: + (ftrace buffer empty) +Modules linked in: +CPU: 1 PID: 4168 Comm: syzkaller034710 Not tainted 4.16.0-rc1+ #309 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS +Google 01/01/2011 +RIP: 0010:nf_nat_l4proto_unique_tuple+0x291/0x530 +net/netfilter/nf_nat_proto_common.c:88 +RSP: 0018:ffff8801b2466778 EFLAGS: 00010246 +RAX: 000000000000f153 RBX: ffff8801b2466dd8 RCX: ffff8801b2466c7c +RDX: 0000000000000000 RSI: ffff8801b2466c58 RDI: ffff8801db5293ac +RBP: ffff8801b24667d8 R08: ffff8801b8ba6dc0 R09: ffffffff88af5900 +R10: ffff8801b24666f0 R11: 0000000000000000 R12: 000000002990f153 +R13: 0000000000000001 R14: 0000000000000000 R15: ffff8801b2466c7c +FS: 00000000017e3880(0000) GS:ffff8801db500000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00000000208fdfe4 CR3: 00000001b5340002 CR4: 00000000001606e0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +Call Trace: + dccp_unique_tuple+0x40/0x50 net/netfilter/nf_nat_proto_dccp.c:30 + get_unique_tuple+0xc28/0x1c10 net/netfilter/nf_nat_core.c:362 + nf_nat_setup_info+0x1c2/0xe00 net/netfilter/nf_nat_core.c:406 + nf_nat_redirect_ipv6+0x306/0x730 net/netfilter/nf_nat_redirect.c:124 + redirect_tg6+0x7f/0xb0 net/netfilter/xt_REDIRECT.c:34 + ip6t_do_table+0xc2a/0x1a30 net/ipv6/netfilter/ip6_tables.c:365 + ip6table_nat_do_chain+0x65/0x80 net/ipv6/netfilter/ip6table_nat.c:41 + nf_nat_ipv6_fn+0x594/0xa80 net/ipv6/netfilter/nf_nat_l3proto_ipv6.c:302 + nf_nat_ipv6_local_fn+0x33/0x5d0 +net/ipv6/netfilter/nf_nat_l3proto_ipv6.c:407 + ip6table_nat_local_fn+0x2c/0x40 net/ipv6/netfilter/ip6table_nat.c:69 + nf_hook_entry_hookfn include/linux/netfilter.h:120 [inline] + nf_hook_slow+0xba/0x1a0 net/netfilter/core.c:483 + nf_hook include/linux/netfilter.h:243 [inline] + NF_HOOK include/linux/netfilter.h:286 [inline] + ip6_xmit+0x10ec/0x2260 net/ipv6/ip6_output.c:277 + inet6_csk_xmit+0x2fc/0x580 net/ipv6/inet6_connection_sock.c:139 + dccp_transmit_skb+0x9ac/0x10f0 net/dccp/output.c:142 + dccp_connect+0x369/0x670 net/dccp/output.c:564 + dccp_v6_connect+0xe17/0x1bf0 net/dccp/ipv6.c:946 + __inet_stream_connect+0x2d4/0xf00 net/ipv4/af_inet.c:620 + inet_stream_connect+0x58/0xa0 net/ipv4/af_inet.c:684 + SYSC_connect+0x213/0x4a0 net/socket.c:1639 + SyS_connect+0x24/0x30 net/socket.c:1620 + do_syscall_64+0x282/0x940 arch/x86/entry/common.c:287 + entry_SYSCALL_64_after_hwframe+0x26/0x9b +RIP: 0033:0x441c69 +RSP: 002b:00007ffe50cc0be8 EFLAGS: 00000217 ORIG_RAX: 000000000000002a +RAX: ffffffffffffffda RBX: ffffffffffffffff RCX: 0000000000441c69 +RDX: 000000000000001c RSI: 00000000208fdfe4 RDI: 0000000000000003 +RBP: 00000000006cc018 R08: 0000000000000000 R09: 0000000000000000 +R10: 0000000000000538 R11: 0000000000000217 R12: 0000000000403590 +R13: 0000000000403620 R14: 0000000000000000 R15: 0000000000000000 +Code: 48 89 f0 83 e0 07 83 c0 01 38 d0 7c 08 84 d2 0f 85 46 02 00 00 48 8b +45 c8 44 0f b7 20 e8 88 97 04 fd 31 d2 41 0f b7 c4 4c 89 f9 <41> f7 f6 48 +c1 e9 03 48 b8 00 00 00 00 00 fc ff df 0f b6 0c 01 +RIP: nf_nat_l4proto_unique_tuple+0x291/0x530 +net/netfilter/nf_nat_proto_common.c:88 RSP: ffff8801b2466778 + +The problem is that currently we don't have any check on the +configured port range. A port range == -1 triggers the bug, while +other negative values may require a very long time to complete the +following loop. + +This commit addresses the issue swapping the two ends on negative +ranges. The check is performed in nf_nat_l4proto_unique_tuple() since +the nft nat loads the port values from nft registers at runtime. + +v1 -> v2: use the correct 'Fixes' tag +v2 -> v3: update commit message, drop unneeded READ_ONCE() + +Fixes: 5b1158e909ec ("[NETFILTER]: Add NAT support for nf_conntrack") +Reported-by: syzbot+8012e198bd037f4871e5@syzkaller.appspotmail.com +Signed-off-by: Paolo Abeni +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/nf_nat_proto_common.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/net/netfilter/nf_nat_proto_common.c ++++ b/net/netfilter/nf_nat_proto_common.c +@@ -41,7 +41,7 @@ void nf_nat_l4proto_unique_tuple(const s + const struct nf_conn *ct, + u16 *rover) + { +- unsigned int range_size, min, i; ++ unsigned int range_size, min, max, i; + __be16 *portptr; + u_int16_t off; + +@@ -71,7 +71,10 @@ void nf_nat_l4proto_unique_tuple(const s + } + } else { + min = ntohs(range->min_proto.all); +- range_size = ntohs(range->max_proto.all) - min + 1; ++ max = ntohs(range->max_proto.all); ++ if (unlikely(max < min)) ++ swap(max, min); ++ range_size = max - min + 1; + } + + if (range->flags & NF_NAT_RANGE_PROTO_RANDOM) { diff --git a/queue-4.15/netfilter-use-skb_to_full_sk-in-ip6_route_me_harder.patch b/queue-4.15/netfilter-use-skb_to_full_sk-in-ip6_route_me_harder.patch new file mode 100644 index 00000000000..9136a50895d --- /dev/null +++ b/queue-4.15/netfilter-use-skb_to_full_sk-in-ip6_route_me_harder.patch @@ -0,0 +1,60 @@ +From 7d98386d55a5afaa65de77e1e9197edeb8a42079 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Sun, 25 Feb 2018 11:49:07 -0800 +Subject: netfilter: use skb_to_full_sk in ip6_route_me_harder +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Eric Dumazet + +commit 7d98386d55a5afaa65de77e1e9197edeb8a42079 upstream. + +For some reason, Florian forgot to apply to ip6_route_me_harder +the fix that went in commit 29e09229d9f2 ("netfilter: use +skb_to_full_sk in ip_route_me_harder") + +Fixes: ca6fb0651883 ("tcp: attach SYNACK messages to request sockets instead of listener")  +Signed-off-by: Eric Dumazet +Reported-by: syzbot +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/ipv6/netfilter.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/net/ipv6/netfilter.c ++++ b/net/ipv6/netfilter.c +@@ -21,18 +21,19 @@ + int ip6_route_me_harder(struct net *net, struct sk_buff *skb) + { + const struct ipv6hdr *iph = ipv6_hdr(skb); ++ struct sock *sk = sk_to_full_sk(skb->sk); + unsigned int hh_len; + struct dst_entry *dst; + struct flowi6 fl6 = { +- .flowi6_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0, ++ .flowi6_oif = sk ? sk->sk_bound_dev_if : 0, + .flowi6_mark = skb->mark, +- .flowi6_uid = sock_net_uid(net, skb->sk), ++ .flowi6_uid = sock_net_uid(net, sk), + .daddr = iph->daddr, + .saddr = iph->saddr, + }; + int err; + +- dst = ip6_route_output(net, skb->sk, &fl6); ++ dst = ip6_route_output(net, sk, &fl6); + err = dst->error; + if (err) { + IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); +@@ -50,7 +51,7 @@ int ip6_route_me_harder(struct net *net, + if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) && + xfrm_decode_session(skb, flowi6_to_flowi(&fl6), AF_INET6) == 0) { + skb_dst_set(skb, NULL); +- dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), skb->sk, 0); ++ dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), sk, 0); + if (IS_ERR(dst)) + return PTR_ERR(dst); + skb_dst_set(skb, dst); diff --git a/queue-4.15/netfilter-x_tables-fix-missing-timer-initialization-in-xt_led.patch b/queue-4.15/netfilter-x_tables-fix-missing-timer-initialization-in-xt_led.patch new file mode 100644 index 00000000000..71b8323c8ce --- /dev/null +++ b/queue-4.15/netfilter-x_tables-fix-missing-timer-initialization-in-xt_led.patch @@ -0,0 +1,100 @@ +From 10414014bc085aac9f787a5890b33b5605fbcfc4 Mon Sep 17 00:00:00 2001 +From: Paolo Abeni +Date: Mon, 12 Feb 2018 18:49:39 +0100 +Subject: netfilter: x_tables: fix missing timer initialization in xt_LED + +From: Paolo Abeni + +commit 10414014bc085aac9f787a5890b33b5605fbcfc4 upstream. + +syzbot reported that xt_LED may try to use the ledinternal->timer +without previously initializing it: + +------------[ cut here ]------------ +kernel BUG at kernel/time/timer.c:958! +invalid opcode: 0000 [#1] SMP KASAN +Dumping ftrace buffer: + (ftrace buffer empty) +Modules linked in: +CPU: 1 PID: 1826 Comm: kworker/1:2 Not tainted 4.15.0+ #306 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS +Google 01/01/2011 +Workqueue: ipv6_addrconf addrconf_dad_work +RIP: 0010:__mod_timer kernel/time/timer.c:958 [inline] +RIP: 0010:mod_timer+0x7d6/0x13c0 kernel/time/timer.c:1102 +RSP: 0018:ffff8801d24fe9f8 EFLAGS: 00010293 +RAX: ffff8801d25246c0 RBX: ffff8801aec6cb50 RCX: ffffffff816052c6 +RDX: 0000000000000000 RSI: 00000000fffbd14b RDI: ffff8801aec6cb68 +RBP: ffff8801d24fec98 R08: 0000000000000000 R09: 1ffff1003a49fd6c +R10: ffff8801d24feb28 R11: 0000000000000005 R12: dffffc0000000000 +R13: ffff8801d24fec70 R14: 00000000fffbd14b R15: ffff8801af608f90 +FS: 0000000000000000(0000) GS:ffff8801db500000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00000000206d6fd0 CR3: 0000000006a22001 CR4: 00000000001606e0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +Call Trace: + led_tg+0x1db/0x2e0 net/netfilter/xt_LED.c:75 + ip6t_do_table+0xc2a/0x1a30 net/ipv6/netfilter/ip6_tables.c:365 + ip6table_raw_hook+0x65/0x80 net/ipv6/netfilter/ip6table_raw.c:42 + nf_hook_entry_hookfn include/linux/netfilter.h:120 [inline] + nf_hook_slow+0xba/0x1a0 net/netfilter/core.c:483 + nf_hook.constprop.27+0x3f6/0x830 include/linux/netfilter.h:243 + NF_HOOK include/linux/netfilter.h:286 [inline] + ndisc_send_skb+0xa51/0x1370 net/ipv6/ndisc.c:491 + ndisc_send_ns+0x38a/0x870 net/ipv6/ndisc.c:633 + addrconf_dad_work+0xb9e/0x1320 net/ipv6/addrconf.c:4008 + process_one_work+0xbbf/0x1af0 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:429 +Code: 85 2a 0b 00 00 4d 8b 3c 24 4d 85 ff 75 9f 4c 8b bd 60 fd ff ff e8 bb +57 10 00 65 ff 0d 94 9a a1 7e e9 d9 fc ff ff e8 aa 57 10 00 <0f> 0b e8 a3 +57 10 00 e9 14 fb ff ff e8 99 57 10 00 4c 89 bd 70 +RIP: __mod_timer kernel/time/timer.c:958 [inline] RSP: ffff8801d24fe9f8 +RIP: mod_timer+0x7d6/0x13c0 kernel/time/timer.c:1102 RSP: ffff8801d24fe9f8 +---[ end trace f661ab06f5dd8b3d ]--- + +The ledinternal struct can be shared between several different +xt_LED targets, but the related timer is currently initialized only +if the first target requires it. Fix it by unconditionally +initializing the timer struct. + +v1 -> v2: call del_timer_sync() unconditionally, too. + +Fixes: 268cb38e1802 ("netfilter: x_tables: add LED trigger target") +Reported-by: syzbot+10c98dc5725c6c8fc7fb@syzkaller.appspotmail.com +Signed-off-by: Paolo Abeni +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/xt_LED.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/net/netfilter/xt_LED.c ++++ b/net/netfilter/xt_LED.c +@@ -142,9 +142,10 @@ static int led_tg_check(const struct xt_ + goto exit_alloc; + } + +- /* See if we need to set up a timer */ +- if (ledinfo->delay > 0) +- timer_setup(&ledinternal->timer, led_timeout_callback, 0); ++ /* Since the letinternal timer can be shared between multiple targets, ++ * always set it up, even if the current target does not need it ++ */ ++ timer_setup(&ledinternal->timer, led_timeout_callback, 0); + + list_add_tail(&ledinternal->list, &xt_led_triggers); + +@@ -181,8 +182,7 @@ static void led_tg_destroy(const struct + + list_del(&ledinternal->list); + +- if (ledinfo->delay > 0) +- del_timer_sync(&ledinternal->timer); ++ del_timer_sync(&ledinternal->timer); + + led_trigger_unregister(&ledinternal->netfilter_led_trigger); + diff --git a/queue-4.15/netfilter-xt_hashlimit-fix-lock-imbalance.patch b/queue-4.15/netfilter-xt_hashlimit-fix-lock-imbalance.patch new file mode 100644 index 00000000000..8f6547f0401 --- /dev/null +++ b/queue-4.15/netfilter-xt_hashlimit-fix-lock-imbalance.patch @@ -0,0 +1,34 @@ +From de526f401284e1638d4c97cb5a4c292ac3f37655 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Mon, 12 Feb 2018 08:11:48 -0800 +Subject: netfilter: xt_hashlimit: fix lock imbalance + +From: Eric Dumazet + +commit de526f401284e1638d4c97cb5a4c292ac3f37655 upstream. + +syszkaller found that rcu was not held in hashlimit_mt_common() + +We only need to enable BH at this point. + +Fixes: bea74641e378 ("netfilter: xt_hashlimit: add rate match mode") +Signed-off-by: Eric Dumazet +Reported-by: syzkaller +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/xt_hashlimit.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/netfilter/xt_hashlimit.c ++++ b/net/netfilter/xt_hashlimit.c +@@ -774,7 +774,7 @@ hashlimit_mt_common(const struct sk_buff + if (!dh->rateinfo.prev_window && + (dh->rateinfo.current_rate <= dh->rateinfo.burst)) { + spin_unlock(&dh->lock); +- rcu_read_unlock_bh(); ++ local_bh_enable(); + return !(cfg->mode & XT_HASHLIMIT_INVERT); + } else { + goto overlimit; diff --git a/queue-4.15/series b/queue-4.15/series index 0a173b7c6fc..fdb8fe83c61 100644 --- a/queue-4.15/series +++ b/queue-4.15/series @@ -105,3 +105,13 @@ watchdog-hpwdt-smbios-check.patch watchdog-hpwdt-check-source-of-nmi.patch watchdog-hpwdt-fix-unused-variable-warning.patch watchdog-hpwdt-remove-legacy-nmi-sourcing.patch +netfilter-add-back-stackpointer-size-checks.patch +netfilter-ipt_clusterip-fix-a-race-condition-of-proc-file-creation.patch +netfilter-xt_hashlimit-fix-lock-imbalance.patch +netfilter-x_tables-fix-missing-timer-initialization-in-xt_led.patch +netfilter-nat-cope-with-negative-port-range.patch +netfilter-idletimer-be-syzkaller-friendly.patch +netfilter-ebtables-config_compat-don-t-trust-userland-offsets.patch +netfilter-bridge-ebt_among-add-missing-match-size-checks.patch +netfilter-ipv6-fix-use-after-free-write-in-nf_nat_ipv6_manip_pkt.patch +netfilter-use-skb_to_full_sk-in-ip6_route_me_harder.patch