]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 21 Nov 2017 12:39:53 +0000 (13:39 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 21 Nov 2017 12:39:53 +0000 (13:39 +0100)
added patches:
af_netlink-ensure-that-nlmsg_done-never-fails-in-dumps.patch
bio-ensure-__bio_clone_fast-copies-bi_partno.patch
fealnx-fix-building-error-on-mips.patch
net-cdc_ncm-getntbformat-endian-fix.patch
net-sctp-always-set-scope_id-in-sctp_inet6_skb_msgname.patch
vxlan-fix-the-issue-that-neigh-proxy-blocks-all-icmpv6-packets.patch

queue-4.14/af_netlink-ensure-that-nlmsg_done-never-fails-in-dumps.patch [new file with mode: 0644]
queue-4.14/bio-ensure-__bio_clone_fast-copies-bi_partno.patch [new file with mode: 0644]
queue-4.14/fealnx-fix-building-error-on-mips.patch [new file with mode: 0644]
queue-4.14/net-cdc_ncm-getntbformat-endian-fix.patch [new file with mode: 0644]
queue-4.14/net-sctp-always-set-scope_id-in-sctp_inet6_skb_msgname.patch [new file with mode: 0644]
queue-4.14/vxlan-fix-the-issue-that-neigh-proxy-blocks-all-icmpv6-packets.patch [new file with mode: 0644]

diff --git a/queue-4.14/af_netlink-ensure-that-nlmsg_done-never-fails-in-dumps.patch b/queue-4.14/af_netlink-ensure-that-nlmsg_done-never-fails-in-dumps.patch
new file mode 100644 (file)
index 0000000..1f1ba79
--- /dev/null
@@ -0,0 +1,114 @@
+From foo@baz Tue Nov 21 13:07:02 CET 2017
+From: "Jason A. Donenfeld" <Jason@zx2c4.com>
+Date: Thu, 9 Nov 2017 13:04:44 +0900
+Subject: af_netlink: ensure that NLMSG_DONE never fails in dumps
+
+From: "Jason A. Donenfeld" <Jason@zx2c4.com>
+
+
+[ Upstream commit 0642840b8bb008528dbdf929cec9f65ac4231ad0 ]
+
+The way people generally use netlink_dump is that they fill in the skb
+as much as possible, breaking when nla_put returns an error. Then, they
+get called again and start filling out the next skb, and again, and so
+forth. The mechanism at work here is the ability for the iterative
+dumping function to detect when the skb is filled up and not fill it
+past the brim, waiting for a fresh skb for the rest of the data.
+
+However, if the attributes are small and nicely packed, it is possible
+that a dump callback function successfully fills in attributes until the
+skb is of size 4080 (libmnl's default page-sized receive buffer size).
+The dump function completes, satisfied, and then, if it happens to be
+that this is actually the last skb, and no further ones are to be sent,
+then netlink_dump will add on the NLMSG_DONE part:
+
+  nlh = nlmsg_put_answer(skb, cb, NLMSG_DONE, sizeof(len), NLM_F_MULTI);
+
+It is very important that netlink_dump does this, of course. However, in
+this example, that call to nlmsg_put_answer will fail, because the
+previous filling by the dump function did not leave it enough room. And
+how could it possibly have done so? All of the nla_put variety of
+functions simply check to see if the skb has enough tailroom,
+independent of the context it is in.
+
+In order to keep the important assumptions of all netlink dump users, it
+is therefore important to give them an skb that has this end part of the
+tail already reserved, so that the call to nlmsg_put_answer does not
+fail. Otherwise, library authors are forced to find some bizarre sized
+receive buffer that has a large modulo relative to the common sizes of
+messages received, which is ugly and buggy.
+
+This patch thus saves the NLMSG_DONE for an additional message, for the
+case that things are dangerously close to the brim. This requires
+keeping track of the errno from ->dump() across calls.
+
+Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/netlink/af_netlink.c |   17 +++++++++++------
+ net/netlink/af_netlink.h |    1 +
+ 2 files changed, 12 insertions(+), 6 deletions(-)
+
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -2136,7 +2136,7 @@ static int netlink_dump(struct sock *sk)
+       struct sk_buff *skb = NULL;
+       struct nlmsghdr *nlh;
+       struct module *module;
+-      int len, err = -ENOBUFS;
++      int err = -ENOBUFS;
+       int alloc_min_size;
+       int alloc_size;
+@@ -2183,9 +2183,11 @@ static int netlink_dump(struct sock *sk)
+       skb_reserve(skb, skb_tailroom(skb) - alloc_size);
+       netlink_skb_set_owner_r(skb, sk);
+-      len = cb->dump(skb, cb);
++      if (nlk->dump_done_errno > 0)
++              nlk->dump_done_errno = cb->dump(skb, cb);
+-      if (len > 0) {
++      if (nlk->dump_done_errno > 0 ||
++          skb_tailroom(skb) < nlmsg_total_size(sizeof(nlk->dump_done_errno))) {
+               mutex_unlock(nlk->cb_mutex);
+               if (sk_filter(sk, skb))
+@@ -2195,13 +2197,15 @@ static int netlink_dump(struct sock *sk)
+               return 0;
+       }
+-      nlh = nlmsg_put_answer(skb, cb, NLMSG_DONE, sizeof(len), NLM_F_MULTI);
+-      if (!nlh)
++      nlh = nlmsg_put_answer(skb, cb, NLMSG_DONE,
++                             sizeof(nlk->dump_done_errno), NLM_F_MULTI);
++      if (WARN_ON(!nlh))
+               goto errout_skb;
+       nl_dump_check_consistent(cb, nlh);
+-      memcpy(nlmsg_data(nlh), &len, sizeof(len));
++      memcpy(nlmsg_data(nlh), &nlk->dump_done_errno,
++             sizeof(nlk->dump_done_errno));
+       if (sk_filter(sk, skb))
+               kfree_skb(skb);
+@@ -2273,6 +2277,7 @@ int __netlink_dump_start(struct sock *ss
+       }
+       nlk->cb_running = true;
++      nlk->dump_done_errno = INT_MAX;
+       mutex_unlock(nlk->cb_mutex);
+--- a/net/netlink/af_netlink.h
++++ b/net/netlink/af_netlink.h
+@@ -34,6 +34,7 @@ struct netlink_sock {
+       wait_queue_head_t       wait;
+       bool                    bound;
+       bool                    cb_running;
++      int                     dump_done_errno;
+       struct netlink_callback cb;
+       struct mutex            *cb_mutex;
+       struct mutex            cb_def_mutex;
diff --git a/queue-4.14/bio-ensure-__bio_clone_fast-copies-bi_partno.patch b/queue-4.14/bio-ensure-__bio_clone_fast-copies-bi_partno.patch
new file mode 100644 (file)
index 0000000..da88a71
--- /dev/null
@@ -0,0 +1,38 @@
+From 62530ed8b1d07a45dec94d46e521c0c6c2d476e6 Mon Sep 17 00:00:00 2001
+From: Michael Lyle <mlyle@lyle.org>
+Date: Thu, 16 Nov 2017 23:47:25 -0800
+Subject: bio: ensure __bio_clone_fast copies bi_partno
+
+From: Michael Lyle <mlyle@lyle.org>
+
+commit 62530ed8b1d07a45dec94d46e521c0c6c2d476e6 upstream.
+
+A new field was introduced in 74d46992e0d9, bi_partno, instead of using
+bdev->bd_contains and encoding the partition information in the bi_bdev
+field.  __bio_clone_fast was changed to copy the disk information, but
+not the partition information.  At minimum, this regressed bcache and
+caused data corruption.
+
+Signed-off-by: Michael Lyle <mlyle@lyle.org>
+Fixes: 74d46992e0d9 ("block: replace bi_bdev with a gendisk pointer and partitions index")
+Reported-by: Pavel Goran <via-bcache@pvgoran.name>
+Reported-by: Campbell Steven <casteven@gmail.com>
+Reviewed-by: Coly Li <colyli@suse.de>
+Reviewed-by: Ming Lei <ming.lei@redhat.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ block/bio.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/block/bio.c
++++ b/block/bio.c
+@@ -597,6 +597,7 @@ void __bio_clone_fast(struct bio *bio, s
+        * so we don't set nor calculate new physical/hw segment counts here
+        */
+       bio->bi_disk = bio_src->bi_disk;
++      bio->bi_partno = bio_src->bi_partno;
+       bio_set_flag(bio, BIO_CLONED);
+       bio->bi_opf = bio_src->bi_opf;
+       bio->bi_write_hint = bio_src->bi_write_hint;
diff --git a/queue-4.14/fealnx-fix-building-error-on-mips.patch b/queue-4.14/fealnx-fix-building-error-on-mips.patch
new file mode 100644 (file)
index 0000000..b89166d
--- /dev/null
@@ -0,0 +1,43 @@
+From foo@baz Tue Nov 21 13:07:02 CET 2017
+From: Huacai Chen <chenhc@lemote.com>
+Date: Thu, 16 Nov 2017 11:07:15 +0800
+Subject: fealnx: Fix building error on MIPS
+
+From: Huacai Chen <chenhc@lemote.com>
+
+
+[ Upstream commit cc54c1d32e6a4bb3f116721abf900513173e4d02 ]
+
+This patch try to fix the building error on MIPS. The reason is MIPS
+has already defined the LONG macro, which conflicts with the LONG enum
+in drivers/net/ethernet/fealnx.c.
+
+Signed-off-by: Huacai Chen <chenhc@lemote.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/fealnx.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/ethernet/fealnx.c
++++ b/drivers/net/ethernet/fealnx.c
+@@ -257,8 +257,8 @@ enum rx_desc_status_bits {
+       RXFSD = 0x00000800,     /* first descriptor */
+       RXLSD = 0x00000400,     /* last descriptor */
+       ErrorSummary = 0x80,    /* error summary */
+-      RUNT = 0x40,            /* runt packet received */
+-      LONG = 0x20,            /* long packet received */
++      RUNTPKT = 0x40,         /* runt packet received */
++      LONGPKT = 0x20,         /* long packet received */
+       FAE = 0x10,             /* frame align error */
+       CRC = 0x08,             /* crc error */
+       RXER = 0x04,            /* receive error */
+@@ -1632,7 +1632,7 @@ static int netdev_rx(struct net_device *
+                                              dev->name, rx_status);
+                               dev->stats.rx_errors++; /* end of a packet. */
+-                              if (rx_status & (LONG | RUNT))
++                              if (rx_status & (LONGPKT | RUNTPKT))
+                                       dev->stats.rx_length_errors++;
+                               if (rx_status & RXER)
+                                       dev->stats.rx_frame_errors++;
diff --git a/queue-4.14/net-cdc_ncm-getntbformat-endian-fix.patch b/queue-4.14/net-cdc_ncm-getntbformat-endian-fix.patch
new file mode 100644 (file)
index 0000000..c8a00dc
--- /dev/null
@@ -0,0 +1,50 @@
+From foo@baz Tue Nov 21 13:07:02 CET 2017
+From: Bjørn Mork <bjorn@mork.no>
+Date: Wed, 15 Nov 2017 09:35:02 +0100
+Subject: net: cdc_ncm: GetNtbFormat endian fix
+
+From: Bjørn Mork <bjorn@mork.no>
+
+
+[ Upstream commit 6314dab4b8fb8493d810e175cb340376052c69b6 ]
+
+The GetNtbFormat and SetNtbFormat requests operate on 16 bit little
+endian values. We get away with ignoring this most of the time, because
+we only care about USB_CDC_NCM_NTB16_FORMAT which is 0x0000.  This
+fails for USB_CDC_NCM_NTB32_FORMAT.
+
+Fix comparison between LE value from device and constant by converting
+the constant to LE.
+
+Reported-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Fixes: 2b02c20ce0c2 ("cdc_ncm: Set NTB format again after altsetting switch for Huawei devices")
+Cc: Enrico Mioso <mrkiko.rs@gmail.com>
+Cc: Christian Panton <christian@panton.org>
+Signed-off-by: Bjørn Mork <bjorn@mork.no>
+Acked-By: Enrico Mioso <mrkiko.rs@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/cdc_ncm.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/usb/cdc_ncm.c
++++ b/drivers/net/usb/cdc_ncm.c
+@@ -771,7 +771,7 @@ int cdc_ncm_bind_common(struct usbnet *d
+       int err;
+       u8 iface_no;
+       struct usb_cdc_parsed_header hdr;
+-      u16 curr_ntb_format;
++      __le16 curr_ntb_format;
+       ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+       if (!ctx)
+@@ -889,7 +889,7 @@ int cdc_ncm_bind_common(struct usbnet *d
+                       goto error2;
+               }
+-              if (curr_ntb_format == USB_CDC_NCM_NTB32_FORMAT) {
++              if (curr_ntb_format == cpu_to_le16(USB_CDC_NCM_NTB32_FORMAT)) {
+                       dev_info(&intf->dev, "resetting NTB format to 16-bit");
+                       err = usbnet_write_cmd(dev, USB_CDC_SET_NTB_FORMAT,
+                                              USB_TYPE_CLASS | USB_DIR_OUT
diff --git a/queue-4.14/net-sctp-always-set-scope_id-in-sctp_inet6_skb_msgname.patch b/queue-4.14/net-sctp-always-set-scope_id-in-sctp_inet6_skb_msgname.patch
new file mode 100644 (file)
index 0000000..19f70e3
--- /dev/null
@@ -0,0 +1,57 @@
+From foo@baz Tue Nov 21 13:07:02 CET 2017
+From: "Eric W. Biederman" <ebiederm@xmission.com>
+Date: Wed, 15 Nov 2017 22:17:48 -0600
+Subject: net/sctp: Always set scope_id in sctp_inet6_skb_msgname
+
+From: "Eric W. Biederman" <ebiederm@xmission.com>
+
+
+[ Upstream commit 7c8a61d9ee1df0fb4747879fa67a99614eb62fec ]
+
+Alexandar Potapenko while testing the kernel with KMSAN and syzkaller
+discovered that in some configurations sctp would leak 4 bytes of
+kernel stack.
+
+Working with his reproducer I discovered that those 4 bytes that
+are leaked is the scope id of an ipv6 address returned by recvmsg.
+
+With a little code inspection and a shrewd guess I discovered that
+sctp_inet6_skb_msgname only initializes the scope_id field for link
+local ipv6 addresses to the interface index the link local address
+pertains to instead of initializing the scope_id field for all ipv6
+addresses.
+
+That is almost reasonable as scope_id's are meaniningful only for link
+local addresses.  Set the scope_id in all other cases to 0 which is
+not a valid interface index to make it clear there is nothing useful
+in the scope_id field.
+
+There should be no danger of breaking userspace as the stack leak
+guaranteed that previously meaningless random data was being returned.
+
+Fixes: 372f525b495c ("SCTP:  Resync with LKSCTP tree.")
+History-tree: https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git
+Reported-by: Alexander Potapenko <glider@google.com>
+Tested-by: Alexander Potapenko <glider@google.com>
+Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sctp/ipv6.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/net/sctp/ipv6.c
++++ b/net/sctp/ipv6.c
+@@ -807,9 +807,10 @@ static void sctp_inet6_skb_msgname(struc
+               addr->v6.sin6_flowinfo = 0;
+               addr->v6.sin6_port = sh->source;
+               addr->v6.sin6_addr = ipv6_hdr(skb)->saddr;
+-              if (ipv6_addr_type(&addr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) {
++              if (ipv6_addr_type(&addr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL)
+                       addr->v6.sin6_scope_id = sctp_v6_skb_iif(skb);
+-              }
++              else
++                      addr->v6.sin6_scope_id = 0;
+       }
+       *addr_len = sctp_v6_addr_to_user(sctp_sk(skb->sk), addr);
diff --git a/queue-4.14/vxlan-fix-the-issue-that-neigh-proxy-blocks-all-icmpv6-packets.patch b/queue-4.14/vxlan-fix-the-issue-that-neigh-proxy-blocks-all-icmpv6-packets.patch
new file mode 100644 (file)
index 0000000..12b3c9c
--- /dev/null
@@ -0,0 +1,97 @@
+From foo@baz Tue Nov 21 13:07:02 CET 2017
+From: Xin Long <lucien.xin@gmail.com>
+Date: Sat, 11 Nov 2017 19:58:50 +0800
+Subject: vxlan: fix the issue that neigh proxy blocks all icmpv6 packets
+
+From: Xin Long <lucien.xin@gmail.com>
+
+
+[ Upstream commit 8bff3685a4bbf175a96bc6a528f13455d8d38244 ]
+
+Commit f1fb08f6337c ("vxlan: fix ND proxy when skb doesn't have transport
+header offset") removed icmp6_code and icmp6_type check before calling
+neigh_reduce when doing neigh proxy.
+
+It means all icmpv6 packets would be blocked by this, not only ns packet.
+In Jianlin's env, even ping6 couldn't work through it.
+
+This patch is to bring the icmp6_code and icmp6_type check back and also
+removed the same check from neigh_reduce().
+
+Fixes: f1fb08f6337c ("vxlan: fix ND proxy when skb doesn't have transport header offset")
+Reported-by: Jianlin Shi <jishi@redhat.com>
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Reviewed-by: Vincent Bernat <vincent@bernat.im>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/vxlan.c |   31 +++++++++++++------------------
+ 1 file changed, 13 insertions(+), 18 deletions(-)
+
+--- a/drivers/net/vxlan.c
++++ b/drivers/net/vxlan.c
+@@ -1623,26 +1623,19 @@ static struct sk_buff *vxlan_na_create(s
+ static int neigh_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni)
+ {
+       struct vxlan_dev *vxlan = netdev_priv(dev);
+-      struct nd_msg *msg;
+-      const struct ipv6hdr *iphdr;
+       const struct in6_addr *daddr;
+-      struct neighbour *n;
++      const struct ipv6hdr *iphdr;
+       struct inet6_dev *in6_dev;
++      struct neighbour *n;
++      struct nd_msg *msg;
+       in6_dev = __in6_dev_get(dev);
+       if (!in6_dev)
+               goto out;
+-      if (!pskb_may_pull(skb, sizeof(struct ipv6hdr) + sizeof(struct nd_msg)))
+-              goto out;
+-
+       iphdr = ipv6_hdr(skb);
+       daddr = &iphdr->daddr;
+-
+       msg = (struct nd_msg *)(iphdr + 1);
+-      if (msg->icmph.icmp6_code != 0 ||
+-          msg->icmph.icmp6_type != NDISC_NEIGHBOUR_SOLICITATION)
+-              goto out;
+       if (ipv6_addr_loopback(daddr) ||
+           ipv6_addr_is_multicast(&msg->target))
+@@ -2240,11 +2233,11 @@ tx_error:
+ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
+ {
+       struct vxlan_dev *vxlan = netdev_priv(dev);
++      struct vxlan_rdst *rdst, *fdst = NULL;
+       const struct ip_tunnel_info *info;
+-      struct ethhdr *eth;
+       bool did_rsc = false;
+-      struct vxlan_rdst *rdst, *fdst = NULL;
+       struct vxlan_fdb *f;
++      struct ethhdr *eth;
+       __be32 vni = 0;
+       info = skb_tunnel_info(skb);
+@@ -2269,12 +2262,14 @@ static netdev_tx_t vxlan_xmit(struct sk_
+               if (ntohs(eth->h_proto) == ETH_P_ARP)
+                       return arp_reduce(dev, skb, vni);
+ #if IS_ENABLED(CONFIG_IPV6)
+-              else if (ntohs(eth->h_proto) == ETH_P_IPV6) {
+-                      struct ipv6hdr *hdr, _hdr;
+-                      if ((hdr = skb_header_pointer(skb,
+-                                                    skb_network_offset(skb),
+-                                                    sizeof(_hdr), &_hdr)) &&
+-                          hdr->nexthdr == IPPROTO_ICMPV6)
++              else if (ntohs(eth->h_proto) == ETH_P_IPV6 &&
++                       pskb_may_pull(skb, sizeof(struct ipv6hdr) +
++                                          sizeof(struct nd_msg)) &&
++                       ipv6_hdr(skb)->nexthdr == IPPROTO_ICMPV6) {
++                      struct nd_msg *m = (struct nd_msg *)(ipv6_hdr(skb) + 1);
++
++                      if (m->icmph.icmp6_code == 0 &&
++                          m->icmph.icmp6_type == NDISC_NEIGHBOUR_SOLICITATION)
+                               return neigh_reduce(dev, skb, vni);
+               }
+ #endif