From: Greg Kroah-Hartman Date: Wed, 26 Sep 2018 11:32:54 +0000 (+0200) Subject: 4.9-stable patches X-Git-Tag: v4.18.11~21 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f31b8242c26817286f6ba9c0501abfae45bc3705;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: gso_segment-reset-skb-mac_len-after-modifying-network-header.patch ipv6-fix-possible-use-after-free-in-ip6_xmit.patch neighbour-confirm-neigh-entries-when-arp-packet-is-received.patch net-appletalk-fix-minor-pointer-leak-to-userspace-in-siocfindipddprt.patch net-hp100-fix-always-true-check-for-link-up-state.patch udp4-fix-ip_cmsg_checksum-for-connected-sockets.patch --- diff --git a/queue-4.9/gso_segment-reset-skb-mac_len-after-modifying-network-header.patch b/queue-4.9/gso_segment-reset-skb-mac_len-after-modifying-network-header.patch new file mode 100644 index 00000000000..308eabf2c62 --- /dev/null +++ b/queue-4.9/gso_segment-reset-skb-mac_len-after-modifying-network-header.patch @@ -0,0 +1,55 @@ +From foo@baz Wed Sep 26 13:11:11 CEST 2018 +From: "Toke Høiland-Jørgensen" +Date: Thu, 13 Sep 2018 16:43:07 +0200 +Subject: gso_segment: Reset skb->mac_len after modifying network header + +From: "Toke Høiland-Jørgensen" + +[ Upstream commit c56cae23c6b167acc68043c683c4573b80cbcc2c ] + +When splitting a GSO segment that consists of encapsulated packets, the +skb->mac_len of the segments can end up being set wrong, causing packet +drops in particular when using act_mirred and ifb interfaces in +combination with a qdisc that splits GSO packets. + +This happens because at the time skb_segment() is called, network_header +will point to the inner header, throwing off the calculation in +skb_reset_mac_len(). The network_header is subsequently adjust by the +outer IP gso_segment handlers, but they don't set the mac_len. + +Fix this by adding skb_reset_mac_len() calls to both the IPv4 and IPv6 +gso_segment handlers, after they modify the network_header. + +Many thanks to Eric Dumazet for his help in identifying the cause of +the bug. + +Acked-by: Dave Taht +Reviewed-by: Eric Dumazet +Signed-off-by: Toke Høiland-Jørgensen +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/af_inet.c | 1 + + net/ipv6/ip6_offload.c | 1 + + 2 files changed, 2 insertions(+) + +--- a/net/ipv4/af_inet.c ++++ b/net/ipv4/af_inet.c +@@ -1277,6 +1277,7 @@ struct sk_buff *inet_gso_segment(struct + if (encap) + skb_reset_inner_headers(skb); + skb->network_header = (u8 *)iph - skb->head; ++ skb_reset_mac_len(skb); + } while ((skb = skb->next)); + + out: +--- a/net/ipv6/ip6_offload.c ++++ b/net/ipv6/ip6_offload.c +@@ -113,6 +113,7 @@ static struct sk_buff *ipv6_gso_segment( + payload_len = skb->len - nhoff - sizeof(*ipv6h); + ipv6h->payload_len = htons(payload_len); + skb->network_header = (u8 *)ipv6h - skb->head; ++ skb_reset_mac_len(skb); + + if (udpfrag) { + int err = ip6_find_1stfragopt(skb, &prevhdr); diff --git a/queue-4.9/ipv6-fix-possible-use-after-free-in-ip6_xmit.patch b/queue-4.9/ipv6-fix-possible-use-after-free-in-ip6_xmit.patch new file mode 100644 index 00000000000..598f7e92cee --- /dev/null +++ b/queue-4.9/ipv6-fix-possible-use-after-free-in-ip6_xmit.patch @@ -0,0 +1,41 @@ +From foo@baz Wed Sep 26 13:11:11 CEST 2018 +From: Eric Dumazet +Date: Fri, 14 Sep 2018 12:02:31 -0700 +Subject: ipv6: fix possible use-after-free in ip6_xmit() + +From: Eric Dumazet + +[ Upstream commit bbd6528d28c1b8e80832b3b018ec402b6f5c3215 ] + +In the unlikely case ip6_xmit() has to call skb_realloc_headroom(), +we need to call skb_set_owner_w() before consuming original skb, +otherwise we risk a use-after-free. + +Bring IPv6 in line with what we do in IPv4 to fix this. + +Fixes: 1da177e4c3f41 ("Linux-2.6.12-rc2") +Signed-off-by: Eric Dumazet +Reported-by: syzbot +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/ip6_output.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -201,12 +201,10 @@ int ip6_xmit(const struct sock *sk, stru + kfree_skb(skb); + return -ENOBUFS; + } ++ if (skb->sk) ++ skb_set_owner_w(skb2, skb->sk); + consume_skb(skb); + skb = skb2; +- /* skb_set_owner_w() changes sk->sk_wmem_alloc atomically, +- * it is safe to call in our context (socket lock not held) +- */ +- skb_set_owner_w(skb, (struct sock *)sk); + } + if (opt->opt_flen) + ipv6_push_frag_opts(skb, opt, &proto); diff --git a/queue-4.9/neighbour-confirm-neigh-entries-when-arp-packet-is-received.patch b/queue-4.9/neighbour-confirm-neigh-entries-when-arp-packet-is-received.patch new file mode 100644 index 00000000000..4a3c9de75e3 --- /dev/null +++ b/queue-4.9/neighbour-confirm-neigh-entries-when-arp-packet-is-received.patch @@ -0,0 +1,54 @@ +From foo@baz Wed Sep 26 13:11:11 CEST 2018 +From: Vasily Khoruzhick +Date: Thu, 13 Sep 2018 11:12:03 -0700 +Subject: neighbour: confirm neigh entries when ARP packet is received + +From: Vasily Khoruzhick + +[ Upstream commit f0e0d04413fcce9bc76388839099aee93cd0d33b ] + +Update 'confirmed' timestamp when ARP packet is received. It shouldn't +affect locktime logic and anyway entry can be confirmed by any higher-layer +protocol. Thus it makes sense to confirm it when ARP packet is received. + +Fixes: 77d7123342dc ("neighbour: update neigh timestamps iff update is effective") +Signed-off-by: Vasily Khoruzhick +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/neighbour.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +--- a/net/core/neighbour.c ++++ b/net/core/neighbour.c +@@ -1138,6 +1138,12 @@ int neigh_update(struct neighbour *neigh + lladdr = neigh->ha; + } + ++ /* Update confirmed timestamp for neighbour entry after we ++ * received ARP packet even if it doesn't change IP to MAC binding. ++ */ ++ if (new & NUD_CONNECTED) ++ neigh->confirmed = jiffies; ++ + /* If entry was valid and address is not changed, + do not change entry state, if new one is STALE. + */ +@@ -1159,15 +1165,12 @@ int neigh_update(struct neighbour *neigh + } + } + +- /* Update timestamps only once we know we will make a change to the ++ /* Update timestamp only once we know we will make a change to the + * neighbour entry. Otherwise we risk to move the locktime window with + * noop updates and ignore relevant ARP updates. + */ +- if (new != old || lladdr != neigh->ha) { +- if (new & NUD_CONNECTED) +- neigh->confirmed = jiffies; ++ if (new != old || lladdr != neigh->ha) + neigh->updated = jiffies; +- } + + if (new != old) { + neigh_del_timer(neigh); diff --git a/queue-4.9/net-appletalk-fix-minor-pointer-leak-to-userspace-in-siocfindipddprt.patch b/queue-4.9/net-appletalk-fix-minor-pointer-leak-to-userspace-in-siocfindipddprt.patch new file mode 100644 index 00000000000..ef4b7d0c1f8 --- /dev/null +++ b/queue-4.9/net-appletalk-fix-minor-pointer-leak-to-userspace-in-siocfindipddprt.patch @@ -0,0 +1,40 @@ +From foo@baz Wed Sep 26 13:11:11 CEST 2018 +From: Willy Tarreau +Date: Wed, 12 Sep 2018 07:36:35 +0200 +Subject: net/appletalk: fix minor pointer leak to userspace in SIOCFINDIPDDPRT + +From: Willy Tarreau + +[ Upstream commit 9824dfae5741275473a23a7ed5756c7b6efacc9d ] + +Fields ->dev and ->next of struct ipddp_route may be copied to +userspace on the SIOCFINDIPDDPRT ioctl. This is only accessible +to CAP_NET_ADMIN though. Let's manually copy the relevant fields +instead of using memcpy(). + +BugLink: http://blog.infosectcbr.com.au/2018/09/linux-kernel-infoleaks.html +Cc: Jann Horn +Signed-off-by: Willy Tarreau +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/appletalk/ipddp.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/net/appletalk/ipddp.c ++++ b/drivers/net/appletalk/ipddp.c +@@ -284,8 +284,12 @@ static int ipddp_ioctl(struct net_device + case SIOCFINDIPDDPRT: + spin_lock_bh(&ipddp_route_lock); + rp = __ipddp_find_route(&rcp); +- if (rp) +- memcpy(&rcp2, rp, sizeof(rcp2)); ++ if (rp) { ++ memset(&rcp2, 0, sizeof(rcp2)); ++ rcp2.ip = rp->ip; ++ rcp2.at = rp->at; ++ rcp2.flags = rp->flags; ++ } + spin_unlock_bh(&ipddp_route_lock); + + if (rp) { diff --git a/queue-4.9/net-hp100-fix-always-true-check-for-link-up-state.patch b/queue-4.9/net-hp100-fix-always-true-check-for-link-up-state.patch new file mode 100644 index 00000000000..3dfe3da4b99 --- /dev/null +++ b/queue-4.9/net-hp100-fix-always-true-check-for-link-up-state.patch @@ -0,0 +1,35 @@ +From foo@baz Wed Sep 26 13:11:11 CEST 2018 +From: Colin Ian King +Date: Fri, 14 Sep 2018 17:39:53 +0100 +Subject: net: hp100: fix always-true check for link up state + +From: Colin Ian King + +[ Upstream commit a7f38002fb69b44f8fc622ecb838665d0b8666af ] + +The operation ~(p100_inb(VG_LAN_CFG_1) & HP100_LINK_UP) returns a value +that is always non-zero and hence the wait for the link to drop always +terminates prematurely. Fix this by using a logical not operator instead +of a bitwise complement. This issue has been in the driver since +pre-2.6.12-rc2. + +Detected by CoverityScan, CID#114157 ("Logical vs. bitwise operator") + +Signed-off-by: Colin Ian King +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/hp/hp100.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/hp/hp100.c ++++ b/drivers/net/ethernet/hp/hp100.c +@@ -2636,7 +2636,7 @@ static int hp100_login_to_vg_hub(struct + /* Wait for link to drop */ + time = jiffies + (HZ / 10); + do { +- if (~(hp100_inb(VG_LAN_CFG_1) & HP100_LINK_UP_ST)) ++ if (!(hp100_inb(VG_LAN_CFG_1) & HP100_LINK_UP_ST)) + break; + if (!in_interrupt()) + schedule_timeout_interruptible(1); diff --git a/queue-4.9/series b/queue-4.9/series index 7a8cc92189e..1f5ded2ae3e 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -16,3 +16,9 @@ xen-x86-vpmu-zero-struct-pt_regs-before-calling-into-sample-handling-code.patch revert-pci-add-acs-quirk-for-intel-300-series.patch ring-buffer-allow-for-rescheduling-when-removing-pages.patch mm-shmem.c-correctly-annotate-new-inodes-for-lockdep.patch +gso_segment-reset-skb-mac_len-after-modifying-network-header.patch +ipv6-fix-possible-use-after-free-in-ip6_xmit.patch +net-appletalk-fix-minor-pointer-leak-to-userspace-in-siocfindipddprt.patch +net-hp100-fix-always-true-check-for-link-up-state.patch +udp4-fix-ip_cmsg_checksum-for-connected-sockets.patch +neighbour-confirm-neigh-entries-when-arp-packet-is-received.patch diff --git a/queue-4.9/udp4-fix-ip_cmsg_checksum-for-connected-sockets.patch b/queue-4.9/udp4-fix-ip_cmsg_checksum-for-connected-sockets.patch new file mode 100644 index 00000000000..a8ad2a206e7 --- /dev/null +++ b/queue-4.9/udp4-fix-ip_cmsg_checksum-for-connected-sockets.patch @@ -0,0 +1,99 @@ +From foo@baz Wed Sep 26 13:11:11 CEST 2018 +From: Paolo Abeni +Date: Thu, 13 Sep 2018 16:27:20 +0200 +Subject: udp4: fix IP_CMSG_CHECKSUM for connected sockets + +From: Paolo Abeni + +[ Upstream commit 2b5a921740a55c00223a797d075b9c77c42cb171 ] + +commit 2abb7cdc0dc8 ("udp: Add support for doing checksum +unnecessary conversion") left out the early demux path for +connected sockets. As a result IP_CMSG_CHECKSUM gives wrong +values for such socket when GRO is not enabled/available. + +This change addresses the issue by moving the csum conversion to a +common helper and using such helper in both the default and the +early demux rx path. + +Fixes: 2abb7cdc0dc8 ("udp: Add support for doing checksum unnecessary conversion") +Signed-off-by: Paolo Abeni +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/udp.c | 49 ++++++++++++++++++++++++++----------------------- + 1 file changed, 26 insertions(+), 23 deletions(-) + +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -1730,6 +1730,28 @@ static inline int udp4_csum_init(struct + inet_compute_pseudo); + } + ++/* wrapper for udp_queue_rcv_skb tacking care of csum conversion and ++ * return code conversion for ip layer consumption ++ */ ++static int udp_unicast_rcv_skb(struct sock *sk, struct sk_buff *skb, ++ struct udphdr *uh) ++{ ++ int ret; ++ ++ if (inet_get_convert_csum(sk) && uh->check && !IS_UDPLITE(sk)) ++ skb_checksum_try_convert(skb, IPPROTO_UDP, uh->check, ++ inet_compute_pseudo); ++ ++ ret = udp_queue_rcv_skb(sk, skb); ++ ++ /* a return value > 0 means to resubmit the input, but ++ * it wants the return to be -protocol, or 0 ++ */ ++ if (ret > 0) ++ return -ret; ++ return 0; ++} ++ + /* + * All we need to do is get the socket, and then do a checksum. + */ +@@ -1776,14 +1798,9 @@ int __udp4_lib_rcv(struct sk_buff *skb, + if (unlikely(sk->sk_rx_dst != dst)) + udp_sk_rx_dst_set(sk, dst); + +- ret = udp_queue_rcv_skb(sk, skb); ++ ret = udp_unicast_rcv_skb(sk, skb, uh); + sock_put(sk); +- /* a return value > 0 means to resubmit the input, but +- * it wants the return to be -protocol, or 0 +- */ +- if (ret > 0) +- return -ret; +- return 0; ++ return ret; + } + + if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST)) +@@ -1791,22 +1808,8 @@ int __udp4_lib_rcv(struct sk_buff *skb, + saddr, daddr, udptable, proto); + + sk = __udp4_lib_lookup_skb(skb, uh->source, uh->dest, udptable); +- if (sk) { +- int ret; +- +- if (inet_get_convert_csum(sk) && uh->check && !IS_UDPLITE(sk)) +- skb_checksum_try_convert(skb, IPPROTO_UDP, uh->check, +- inet_compute_pseudo); +- +- ret = udp_queue_rcv_skb(sk, skb); +- +- /* a return value > 0 means to resubmit the input, but +- * it wants the return to be -protocol, or 0 +- */ +- if (ret > 0) +- return -ret; +- return 0; +- } ++ if (sk) ++ return udp_unicast_rcv_skb(sk, skb, uh); + + if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) + goto drop;