]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 26 Sep 2018 11:32:54 +0000 (13:32 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 26 Sep 2018 11:32:54 +0000 (13:32 +0200)
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

queue-4.9/gso_segment-reset-skb-mac_len-after-modifying-network-header.patch [new file with mode: 0644]
queue-4.9/ipv6-fix-possible-use-after-free-in-ip6_xmit.patch [new file with mode: 0644]
queue-4.9/neighbour-confirm-neigh-entries-when-arp-packet-is-received.patch [new file with mode: 0644]
queue-4.9/net-appletalk-fix-minor-pointer-leak-to-userspace-in-siocfindipddprt.patch [new file with mode: 0644]
queue-4.9/net-hp100-fix-always-true-check-for-link-up-state.patch [new file with mode: 0644]
queue-4.9/series
queue-4.9/udp4-fix-ip_cmsg_checksum-for-connected-sockets.patch [new file with mode: 0644]

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 (file)
index 0000000..308eabf
--- /dev/null
@@ -0,0 +1,55 @@
+From foo@baz Wed Sep 26 13:11:11 CEST 2018
+From: "Toke Høiland-Jørgensen" <toke@toke.dk>
+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" <toke@toke.dk>
+
+[ 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 <dave.taht@gmail.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..598f7e9
--- /dev/null
@@ -0,0 +1,41 @@
+From foo@baz Wed Sep 26 13:11:11 CEST 2018
+From: Eric Dumazet <edumazet@google.com>
+Date: Fri, 14 Sep 2018 12:02:31 -0700
+Subject: ipv6: fix possible use-after-free in ip6_xmit()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ 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 <edumazet@google.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..4a3c9de
--- /dev/null
@@ -0,0 +1,54 @@
+From foo@baz Wed Sep 26 13:11:11 CEST 2018
+From: Vasily Khoruzhick <vasilykh@arista.com>
+Date: Thu, 13 Sep 2018 11:12:03 -0700
+Subject: neighbour: confirm neigh entries when ARP packet is received
+
+From: Vasily Khoruzhick <vasilykh@arista.com>
+
+[ 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 <vasilykh@arista.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..ef4b7d0
--- /dev/null
@@ -0,0 +1,40 @@
+From foo@baz Wed Sep 26 13:11:11 CEST 2018
+From: Willy Tarreau <w@1wt.eu>
+Date: Wed, 12 Sep 2018 07:36:35 +0200
+Subject: net/appletalk: fix minor pointer leak to userspace in SIOCFINDIPDDPRT
+
+From: Willy Tarreau <w@1wt.eu>
+
+[ 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 <jannh@google.com>
+Signed-off-by: Willy Tarreau <w@1wt.eu>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..3dfe3da
--- /dev/null
@@ -0,0 +1,35 @@
+From foo@baz Wed Sep 26 13:11:11 CEST 2018
+From: Colin Ian King <colin.king@canonical.com>
+Date: Fri, 14 Sep 2018 17:39:53 +0100
+Subject: net: hp100: fix always-true check for link up state
+
+From: Colin Ian King <colin.king@canonical.com>
+
+[ 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 <colin.king@canonical.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);
index 7a8cc92189e3350d1cba428f517c2a0591e992d6..1f5ded2ae3e2ecad15d647fba91fa42ecf2341a0 100644 (file)
@@ -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 (file)
index 0000000..a8ad2a2
--- /dev/null
@@ -0,0 +1,99 @@
+From foo@baz Wed Sep 26 13:11:11 CEST 2018
+From: Paolo Abeni <pabeni@redhat.com>
+Date: Thu, 13 Sep 2018 16:27:20 +0200
+Subject: udp4: fix IP_CMSG_CHECKSUM for connected sockets
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+[ 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 <pabeni@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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;