From f3b4e9e95eb488d23f6e33c7e29cad3404de6470 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Sun, 24 Sep 2023 15:27:47 -0400 Subject: [PATCH] Fixes for 4.14 Signed-off-by: Sasha Levin --- ...cp-fix-dccp_v4_err-dccp_v6_err-again.patch | 132 ++++++++++++++++++ ...-fix-null-deref-in-ipv4_link_failure.patch | 53 +++++++ ...rf-hv-24x7-update-domain-value-check.patch | 63 +++++++++ queue-4.14/series | 4 + ...r-deref-when-team-device-type-is-cha.patch | 121 ++++++++++++++++ 5 files changed, 373 insertions(+) create mode 100644 queue-4.14/dccp-fix-dccp_v4_err-dccp_v6_err-again.patch create mode 100644 queue-4.14/ipv4-fix-null-deref-in-ipv4_link_failure.patch create mode 100644 queue-4.14/powerpc-perf-hv-24x7-update-domain-value-check.patch create mode 100644 queue-4.14/team-fix-null-ptr-deref-when-team-device-type-is-cha.patch diff --git a/queue-4.14/dccp-fix-dccp_v4_err-dccp_v6_err-again.patch b/queue-4.14/dccp-fix-dccp_v4_err-dccp_v6_err-again.patch new file mode 100644 index 00000000000..5441502bfb4 --- /dev/null +++ b/queue-4.14/dccp-fix-dccp_v4_err-dccp_v6_err-again.patch @@ -0,0 +1,132 @@ +From 40248ab9c9a57e66f5b3ca3683ac2f2345314d7f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Sep 2023 19:00:35 +0000 +Subject: dccp: fix dccp_v4_err()/dccp_v6_err() again + +From: Eric Dumazet + +[ Upstream commit 6af289746a636f71f4c0535a9801774118486c7a ] + +dh->dccph_x is the 9th byte (offset 8) in "struct dccp_hdr", +not in the "byte 7" as Jann claimed. + +We need to make sure the ICMP messages are big enough, +using more standard ways (no more assumptions). + +syzbot reported: +BUG: KMSAN: uninit-value in pskb_may_pull_reason include/linux/skbuff.h:2667 [inline] +BUG: KMSAN: uninit-value in pskb_may_pull include/linux/skbuff.h:2681 [inline] +BUG: KMSAN: uninit-value in dccp_v6_err+0x426/0x1aa0 net/dccp/ipv6.c:94 +pskb_may_pull_reason include/linux/skbuff.h:2667 [inline] +pskb_may_pull include/linux/skbuff.h:2681 [inline] +dccp_v6_err+0x426/0x1aa0 net/dccp/ipv6.c:94 +icmpv6_notify+0x4c7/0x880 net/ipv6/icmp.c:867 +icmpv6_rcv+0x19d5/0x30d0 +ip6_protocol_deliver_rcu+0xda6/0x2a60 net/ipv6/ip6_input.c:438 +ip6_input_finish net/ipv6/ip6_input.c:483 [inline] +NF_HOOK include/linux/netfilter.h:304 [inline] +ip6_input+0x15d/0x430 net/ipv6/ip6_input.c:492 +ip6_mc_input+0xa7e/0xc80 net/ipv6/ip6_input.c:586 +dst_input include/net/dst.h:468 [inline] +ip6_rcv_finish+0x5db/0x870 net/ipv6/ip6_input.c:79 +NF_HOOK include/linux/netfilter.h:304 [inline] +ipv6_rcv+0xda/0x390 net/ipv6/ip6_input.c:310 +__netif_receive_skb_one_core net/core/dev.c:5523 [inline] +__netif_receive_skb+0x1a6/0x5a0 net/core/dev.c:5637 +netif_receive_skb_internal net/core/dev.c:5723 [inline] +netif_receive_skb+0x58/0x660 net/core/dev.c:5782 +tun_rx_batched+0x83b/0x920 +tun_get_user+0x564c/0x6940 drivers/net/tun.c:2002 +tun_chr_write_iter+0x3af/0x5d0 drivers/net/tun.c:2048 +call_write_iter include/linux/fs.h:1985 [inline] +new_sync_write fs/read_write.c:491 [inline] +vfs_write+0x8ef/0x15c0 fs/read_write.c:584 +ksys_write+0x20f/0x4c0 fs/read_write.c:637 +__do_sys_write fs/read_write.c:649 [inline] +__se_sys_write fs/read_write.c:646 [inline] +__x64_sys_write+0x93/0xd0 fs/read_write.c:646 +do_syscall_x64 arch/x86/entry/common.c:50 [inline] +do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 +entry_SYSCALL_64_after_hwframe+0x63/0xcd + +Uninit was created at: +slab_post_alloc_hook+0x12f/0xb70 mm/slab.h:767 +slab_alloc_node mm/slub.c:3478 [inline] +kmem_cache_alloc_node+0x577/0xa80 mm/slub.c:3523 +kmalloc_reserve+0x13d/0x4a0 net/core/skbuff.c:559 +__alloc_skb+0x318/0x740 net/core/skbuff.c:650 +alloc_skb include/linux/skbuff.h:1286 [inline] +alloc_skb_with_frags+0xc8/0xbd0 net/core/skbuff.c:6313 +sock_alloc_send_pskb+0xa80/0xbf0 net/core/sock.c:2795 +tun_alloc_skb drivers/net/tun.c:1531 [inline] +tun_get_user+0x23cf/0x6940 drivers/net/tun.c:1846 +tun_chr_write_iter+0x3af/0x5d0 drivers/net/tun.c:2048 +call_write_iter include/linux/fs.h:1985 [inline] +new_sync_write fs/read_write.c:491 [inline] +vfs_write+0x8ef/0x15c0 fs/read_write.c:584 +ksys_write+0x20f/0x4c0 fs/read_write.c:637 +__do_sys_write fs/read_write.c:649 [inline] +__se_sys_write fs/read_write.c:646 [inline] +__x64_sys_write+0x93/0xd0 fs/read_write.c:646 +do_syscall_x64 arch/x86/entry/common.c:50 [inline] +do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 +entry_SYSCALL_64_after_hwframe+0x63/0xcd + +CPU: 0 PID: 4995 Comm: syz-executor153 Not tainted 6.6.0-rc1-syzkaller-00014-ga747acc0b752 #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 08/04/2023 + +Fixes: 977ad86c2a1b ("dccp: Fix out of bounds access in DCCP error handler") +Reported-by: syzbot +Signed-off-by: Eric Dumazet +Cc: Jann Horn +Reviewed-by: Jann Horn +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/dccp/ipv4.c | 9 ++------- + net/dccp/ipv6.c | 9 ++------- + 2 files changed, 4 insertions(+), 14 deletions(-) + +diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c +index b2fc9ef7708f2..1e71fca79c2fd 100644 +--- a/net/dccp/ipv4.c ++++ b/net/dccp/ipv4.c +@@ -247,13 +247,8 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info) + int err; + struct net *net = dev_net(skb->dev); + +- /* For the first __dccp_basic_hdr_len() check, we only need dh->dccph_x, +- * which is in byte 7 of the dccp header. +- * Our caller (icmp_socket_deliver()) already pulled 8 bytes for us. +- * +- * Later on, we want to access the sequence number fields, which are +- * beyond 8 bytes, so we have to pskb_may_pull() ourselves. +- */ ++ if (!pskb_may_pull(skb, offset + sizeof(*dh))) ++ return -EINVAL; + dh = (struct dccp_hdr *)(skb->data + offset); + if (!pskb_may_pull(skb, offset + __dccp_basic_hdr_len(dh))) + return; +diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c +index f8d8caa967b11..889613b7a0c39 100644 +--- a/net/dccp/ipv6.c ++++ b/net/dccp/ipv6.c +@@ -80,13 +80,8 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, + __u64 seq; + struct net *net = dev_net(skb->dev); + +- /* For the first __dccp_basic_hdr_len() check, we only need dh->dccph_x, +- * which is in byte 7 of the dccp header. +- * Our caller (icmpv6_notify()) already pulled 8 bytes for us. +- * +- * Later on, we want to access the sequence number fields, which are +- * beyond 8 bytes, so we have to pskb_may_pull() ourselves. +- */ ++ if (!pskb_may_pull(skb, offset + sizeof(*dh))) ++ return -EINVAL; + dh = (struct dccp_hdr *)(skb->data + offset); + if (!pskb_may_pull(skb, offset + __dccp_basic_hdr_len(dh))) + return; +-- +2.40.1 + diff --git a/queue-4.14/ipv4-fix-null-deref-in-ipv4_link_failure.patch b/queue-4.14/ipv4-fix-null-deref-in-ipv4_link_failure.patch new file mode 100644 index 00000000000..9f2e6dcb46d --- /dev/null +++ b/queue-4.14/ipv4-fix-null-deref-in-ipv4_link_failure.patch @@ -0,0 +1,53 @@ +From 4e93109dc11b08fe4b9ed1b42c9470f5b6b72926 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Sep 2023 22:12:57 -0700 +Subject: ipv4: fix null-deref in ipv4_link_failure + +From: Kyle Zeng + +[ Upstream commit 0113d9c9d1ccc07f5a3710dac4aa24b6d711278c ] + +Currently, we assume the skb is associated with a device before calling +__ip_options_compile, which is not always the case if it is re-routed by +ipvs. +When skb->dev is NULL, dev_net(skb->dev) will become null-dereference. +This patch adds a check for the edge case and switch to use the net_device +from the rtable when skb->dev is NULL. + +Fixes: ed0de45a1008 ("ipv4: recompile ip options in ipv4_link_failure") +Suggested-by: David Ahern +Signed-off-by: Kyle Zeng +Cc: Stephen Suryaputra +Cc: Vadim Fedorenko +Reviewed-by: David Ahern +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/ipv4/route.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/net/ipv4/route.c b/net/ipv4/route.c +index 52c4098e1debf..4a6f4ef369d05 100644 +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -1221,6 +1221,7 @@ static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie) + + static void ipv4_send_dest_unreach(struct sk_buff *skb) + { ++ struct net_device *dev; + struct ip_options opt; + int res; + +@@ -1238,7 +1239,8 @@ static void ipv4_send_dest_unreach(struct sk_buff *skb) + opt.optlen = ip_hdr(skb)->ihl * 4 - sizeof(struct iphdr); + + rcu_read_lock(); +- res = __ip_options_compile(dev_net(skb->dev), &opt, skb, NULL); ++ dev = skb->dev ? skb->dev : skb_rtable(skb)->dst.dev; ++ res = __ip_options_compile(dev_net(dev), &opt, skb, NULL); + rcu_read_unlock(); + + if (res) +-- +2.40.1 + diff --git a/queue-4.14/powerpc-perf-hv-24x7-update-domain-value-check.patch b/queue-4.14/powerpc-perf-hv-24x7-update-domain-value-check.patch new file mode 100644 index 00000000000..63b87c8f397 --- /dev/null +++ b/queue-4.14/powerpc-perf-hv-24x7-update-domain-value-check.patch @@ -0,0 +1,63 @@ +From 803d8c6666a941dc2a435d1b4aa2b8f652adfbc9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Aug 2023 11:26:01 +0530 +Subject: powerpc/perf/hv-24x7: Update domain value check + +From: Kajol Jain + +[ Upstream commit 4ff3ba4db5943cac1045e3e4a3c0463ea10f6930 ] + +Valid domain value is in range 1 to HV_PERF_DOMAIN_MAX. Current code has +check for domain value greater than or equal to HV_PERF_DOMAIN_MAX. But +the check for domain value 0 is missing. + +Fix this issue by adding check for domain value 0. + +Before: + # ./perf stat -v -e hv_24x7/CPM_ADJUNCT_INST,domain=0,core=1/ sleep 1 + Using CPUID 00800200 + Control descriptor is not initialized + Error: + The sys_perf_event_open() syscall returned with 5 (Input/output error) for + event (hv_24x7/CPM_ADJUNCT_INST,domain=0,core=1/). + /bin/dmesg | grep -i perf may provide additional information. + + Result from dmesg: + [ 37.819387] hv-24x7: hcall failed: [0 0x60040000 0x100 0] => ret + 0xfffffffffffffffc (-4) detail=0x2000000 failing ix=0 + +After: + # ./perf stat -v -e hv_24x7/CPM_ADJUNCT_INST,domain=0,core=1/ sleep 1 + Using CPUID 00800200 + Control descriptor is not initialized + Warning: + hv_24x7/CPM_ADJUNCT_INST,domain=0,core=1/ event is not supported by the kernel. + failed to read counter hv_24x7/CPM_ADJUNCT_INST,domain=0,core=1/ + +Fixes: ebd4a5a3ebd9 ("powerpc/perf/hv-24x7: Minor improvements") +Reported-by: Krishan Gopal Sarawast +Signed-off-by: Kajol Jain +Tested-by: Disha Goel +Signed-off-by: Michael Ellerman +Link: https://msgid.link/20230825055601.360083-1-kjain@linux.ibm.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/perf/hv-24x7.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c +index 2bb798918483d..e6eb2b4cf97ea 100644 +--- a/arch/powerpc/perf/hv-24x7.c ++++ b/arch/powerpc/perf/hv-24x7.c +@@ -1326,7 +1326,7 @@ static int h_24x7_event_init(struct perf_event *event) + } + + domain = event_get_domain(event); +- if (domain >= HV_PERF_DOMAIN_MAX) { ++ if (domain == 0 || domain >= HV_PERF_DOMAIN_MAX) { + pr_devel("invalid domain %d\n", domain); + return -EINVAL; + } +-- +2.40.1 + diff --git a/queue-4.14/series b/queue-4.14/series index 80b0e13f003..edd8a67c04b 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -1 +1,5 @@ nfs-pnfs-report-einval-errors-from-connect-to-the-se.patch +ipv4-fix-null-deref-in-ipv4_link_failure.patch +powerpc-perf-hv-24x7-update-domain-value-check.patch +dccp-fix-dccp_v4_err-dccp_v6_err-again.patch +team-fix-null-ptr-deref-when-team-device-type-is-cha.patch diff --git a/queue-4.14/team-fix-null-ptr-deref-when-team-device-type-is-cha.patch b/queue-4.14/team-fix-null-ptr-deref-when-team-device-type-is-cha.patch new file mode 100644 index 00000000000..9c804673a7f --- /dev/null +++ b/queue-4.14/team-fix-null-ptr-deref-when-team-device-type-is-cha.patch @@ -0,0 +1,121 @@ +From 3363b76b7e01bc38781d3957d6f465a5f489976d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 18 Sep 2023 20:30:11 +0800 +Subject: team: fix null-ptr-deref when team device type is changed + +From: Ziyang Xuan + +[ Upstream commit 492032760127251e5540a5716a70996bacf2a3fd ] + +Get a null-ptr-deref bug as follows with reproducer [1]. + +BUG: kernel NULL pointer dereference, address: 0000000000000228 +... +RIP: 0010:vlan_dev_hard_header+0x35/0x140 [8021q] +... +Call Trace: + + ? __die+0x24/0x70 + ? page_fault_oops+0x82/0x150 + ? exc_page_fault+0x69/0x150 + ? asm_exc_page_fault+0x26/0x30 + ? vlan_dev_hard_header+0x35/0x140 [8021q] + ? vlan_dev_hard_header+0x8e/0x140 [8021q] + neigh_connected_output+0xb2/0x100 + ip6_finish_output2+0x1cb/0x520 + ? nf_hook_slow+0x43/0xc0 + ? ip6_mtu+0x46/0x80 + ip6_finish_output+0x2a/0xb0 + mld_sendpack+0x18f/0x250 + mld_ifc_work+0x39/0x160 + process_one_work+0x1e6/0x3f0 + worker_thread+0x4d/0x2f0 + ? __pfx_worker_thread+0x10/0x10 + kthread+0xe5/0x120 + ? __pfx_kthread+0x10/0x10 + ret_from_fork+0x34/0x50 + ? __pfx_kthread+0x10/0x10 + ret_from_fork_asm+0x1b/0x30 + +[1] +$ teamd -t team0 -d -c '{"runner": {"name": "loadbalance"}}' +$ ip link add name t-dummy type dummy +$ ip link add link t-dummy name t-dummy.100 type vlan id 100 +$ ip link add name t-nlmon type nlmon +$ ip link set t-nlmon master team0 +$ ip link set t-nlmon nomaster +$ ip link set t-dummy up +$ ip link set team0 up +$ ip link set t-dummy.100 down +$ ip link set t-dummy.100 master team0 + +When enslave a vlan device to team device and team device type is changed +from non-ether to ether, header_ops of team device is changed to +vlan_header_ops. That is incorrect and will trigger null-ptr-deref +for vlan->real_dev in vlan_dev_hard_header() because team device is not +a vlan device. + +Cache eth_header_ops in team_setup(), then assign cached header_ops to +header_ops of team net device when its type is changed from non-ether +to ether to fix the bug. + +Fixes: 1d76efe1577b ("team: add support for non-ethernet devices") +Suggested-by: Hangbin Liu +Reviewed-by: Hangbin Liu +Signed-off-by: Ziyang Xuan +Reviewed-by: Jiri Pirko +Reviewed-by: Eric Dumazet +Link: https://lore.kernel.org/r/20230918123011.1884401-1-william.xuanziyang@huawei.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/team/team.c | 10 +++++++++- + include/linux/if_team.h | 2 ++ + 2 files changed, 11 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c +index 7b6cae28f6d3d..db7069e46eff0 100644 +--- a/drivers/net/team/team.c ++++ b/drivers/net/team/team.c +@@ -2087,7 +2087,12 @@ static const struct ethtool_ops team_ethtool_ops = { + static void team_setup_by_port(struct net_device *dev, + struct net_device *port_dev) + { +- dev->header_ops = port_dev->header_ops; ++ struct team *team = netdev_priv(dev); ++ ++ if (port_dev->type == ARPHRD_ETHER) ++ dev->header_ops = team->header_ops_cache; ++ else ++ dev->header_ops = port_dev->header_ops; + dev->type = port_dev->type; + dev->hard_header_len = port_dev->hard_header_len; + dev->needed_headroom = port_dev->needed_headroom; +@@ -2134,8 +2139,11 @@ static int team_dev_type_check_change(struct net_device *dev, + + static void team_setup(struct net_device *dev) + { ++ struct team *team = netdev_priv(dev); ++ + ether_setup(dev); + dev->max_mtu = ETH_MAX_MTU; ++ team->header_ops_cache = dev->header_ops; + + dev->netdev_ops = &team_netdev_ops; + dev->ethtool_ops = &team_ethtool_ops; +diff --git a/include/linux/if_team.h b/include/linux/if_team.h +index 30294603526f9..31e1798aa6b02 100644 +--- a/include/linux/if_team.h ++++ b/include/linux/if_team.h +@@ -178,6 +178,8 @@ struct team { + struct net_device *dev; /* associated netdevice */ + struct team_pcpu_stats __percpu *pcpu_stats; + ++ const struct header_ops *header_ops_cache; ++ + struct mutex lock; /* used for overall locking, e.g. port lists write */ + + /* +-- +2.40.1 + -- 2.47.3