From 17407fc7c1a44f4dfc0cec2a4441ac8d6bb55a00 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 10 Apr 2021 16:33:50 +0200 Subject: [PATCH] 4.19-stable patches added patches: net-ipv6-bugfix-raw-sctp-switch-to-ipv6_can_nonlocal_bind.patch net-sched-sch_teql-fix-null-pointer-dereference.patch --- ...ctp-switch-to-ipv6_can_nonlocal_bind.patch | 85 +++++++++++++++++ ...ch_teql-fix-null-pointer-dereference.patch | 92 +++++++++++++++++++ queue-4.19/series | 2 + 3 files changed, 179 insertions(+) create mode 100644 queue-4.19/net-ipv6-bugfix-raw-sctp-switch-to-ipv6_can_nonlocal_bind.patch create mode 100644 queue-4.19/net-sched-sch_teql-fix-null-pointer-dereference.patch diff --git a/queue-4.19/net-ipv6-bugfix-raw-sctp-switch-to-ipv6_can_nonlocal_bind.patch b/queue-4.19/net-ipv6-bugfix-raw-sctp-switch-to-ipv6_can_nonlocal_bind.patch new file mode 100644 index 00000000000..03a682fd633 --- /dev/null +++ b/queue-4.19/net-ipv6-bugfix-raw-sctp-switch-to-ipv6_can_nonlocal_bind.patch @@ -0,0 +1,85 @@ +From 630e4576f83accf90366686f39808d665d8dbecc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= +Date: Mon, 5 Apr 2021 00:06:52 -0700 +Subject: net-ipv6: bugfix - raw & sctp - switch to ipv6_can_nonlocal_bind() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Maciej Żenczykowski + +commit 630e4576f83accf90366686f39808d665d8dbecc upstream. + +Found by virtue of ipv6 raw sockets not honouring the per-socket +IP{,V6}_FREEBIND setting. + +Based on hits found via: + git grep '[.]ip_nonlocal_bind' +We fix both raw ipv6 sockets to honour IP{,V6}_FREEBIND and IP{,V6}_TRANSPARENT, +and we fix sctp sockets to honour IP{,V6}_TRANSPARENT (they already honoured +FREEBIND), and not just the ipv6 'ip_nonlocal_bind' sysctl. + +The helper is defined as: + static inline bool ipv6_can_nonlocal_bind(struct net *net, struct inet_sock *inet) { + return net->ipv6.sysctl.ip_nonlocal_bind || inet->freebind || inet->transparent; + } +so this change only widens the accepted opt-outs and is thus a clean bugfix. + +I'm not entirely sure what 'fixes' tag to add, since this is AFAICT an ancient bug, +but IMHO this should be applied to stable kernels as far back as possible. +As such I'm adding a 'fixes' tag with the commit that originally added the helper, +which happened in 4.19. Backporting to older LTS kernels (at least 4.9 and 4.14) +would presumably require open-coding it or backporting the helper as well. + +Other possibly relevant commits: + v4.18-rc6-1502-g83ba4645152d net: add helpers checking if socket can be bound to nonlocal address + v4.18-rc6-1431-gd0c1f01138c4 net/ipv6: allow any source address for sendmsg pktinfo with ip_nonlocal_bind + v4.14-rc5-271-gb71d21c274ef sctp: full support for ipv6 ip_nonlocal_bind & IP_FREEBIND + v4.7-rc7-1883-g9b9742022888 sctp: support ipv6 nonlocal bind + v4.1-12247-g35a256fee52c ipv6: Nonlocal bind + +Cc: Lorenzo Colitti +Fixes: 83ba4645152d ("net: add helpers checking if socket can be bound to nonlocal address") +Signed-off-by: Maciej Żenczykowski +Reviewed-By: Lorenzo Colitti +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/raw.c | 2 +- + net/sctp/ipv6.c | 7 +++---- + 2 files changed, 4 insertions(+), 5 deletions(-) + +--- a/net/ipv6/raw.c ++++ b/net/ipv6/raw.c +@@ -303,7 +303,7 @@ static int rawv6_bind(struct sock *sk, s + */ + v4addr = LOOPBACK4_IPV6; + if (!(addr_type & IPV6_ADDR_MULTICAST) && +- !sock_net(sk)->ipv6.sysctl.ip_nonlocal_bind) { ++ !ipv6_can_nonlocal_bind(sock_net(sk), inet)) { + err = -EADDRNOTAVAIL; + if (!ipv6_chk_addr(sock_net(sk), &addr->sin6_addr, + dev, 0)) { +--- a/net/sctp/ipv6.c ++++ b/net/sctp/ipv6.c +@@ -655,8 +655,8 @@ static int sctp_v6_available(union sctp_ + if (!(type & IPV6_ADDR_UNICAST)) + return 0; + +- return sp->inet.freebind || net->ipv6.sysctl.ip_nonlocal_bind || +- ipv6_chk_addr(net, in6, NULL, 0); ++ return ipv6_can_nonlocal_bind(net, &sp->inet) || ++ ipv6_chk_addr(net, in6, NULL, 0); + } + + /* This function checks if the address is a valid address to be used for +@@ -945,8 +945,7 @@ static int sctp_inet6_bind_verify(struct + net = sock_net(&opt->inet.sk); + rcu_read_lock(); + dev = dev_get_by_index_rcu(net, addr->v6.sin6_scope_id); +- if (!dev || !(opt->inet.freebind || +- net->ipv6.sysctl.ip_nonlocal_bind || ++ if (!dev || !(ipv6_can_nonlocal_bind(net, &opt->inet) || + ipv6_chk_addr(net, &addr->v6.sin6_addr, + dev, 0))) { + rcu_read_unlock(); diff --git a/queue-4.19/net-sched-sch_teql-fix-null-pointer-dereference.patch b/queue-4.19/net-sched-sch_teql-fix-null-pointer-dereference.patch new file mode 100644 index 00000000000..7050c2fc6dd --- /dev/null +++ b/queue-4.19/net-sched-sch_teql-fix-null-pointer-dereference.patch @@ -0,0 +1,92 @@ +From 1ffbc7ea91606e4abd10eb60de5367f1c86daf5e Mon Sep 17 00:00:00 2001 +From: Pavel Tikhomirov +Date: Thu, 8 Apr 2021 18:14:31 +0300 +Subject: net: sched: sch_teql: fix null-pointer dereference + +From: Pavel Tikhomirov + +commit 1ffbc7ea91606e4abd10eb60de5367f1c86daf5e upstream. + +Reproduce: + + modprobe sch_teql + tc qdisc add dev teql0 root teql0 + +This leads to (for instance in Centos 7 VM) OOPS: + +[ 532.366633] BUG: unable to handle kernel NULL pointer dereference at 00000000000000a8 +[ 532.366733] IP: [] teql_destroy+0x18/0x100 [sch_teql] +[ 532.366825] PGD 80000001376d5067 PUD 137e37067 PMD 0 +[ 532.366906] Oops: 0000 [#1] SMP +[ 532.366987] Modules linked in: sch_teql ... +[ 532.367945] CPU: 1 PID: 3026 Comm: tc Kdump: loaded Tainted: G ------------ T 3.10.0-1062.7.1.el7.x86_64 #1 +[ 532.368041] Hardware name: Virtuozzo KVM, BIOS 1.11.0-2.vz7.2 04/01/2014 +[ 532.368125] task: ffff8b7d37d31070 ti: ffff8b7c9fdbc000 task.ti: ffff8b7c9fdbc000 +[ 532.368224] RIP: 0010:[] [] teql_destroy+0x18/0x100 [sch_teql] +[ 532.368320] RSP: 0018:ffff8b7c9fdbf8e0 EFLAGS: 00010286 +[ 532.368394] RAX: ffffffffc0612490 RBX: ffff8b7cb1565e00 RCX: ffff8b7d35ba2000 +[ 532.368476] RDX: ffff8b7d35ba2000 RSI: 0000000000000000 RDI: ffff8b7cb1565e00 +[ 532.368557] RBP: ffff8b7c9fdbf8f8 R08: ffff8b7d3fd1f140 R09: ffff8b7d3b001600 +[ 532.368638] R10: ffff8b7d3b001600 R11: ffffffff84c7d65b R12: 00000000ffffffd8 +[ 532.368719] R13: 0000000000008000 R14: ffff8b7d35ba2000 R15: ffff8b7c9fdbf9a8 +[ 532.368800] FS: 00007f6a4e872740(0000) GS:ffff8b7d3fd00000(0000) knlGS:0000000000000000 +[ 532.368885] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 532.368961] CR2: 00000000000000a8 CR3: 00000001396ee000 CR4: 00000000000206e0 +[ 532.369046] Call Trace: +[ 532.369159] [] qdisc_create+0x36e/0x450 +[ 532.369268] [] ? ns_capable+0x29/0x50 +[ 532.369366] [] ? nla_parse+0x32/0x120 +[ 532.369442] [] tc_modify_qdisc+0x13c/0x610 +[ 532.371508] [] rtnetlink_rcv_msg+0xa7/0x260 +[ 532.372668] [] ? sock_has_perm+0x75/0x90 +[ 532.373790] [] ? rtnl_newlink+0x890/0x890 +[ 532.374914] [] netlink_rcv_skb+0xab/0xc0 +[ 532.376055] [] rtnetlink_rcv+0x28/0x30 +[ 532.377204] [] netlink_unicast+0x170/0x210 +[ 532.378333] [] netlink_sendmsg+0x308/0x420 +[ 532.379465] [] sock_sendmsg+0xb6/0xf0 +[ 532.380710] [] ? __xfs_filemap_fault+0x8e/0x1d0 [xfs] +[ 532.381868] [] ? xfs_filemap_fault+0x2c/0x30 [xfs] +[ 532.383037] [] ? __do_fault.isra.61+0x8a/0x100 +[ 532.384144] [] ___sys_sendmsg+0x3e9/0x400 +[ 532.385268] [] ? handle_mm_fault+0x39d/0x9b0 +[ 532.386387] [] ? __do_page_fault+0x238/0x500 +[ 532.387472] [] __sys_sendmsg+0x51/0x90 +[ 532.388560] [] SyS_sendmsg+0x12/0x20 +[ 532.389636] [] system_call_fastpath+0x25/0x2a +[ 532.390704] [] ? system_call_after_swapgs+0xae/0x146 +[ 532.391753] Code: 00 00 00 00 00 00 5b 5d c3 66 2e 0f 1f 84 00 00 00 00 00 66 66 66 66 90 55 48 89 e5 41 55 41 54 53 48 8b b7 48 01 00 00 48 89 fb <48> 8b 8e a8 00 00 00 48 85 c9 74 43 48 89 ca eb 0f 0f 1f 80 00 +[ 532.394036] RIP [] teql_destroy+0x18/0x100 [sch_teql] +[ 532.395127] RSP +[ 532.396179] CR2: 00000000000000a8 + +Null pointer dereference happens on master->slaves dereference in +teql_destroy() as master is null-pointer. + +When qdisc_create() calls teql_qdisc_init() it imediately fails after +check "if (m->dev == dev)" because both devices are teql0, and it does +not set qdisc_priv(sch)->m leaving it zero on error path, then +qdisc_create() imediately calls teql_destroy() which does not expect +zero master pointer and we get OOPS. + +Fixes: 87b60cfacf9f ("net_sched: fix error recovery at qdisc creation") +Signed-off-by: Pavel Tikhomirov +Reviewed-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/sched/sch_teql.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/sched/sch_teql.c ++++ b/net/sched/sch_teql.c +@@ -138,6 +138,9 @@ teql_destroy(struct Qdisc *sch) + struct teql_sched_data *dat = qdisc_priv(sch); + struct teql_master *master = dat->m; + ++ if (!master) ++ return; ++ + prev = master->slaves; + if (prev) { + do { diff --git a/queue-4.19/series b/queue-4.19/series index 91bb0c6a847..1a65fd3fa04 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -17,3 +17,5 @@ batman-adv-initialize-struct-batadv_tvlv_tt_vlan_data-reserved-field.patch ice-increase-control-queue-timeout.patch net-hso-fix-null-ptr-deref-during-tty-device-unregistration.patch net-ensure-mac-header-is-set-in-virtio_net_hdr_to_skb.patch +net-sched-sch_teql-fix-null-pointer-dereference.patch +net-ipv6-bugfix-raw-sctp-switch-to-ipv6_can_nonlocal_bind.patch -- 2.47.3