]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
patches for 4.14
authorSasha Levin <sashal@kernel.org>
Thu, 21 Feb 2019 05:43:04 +0000 (00:43 -0500)
committerSasha Levin <sashal@kernel.org>
Thu, 21 Feb 2019 05:43:04 +0000 (00:43 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-4.14/dsa-mv88e6xxx-ensure-all-pending-interrupts-are-hand.patch [new file with mode: 0644]
queue-4.14/hwmon-lm80-fix-missing-unlock-on-error-in-set_fan_di.patch [new file with mode: 0644]
queue-4.14/net-fix-ipv6-prefix-route-residue.patch [new file with mode: 0644]
queue-4.14/net-ipv4-use-a-dedicated-counter-for-icmp_v4-redirec.patch [new file with mode: 0644]
queue-4.14/series [new file with mode: 0644]
queue-4.14/vsock-cope-with-memory-allocation-failure-at-socket-.patch [new file with mode: 0644]
queue-4.14/vxlan-test-dev-flags-iff_up-before-calling-netif_rx.patch [new file with mode: 0644]

diff --git a/queue-4.14/dsa-mv88e6xxx-ensure-all-pending-interrupts-are-hand.patch b/queue-4.14/dsa-mv88e6xxx-ensure-all-pending-interrupts-are-hand.patch
new file mode 100644 (file)
index 0000000..245b4d1
--- /dev/null
@@ -0,0 +1,92 @@
+From 2cf4f70c3353918d477db6c2a2f90db4bb8c2548 Mon Sep 17 00:00:00 2001
+From: John David Anglin <dave.anglin@bell.net>
+Date: Mon, 11 Feb 2019 13:40:21 -0500
+Subject: dsa: mv88e6xxx: Ensure all pending interrupts are handled prior to
+ exit
+
+[ Upstream commit 7c0db24cc431e2196d98a5d5ddaa9088e2fcbfe5 ]
+
+The GPIO interrupt controller on the espressobin board only supports edge interrupts.
+If one enables the use of hardware interrupts in the device tree for the 88E6341, it is
+possible to miss an edge.  When this happens, the INTn pin on the Marvell switch is
+stuck low and no further interrupts occur.
+
+I found after adding debug statements to mv88e6xxx_g1_irq_thread_work() that there is
+a race in handling device interrupts (e.g. PHY link interrupts).  Some interrupts are
+directly cleared by reading the Global 1 status register.  However, the device interrupt
+flag, for example, is not cleared until all the unmasked SERDES and PHY ports are serviced.
+This is done by reading the relevant SERDES and PHY status register.
+
+The code only services interrupts whose status bit is set at the time of reading its status
+register.  If an interrupt event occurs after its status is read and before all interrupts
+are serviced, then this event will not be serviced and the INTn output pin will remain low.
+
+This is not a problem with polling or level interrupts since the handler will be called
+again to process the event.  However, it's a big problem when using level interrupts.
+
+The fix presented here is to add a loop around the code servicing switch interrupts.  If
+any pending interrupts remain after the current set has been handled, we loop and process
+the new set.  If there are no pending interrupts after servicing, we are sure that INTn has
+gone high and we will get an edge when a new event occurs.
+
+Tested on espressobin board.
+
+Fixes: dc30c35be720 ("net: dsa: mv88e6xxx: Implement interrupt support.")
+Signed-off-by:  John David Anglin <dave.anglin@bell.net>
+Tested-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/mv88e6xxx/chip.c | 28 ++++++++++++++++++++++------
+ 1 file changed, 22 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
+index 34998ecd9cc93..a3543d637736c 100644
+--- a/drivers/net/dsa/mv88e6xxx/chip.c
++++ b/drivers/net/dsa/mv88e6xxx/chip.c
+@@ -258,6 +258,7 @@ static irqreturn_t mv88e6xxx_g1_irq_thread_fn(int irq, void *dev_id)
+       unsigned int sub_irq;
+       unsigned int n;
+       u16 reg;
++      u16 ctl1;
+       int err;
+       mutex_lock(&chip->reg_lock);
+@@ -267,13 +268,28 @@ static irqreturn_t mv88e6xxx_g1_irq_thread_fn(int irq, void *dev_id)
+       if (err)
+               goto out;
+-      for (n = 0; n < chip->g1_irq.nirqs; ++n) {
+-              if (reg & (1 << n)) {
+-                      sub_irq = irq_find_mapping(chip->g1_irq.domain, n);
+-                      handle_nested_irq(sub_irq);
+-                      ++nhandled;
++      do {
++              for (n = 0; n < chip->g1_irq.nirqs; ++n) {
++                      if (reg & (1 << n)) {
++                              sub_irq = irq_find_mapping(chip->g1_irq.domain,
++                                                         n);
++                              handle_nested_irq(sub_irq);
++                              ++nhandled;
++                      }
+               }
+-      }
++
++              mutex_lock(&chip->reg_lock);
++              err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &ctl1);
++              if (err)
++                      goto unlock;
++              err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &reg);
++unlock:
++              mutex_unlock(&chip->reg_lock);
++              if (err)
++                      goto out;
++              ctl1 &= GENMASK(chip->g1_irq.nirqs, 0);
++      } while (reg & ctl1);
++
+ out:
+       return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE);
+ }
+-- 
+2.19.1
+
diff --git a/queue-4.14/hwmon-lm80-fix-missing-unlock-on-error-in-set_fan_di.patch b/queue-4.14/hwmon-lm80-fix-missing-unlock-on-error-in-set_fan_di.patch
new file mode 100644 (file)
index 0000000..56ea6f7
--- /dev/null
@@ -0,0 +1,37 @@
+From 06c0dde175a2b64a42db500f2d9b980bb11a56a5 Mon Sep 17 00:00:00 2001
+From: Wei Yongjun <weiyongjun1@huawei.com>
+Date: Wed, 26 Dec 2018 11:28:24 +0000
+Subject: hwmon: (lm80) Fix missing unlock on error in set_fan_div()
+
+[ Upstream commit 07bd14ccc3049f9c0147a91a4227a571f981601a ]
+
+Add the missing unlock before return from function set_fan_div()
+in the error handling case.
+
+Fixes: c9c63915519b ("hwmon: (lm80) fix a missing check of the status of SMBus read")
+Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/lm80.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/hwmon/lm80.c b/drivers/hwmon/lm80.c
+index 0e30fa00204cd..f9b8e3e23a8e8 100644
+--- a/drivers/hwmon/lm80.c
++++ b/drivers/hwmon/lm80.c
+@@ -393,8 +393,10 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
+       }
+       rv = lm80_read_value(client, LM80_REG_FANDIV);
+-      if (rv < 0)
++      if (rv < 0) {
++              mutex_unlock(&data->update_lock);
+               return rv;
++      }
+       reg = (rv & ~(3 << (2 * (nr + 1))))
+           | (data->fan_div[nr] << (2 * (nr + 1)));
+       lm80_write_value(client, LM80_REG_FANDIV, reg);
+-- 
+2.19.1
+
diff --git a/queue-4.14/net-fix-ipv6-prefix-route-residue.patch b/queue-4.14/net-fix-ipv6-prefix-route-residue.patch
new file mode 100644 (file)
index 0000000..721a9c4
--- /dev/null
@@ -0,0 +1,49 @@
+From 61922e35284017ede2e0b4c50e63296289e10f2f Mon Sep 17 00:00:00 2001
+From: Zhiqiang Liu <liuzhiqiang26@huawei.com>
+Date: Mon, 11 Feb 2019 10:57:46 +0800
+Subject: net: fix IPv6 prefix route residue
+
+[ Upstream commit e75913c93f7cd5f338ab373c34c93a655bd309cb ]
+
+Follow those steps:
+ # ip addr add 2001:123::1/32 dev eth0
+ # ip addr add 2001:123:456::2/64 dev eth0
+ # ip addr del 2001:123::1/32 dev eth0
+ # ip addr del 2001:123:456::2/64 dev eth0
+and then prefix route of 2001:123::1/32 will still exist.
+
+This is because ipv6_prefix_equal in check_cleanup_prefix_route
+func does not check whether two IPv6 addresses have the same
+prefix length. If the prefix of one address starts with another
+shorter address prefix, even though their prefix lengths are
+different, the return value of ipv6_prefix_equal is true.
+
+Here I add a check of whether two addresses have the same prefix
+to decide whether their prefixes are equal.
+
+Fixes: 5b84efecb7d9 ("ipv6 addrconf: don't cleanup prefix route for IFA_F_NOPREFIXROUTE")
+Signed-off-by: Zhiqiang Liu <liuzhiqiang26@huawei.com>
+Reported-by: Wenhao Zhang <zhangwenhao8@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/addrconf.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
+index 9ac6f62322946..c47161e92407b 100644
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -1124,7 +1124,8 @@ check_cleanup_prefix_route(struct inet6_ifaddr *ifp, unsigned long *expires)
+       list_for_each_entry(ifa, &idev->addr_list, if_list) {
+               if (ifa == ifp)
+                       continue;
+-              if (!ipv6_prefix_equal(&ifa->addr, &ifp->addr,
++              if (ifa->prefix_len != ifp->prefix_len ||
++                  !ipv6_prefix_equal(&ifa->addr, &ifp->addr,
+                                      ifp->prefix_len))
+                       continue;
+               if (ifa->flags & (IFA_F_PERMANENT | IFA_F_NOPREFIXROUTE))
+-- 
+2.19.1
+
diff --git a/queue-4.14/net-ipv4-use-a-dedicated-counter-for-icmp_v4-redirec.patch b/queue-4.14/net-ipv4-use-a-dedicated-counter-for-icmp_v4-redirec.patch
new file mode 100644 (file)
index 0000000..7474d99
--- /dev/null
@@ -0,0 +1,93 @@
+From 44e2244ec6bb932ee5b3bf6e6e8f3504a26910c3 Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
+Date: Wed, 6 Feb 2019 19:18:04 +0100
+Subject: net: ipv4: use a dedicated counter for icmp_v4 redirect packets
+
+[ Upstream commit c09551c6ff7fe16a79a42133bcecba5fc2fc3291 ]
+
+According to the algorithm described in the comment block at the
+beginning of ip_rt_send_redirect, the host should try to send
+'ip_rt_redirect_number' ICMP redirect packets with an exponential
+backoff and then stop sending them at all assuming that the destination
+ignores redirects.
+If the device has previously sent some ICMP error packets that are
+rate-limited (e.g TTL expired) and continues to receive traffic,
+the redirect packets will never be transmitted. This happens since
+peer->rate_tokens will be typically greater than 'ip_rt_redirect_number'
+and so it will never be reset even if the redirect silence timeout
+(ip_rt_redirect_silence) has elapsed without receiving any packet
+requiring redirects.
+
+Fix it by using a dedicated counter for the number of ICMP redirect
+packets that has been sent by the host
+
+I have not been able to identify a given commit that introduced the
+issue since ip_rt_send_redirect implements the same rate-limiting
+algorithm from commit 1da177e4c3f4 ("Linux-2.6.12-rc2")
+
+Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/inetpeer.h | 1 +
+ net/ipv4/inetpeer.c    | 1 +
+ net/ipv4/route.c       | 7 +++++--
+ 3 files changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h
+index 00b5e7825508a..74ff688568a0c 100644
+--- a/include/net/inetpeer.h
++++ b/include/net/inetpeer.h
+@@ -39,6 +39,7 @@ struct inet_peer {
+       u32                     metrics[RTAX_MAX];
+       u32                     rate_tokens;    /* rate limiting for ICMP */
++      u32                     n_redirects;
+       unsigned long           rate_last;
+       /*
+        * Once inet_peer is queued for deletion (refcnt == 0), following field
+diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
+index 64007ce87273e..f9cef27907ed4 100644
+--- a/net/ipv4/inetpeer.c
++++ b/net/ipv4/inetpeer.c
+@@ -215,6 +215,7 @@ struct inet_peer *inet_getpeer(struct inet_peer_base *base,
+                       atomic_set(&p->rid, 0);
+                       p->metrics[RTAX_LOCK-1] = INETPEER_METRICS_NEW;
+                       p->rate_tokens = 0;
++                      p->n_redirects = 0;
+                       /* 60*HZ is arbitrary, but chosen enough high so that the first
+                        * calculation of tokens is at its maximum.
+                        */
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index 7afa8d2463d85..cb30f4e4e5533 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -904,13 +904,15 @@ void ip_rt_send_redirect(struct sk_buff *skb)
+       /* No redirected packets during ip_rt_redirect_silence;
+        * reset the algorithm.
+        */
+-      if (time_after(jiffies, peer->rate_last + ip_rt_redirect_silence))
++      if (time_after(jiffies, peer->rate_last + ip_rt_redirect_silence)) {
+               peer->rate_tokens = 0;
++              peer->n_redirects = 0;
++      }
+       /* Too many ignored redirects; do not send anything
+        * set dst.rate_last to the last seen redirected packet.
+        */
+-      if (peer->rate_tokens >= ip_rt_redirect_number) {
++      if (peer->n_redirects >= ip_rt_redirect_number) {
+               peer->rate_last = jiffies;
+               goto out_put_peer;
+       }
+@@ -927,6 +929,7 @@ void ip_rt_send_redirect(struct sk_buff *skb)
+               icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, gw);
+               peer->rate_last = jiffies;
+               ++peer->rate_tokens;
++              ++peer->n_redirects;
+ #ifdef CONFIG_IP_ROUTE_VERBOSE
+               if (log_martians &&
+                   peer->rate_tokens == ip_rt_redirect_number)
+-- 
+2.19.1
+
diff --git a/queue-4.14/series b/queue-4.14/series
new file mode 100644 (file)
index 0000000..21a0d8b
--- /dev/null
@@ -0,0 +1,6 @@
+dsa-mv88e6xxx-ensure-all-pending-interrupts-are-hand.patch
+net-fix-ipv6-prefix-route-residue.patch
+net-ipv4-use-a-dedicated-counter-for-icmp_v4-redirec.patch
+vsock-cope-with-memory-allocation-failure-at-socket-.patch
+vxlan-test-dev-flags-iff_up-before-calling-netif_rx.patch
+hwmon-lm80-fix-missing-unlock-on-error-in-set_fan_di.patch
diff --git a/queue-4.14/vsock-cope-with-memory-allocation-failure-at-socket-.patch b/queue-4.14/vsock-cope-with-memory-allocation-failure-at-socket-.patch
new file mode 100644 (file)
index 0000000..2220abc
--- /dev/null
@@ -0,0 +1,43 @@
+From c082e91d6db7880f59feee6e812fce40495345fe Mon Sep 17 00:00:00 2001
+From: Paolo Abeni <pabeni@redhat.com>
+Date: Thu, 7 Feb 2019 14:13:18 +0100
+Subject: vsock: cope with memory allocation failure at socket creation time
+
+[ Upstream commit 225d9464268599a5b4d094d02ec17808e44c7553 ]
+
+In the unlikely event that the kmalloc call in vmci_transport_socket_init()
+fails, we end-up calling vmci_transport_destruct() with a NULL vmci_trans()
+and oopsing.
+
+This change addresses the above explicitly checking for zero vmci_trans()
+at destruction time.
+
+Reported-by: Xiumei Mu <xmu@redhat.com>
+Fixes: d021c344051a ("VSOCK: Introduce VM Sockets")
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
+Reviewed-by: Jorgen Hansen <jhansen@vmware.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/vmw_vsock/vmci_transport.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c
+index bf7c516444467..ad3f47a714f36 100644
+--- a/net/vmw_vsock/vmci_transport.c
++++ b/net/vmw_vsock/vmci_transport.c
+@@ -1648,6 +1648,10 @@ static void vmci_transport_cleanup(struct work_struct *work)
+ static void vmci_transport_destruct(struct vsock_sock *vsk)
+ {
++      /* transport can be NULL if we hit a failure at init() time */
++      if (!vmci_trans(vsk))
++              return;
++
+       /* Ensure that the detach callback doesn't use the sk/vsk
+        * we are about to destruct.
+        */
+-- 
+2.19.1
+
diff --git a/queue-4.14/vxlan-test-dev-flags-iff_up-before-calling-netif_rx.patch b/queue-4.14/vxlan-test-dev-flags-iff_up-before-calling-netif_rx.patch
new file mode 100644 (file)
index 0000000..83606e5
--- /dev/null
@@ -0,0 +1,86 @@
+From 4d9e6204e082a9002e072089d151a985551af0ec Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Thu, 7 Feb 2019 12:27:38 -0800
+Subject: vxlan: test dev->flags & IFF_UP before calling netif_rx()
+
+[ Upstream commit 4179cb5a4c924cd233eaadd081882425bc98f44e ]
+
+netif_rx() must be called under a strict contract.
+
+At device dismantle phase, core networking clears IFF_UP
+and flush_all_backlogs() is called after rcu grace period
+to make sure no incoming packet might be in a cpu backlog
+and still referencing the device.
+
+Most drivers call netif_rx() from their interrupt handler,
+and since the interrupts are disabled at device dismantle,
+netif_rx() does not have to check dev->flags & IFF_UP
+
+Virtual drivers do not have this guarantee, and must
+therefore make the check themselves.
+
+Otherwise we risk use-after-free and/or crashes.
+
+Note this patch also fixes a small issue that came
+with commit ce6502a8f957 ("vxlan: fix a use after free
+in vxlan_encap_bypass"), since the dev->stats.rx_dropped
+change was done on the wrong device.
+
+Fixes: d342894c5d2f ("vxlan: virtual extensible lan")
+Fixes: ce6502a8f957 ("vxlan: fix a use after free in vxlan_encap_bypass")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Petr Machata <petrm@mellanox.com>
+Cc: Ido Schimmel <idosch@mellanox.com>
+Cc: Roopa Prabhu <roopa@cumulusnetworks.com>
+Cc: Stefano Brivio <sbrivio@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/vxlan.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
+index 13d39a72fe0d0..a1b40b9c4906e 100644
+--- a/drivers/net/vxlan.c
++++ b/drivers/net/vxlan.c
+@@ -2002,7 +2002,7 @@ static void vxlan_encap_bypass(struct sk_buff *skb, struct vxlan_dev *src_vxlan,
+       struct pcpu_sw_netstats *tx_stats, *rx_stats;
+       union vxlan_addr loopback;
+       union vxlan_addr *remote_ip = &dst_vxlan->default_dst.remote_ip;
+-      struct net_device *dev = skb->dev;
++      struct net_device *dev;
+       int len = skb->len;
+       tx_stats = this_cpu_ptr(src_vxlan->dev->tstats);
+@@ -2022,9 +2022,15 @@ static void vxlan_encap_bypass(struct sk_buff *skb, struct vxlan_dev *src_vxlan,
+ #endif
+       }
++      rcu_read_lock();
++      dev = skb->dev;
++      if (unlikely(!(dev->flags & IFF_UP))) {
++              kfree_skb(skb);
++              goto drop;
++      }
++
+       if (dst_vxlan->cfg.flags & VXLAN_F_LEARN)
+-              vxlan_snoop(skb->dev, &loopback, eth_hdr(skb)->h_source, 0,
+-                          vni);
++              vxlan_snoop(dev, &loopback, eth_hdr(skb)->h_source, 0, vni);
+       u64_stats_update_begin(&tx_stats->syncp);
+       tx_stats->tx_packets++;
+@@ -2037,8 +2043,10 @@ static void vxlan_encap_bypass(struct sk_buff *skb, struct vxlan_dev *src_vxlan,
+               rx_stats->rx_bytes += len;
+               u64_stats_update_end(&rx_stats->syncp);
+       } else {
++drop:
+               dev->stats.rx_dropped++;
+       }
++      rcu_read_unlock();
+ }
+ static int encap_bypass_if_local(struct sk_buff *skb, struct net_device *dev,
+-- 
+2.19.1
+