]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 18 Jul 2017 08:33:58 +0000 (10:33 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 18 Jul 2017 08:33:58 +0000 (10:33 +0200)
added patches:
bpf-prevent-leaking-pointer-via-xadd-on-unpriviledged.patch
liquidio-fix-bug-in-soft-reset-failure-detection.patch
net-handle-napi_gro_free_stolen_head-case-also-in-napi_frags_finish.patch
net-mlx5-cancel-delayed-recovery-work-when-unloading-the-driver.patch
rocker-move-dereference-before-free.patch

queue-4.9/bpf-prevent-leaking-pointer-via-xadd-on-unpriviledged.patch [new file with mode: 0644]
queue-4.9/liquidio-fix-bug-in-soft-reset-failure-detection.patch [new file with mode: 0644]
queue-4.9/net-handle-napi_gro_free_stolen_head-case-also-in-napi_frags_finish.patch [new file with mode: 0644]
queue-4.9/net-mlx5-cancel-delayed-recovery-work-when-unloading-the-driver.patch [new file with mode: 0644]
queue-4.9/rocker-move-dereference-before-free.patch [new file with mode: 0644]
queue-4.9/series

diff --git a/queue-4.9/bpf-prevent-leaking-pointer-via-xadd-on-unpriviledged.patch b/queue-4.9/bpf-prevent-leaking-pointer-via-xadd-on-unpriviledged.patch
new file mode 100644 (file)
index 0000000..1147178
--- /dev/null
@@ -0,0 +1,80 @@
+From 6bdf6abc56b53103324dfd270a86580306e1a232 Mon Sep 17 00:00:00 2001
+From: Daniel Borkmann <daniel@iogearbox.net>
+Date: Thu, 29 Jun 2017 03:04:59 +0200
+Subject: bpf: prevent leaking pointer via xadd on unpriviledged
+
+From: Daniel Borkmann <daniel@iogearbox.net>
+
+commit 6bdf6abc56b53103324dfd270a86580306e1a232 upstream.
+
+Leaking kernel addresses on unpriviledged is generally disallowed,
+for example, verifier rejects the following:
+
+  0: (b7) r0 = 0
+  1: (18) r2 = 0xffff897e82304400
+  3: (7b) *(u64 *)(r1 +48) = r2
+  R2 leaks addr into ctx
+
+Doing pointer arithmetic on them is also forbidden, so that they
+don't turn into unknown value and then get leaked out. However,
+there's xadd as a special case, where we don't check the src reg
+for being a pointer register, e.g. the following will pass:
+
+  0: (b7) r0 = 0
+  1: (7b) *(u64 *)(r1 +48) = r0
+  2: (18) r2 = 0xffff897e82304400 ; map
+  4: (db) lock *(u64 *)(r1 +48) += r2
+  5: (95) exit
+
+We could store the pointer into skb->cb, loose the type context,
+and then read it out from there again to leak it eventually out
+of a map value. Or more easily in a different variant, too:
+
+   0: (bf) r6 = r1
+   1: (7a) *(u64 *)(r10 -8) = 0
+   2: (bf) r2 = r10
+   3: (07) r2 += -8
+   4: (18) r1 = 0x0
+   6: (85) call bpf_map_lookup_elem#1
+   7: (15) if r0 == 0x0 goto pc+3
+   R0=map_value(ks=8,vs=8,id=0),min_value=0,max_value=0 R6=ctx R10=fp
+   8: (b7) r3 = 0
+   9: (7b) *(u64 *)(r0 +0) = r3
+  10: (db) lock *(u64 *)(r0 +0) += r6
+  11: (b7) r0 = 0
+  12: (95) exit
+
+  from 7 to 11: R0=inv,min_value=0,max_value=0 R6=ctx R10=fp
+  11: (b7) r0 = 0
+  12: (95) exit
+
+Prevent this by checking xadd src reg for pointer types. Also
+add a couple of test cases related to this.
+
+Fixes: 1be7f75d1668 ("bpf: enable non-root eBPF programs")
+Fixes: 17a5267067f3 ("bpf: verifier (add verifier core)")
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Alexei Starovoitov <ast@kernel.org>
+Acked-by: Martin KaFai Lau <kafai@fb.com>
+Acked-by: Edward Cree <ecree@solarflare.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/bpf/verifier.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -885,6 +885,11 @@ static int check_xadd(struct bpf_verifie
+       if (err)
+               return err;
++      if (is_pointer_value(env, insn->src_reg)) {
++              verbose("R%d leaks addr into mem\n", insn->src_reg);
++              return -EACCES;
++      }
++
+       /* check whether atomic_add can read the memory */
+       err = check_mem_access(env, insn->dst_reg, insn->off,
+                              BPF_SIZE(insn->code), BPF_READ, -1);
diff --git a/queue-4.9/liquidio-fix-bug-in-soft-reset-failure-detection.patch b/queue-4.9/liquidio-fix-bug-in-soft-reset-failure-detection.patch
new file mode 100644 (file)
index 0000000..10e0050
--- /dev/null
@@ -0,0 +1,51 @@
+From 05a6b4cae8c0cc1680c9dd33a97a49a13c0f01bc Mon Sep 17 00:00:00 2001
+From: Derek Chickles <derek.chickles@cavium.com>
+Date: Wed, 5 Jul 2017 11:59:27 -0700
+Subject: liquidio: fix bug in soft reset failure detection
+
+From: Derek Chickles <derek.chickles@cavium.com>
+
+commit 05a6b4cae8c0cc1680c9dd33a97a49a13c0f01bc upstream.
+
+The code that detects a failed soft reset of Octeon is comparing the wrong
+value against the reset value of the Octeon SLI_SCRATCH_1 register,
+resulting in an inability to detect a soft reset failure.  Fix it by using
+the correct value in the comparison, which is any non-zero value.
+
+Fixes: f21fb3ed364b ("Add support of Cavium Liquidio ethernet adapters")
+Fixes: c0eab5b3580a ("liquidio: CN23XX firmware download")
+Signed-off-by: Derek Chickles <derek.chickles@cavium.com>
+Signed-off-by: Satanand Burla <satananda.burla@cavium.com>
+Signed-off-by: Raghu Vatsavayi <raghu.vatsavayi@cavium.com>
+Signed-off-by: Felix Manlunas <felix.manlunas@cavium.com>
+Reviewed-by: Leon Romanovsky <leonro@mellanox.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c |    2 +-
+ drivers/net/ethernet/cavium/liquidio/cn66xx_device.c    |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c
++++ b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c
+@@ -230,7 +230,7 @@ static int cn23xx_pf_soft_reset(struct o
+       /* Wait for 100ms as Octeon resets. */
+       mdelay(100);
+-      if (octeon_read_csr64(oct, CN23XX_SLI_SCRATCH1) == 0x1234ULL) {
++      if (octeon_read_csr64(oct, CN23XX_SLI_SCRATCH1)) {
+               dev_err(&oct->pci_dev->dev, "OCTEON[%d]: Soft reset failed\n",
+                       oct->octeon_id);
+               return 1;
+--- a/drivers/net/ethernet/cavium/liquidio/cn66xx_device.c
++++ b/drivers/net/ethernet/cavium/liquidio/cn66xx_device.c
+@@ -48,7 +48,7 @@ int lio_cn6xxx_soft_reset(struct octeon_
+       /* Wait for 10ms as Octeon resets. */
+       mdelay(100);
+-      if (octeon_read_csr64(oct, CN6XXX_SLI_SCRATCH1) == 0x1234ULL) {
++      if (octeon_read_csr64(oct, CN6XXX_SLI_SCRATCH1)) {
+               dev_err(&oct->pci_dev->dev, "Soft reset failed\n");
+               return 1;
+       }
diff --git a/queue-4.9/net-handle-napi_gro_free_stolen_head-case-also-in-napi_frags_finish.patch b/queue-4.9/net-handle-napi_gro_free_stolen_head-case-also-in-napi_frags_finish.patch
new file mode 100644 (file)
index 0000000..34835e8
--- /dev/null
@@ -0,0 +1,85 @@
+From e44699d2c28067f69698ccb68dd3ddeacfebc434 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Michal=20Kube=C4=8Dek?= <mkubecek@suse.cz>
+Date: Thu, 29 Jun 2017 11:13:36 +0200
+Subject: net: handle NAPI_GRO_FREE_STOLEN_HEAD case also in napi_frags_finish()
+
+From: Michal Kubeček <mkubecek@suse.cz>
+
+commit e44699d2c28067f69698ccb68dd3ddeacfebc434 upstream.
+
+Recently I started seeing warnings about pages with refcount -1. The
+problem was traced to packets being reused after their head was merged into
+a GRO packet by skb_gro_receive(). While bisecting the issue pointed to
+commit c21b48cc1bbf ("net: adjust skb->truesize in ___pskb_trim()") and
+I have never seen it on a kernel with it reverted, I believe the real
+problem appeared earlier when the option to merge head frag in GRO was
+implemented.
+
+Handling NAPI_GRO_FREE_STOLEN_HEAD state was only added to GRO_MERGED_FREE
+branch of napi_skb_finish() so that if the driver uses napi_gro_frags()
+and head is merged (which in my case happens after the skb_condense()
+call added by the commit mentioned above), the skb is reused including the
+head that has been merged. As a result, we release the page reference
+twice and eventually end up with negative page refcount.
+
+To fix the problem, handle NAPI_GRO_FREE_STOLEN_HEAD in napi_frags_finish()
+the same way it's done in napi_skb_finish().
+
+Fixes: d7e8883cfcf4 ("net: make GRO aware of skb->head_frag")
+Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/core/dev.c |   22 ++++++++++++++++------
+ 1 file changed, 16 insertions(+), 6 deletions(-)
+
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -4641,6 +4641,12 @@ struct packet_offload *gro_find_complete
+ }
+ EXPORT_SYMBOL(gro_find_complete_by_type);
++static void napi_skb_free_stolen_head(struct sk_buff *skb)
++{
++      skb_dst_drop(skb);
++      kmem_cache_free(skbuff_head_cache, skb);
++}
++
+ static gro_result_t napi_skb_finish(gro_result_t ret, struct sk_buff *skb)
+ {
+       switch (ret) {
+@@ -4654,12 +4660,10 @@ static gro_result_t napi_skb_finish(gro_
+               break;
+       case GRO_MERGED_FREE:
+-              if (NAPI_GRO_CB(skb)->free == NAPI_GRO_FREE_STOLEN_HEAD) {
+-                      skb_dst_drop(skb);
+-                      kmem_cache_free(skbuff_head_cache, skb);
+-              } else {
++              if (NAPI_GRO_CB(skb)->free == NAPI_GRO_FREE_STOLEN_HEAD)
++                      napi_skb_free_stolen_head(skb);
++              else
+                       __kfree_skb(skb);
+-              }
+               break;
+       case GRO_HELD:
+@@ -4729,10 +4733,16 @@ static gro_result_t napi_frags_finish(st
+               break;
+       case GRO_DROP:
+-      case GRO_MERGED_FREE:
+               napi_reuse_skb(napi, skb);
+               break;
++      case GRO_MERGED_FREE:
++              if (NAPI_GRO_CB(skb)->free == NAPI_GRO_FREE_STOLEN_HEAD)
++                      napi_skb_free_stolen_head(skb);
++              else
++                      napi_reuse_skb(napi, skb);
++              break;
++
+       case GRO_MERGED:
+               break;
+       }
diff --git a/queue-4.9/net-mlx5-cancel-delayed-recovery-work-when-unloading-the-driver.patch b/queue-4.9/net-mlx5-cancel-delayed-recovery-work-when-unloading-the-driver.patch
new file mode 100644 (file)
index 0000000..e1d4b29
--- /dev/null
@@ -0,0 +1,97 @@
+From 2a0165a034ac024b60cca49c61e46f4afa2e4d98 Mon Sep 17 00:00:00 2001
+From: Mohamad Haj Yahia <mohamad@mellanox.com>
+Date: Thu, 30 Mar 2017 17:09:00 +0300
+Subject: net/mlx5: Cancel delayed recovery work when unloading the driver
+
+From: Mohamad Haj Yahia <mohamad@mellanox.com>
+
+commit 2a0165a034ac024b60cca49c61e46f4afa2e4d98 upstream.
+
+Draining the health workqueue will ignore future health works including
+the one that report hardware failure and thus we can't enter error state
+Instead cancel the recovery flow and make sure only recovery flow won't
+be scheduled.
+
+Fixes: 5e44fca50470 ('net/mlx5: Only cancel recovery work when cleaning up device')
+Signed-off-by: Mohamad Haj Yahia <mohamad@mellanox.com>
+Signed-off-by: Moshe Shemesh <moshe@mellanox.com>
+Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/ethernet/mellanox/mlx5/core/health.c |   15 ++++++++++++++-
+ drivers/net/ethernet/mellanox/mlx5/core/main.c   |    2 +-
+ include/linux/mlx5/driver.h                      |    1 +
+ 3 files changed, 16 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/mellanox/mlx5/core/health.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/health.c
+@@ -67,6 +67,7 @@ enum {
+ enum {
+       MLX5_DROP_NEW_HEALTH_WORK,
++      MLX5_DROP_NEW_RECOVERY_WORK,
+ };
+ static u8 get_nic_state(struct mlx5_core_dev *dev)
+@@ -193,7 +194,7 @@ static void health_care(struct work_stru
+       mlx5_handle_bad_state(dev);
+       spin_lock(&health->wq_lock);
+-      if (!test_bit(MLX5_DROP_NEW_HEALTH_WORK, &health->flags))
++      if (!test_bit(MLX5_DROP_NEW_RECOVERY_WORK, &health->flags))
+               schedule_delayed_work(&health->recover_work, recover_delay);
+       else
+               dev_err(&dev->pdev->dev,
+@@ -328,6 +329,7 @@ void mlx5_start_health_poll(struct mlx5_
+       init_timer(&health->timer);
+       health->sick = 0;
+       clear_bit(MLX5_DROP_NEW_HEALTH_WORK, &health->flags);
++      clear_bit(MLX5_DROP_NEW_RECOVERY_WORK, &health->flags);
+       health->health = &dev->iseg->health;
+       health->health_counter = &dev->iseg->health_counter;
+@@ -350,11 +352,22 @@ void mlx5_drain_health_wq(struct mlx5_co
+       spin_lock(&health->wq_lock);
+       set_bit(MLX5_DROP_NEW_HEALTH_WORK, &health->flags);
++      set_bit(MLX5_DROP_NEW_RECOVERY_WORK, &health->flags);
+       spin_unlock(&health->wq_lock);
+       cancel_delayed_work_sync(&health->recover_work);
+       cancel_work_sync(&health->work);
+ }
++void mlx5_drain_health_recovery(struct mlx5_core_dev *dev)
++{
++      struct mlx5_core_health *health = &dev->priv.health;
++
++      spin_lock(&health->wq_lock);
++      set_bit(MLX5_DROP_NEW_RECOVERY_WORK, &health->flags);
++      spin_unlock(&health->wq_lock);
++      cancel_delayed_work_sync(&dev->priv.health.recover_work);
++}
++
+ void mlx5_health_cleanup(struct mlx5_core_dev *dev)
+ {
+       struct mlx5_core_health *health = &dev->priv.health;
+--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+@@ -1169,7 +1169,7 @@ static int mlx5_unload_one(struct mlx5_c
+       int err = 0;
+       if (cleanup)
+-              mlx5_drain_health_wq(dev);
++              mlx5_drain_health_recovery(dev);
+       mutex_lock(&dev->intf_state_mutex);
+       if (test_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state)) {
+--- a/include/linux/mlx5/driver.h
++++ b/include/linux/mlx5/driver.h
+@@ -788,6 +788,7 @@ int mlx5_health_init(struct mlx5_core_de
+ void mlx5_start_health_poll(struct mlx5_core_dev *dev);
+ void mlx5_stop_health_poll(struct mlx5_core_dev *dev);
+ void mlx5_drain_health_wq(struct mlx5_core_dev *dev);
++void mlx5_drain_health_recovery(struct mlx5_core_dev *dev);
+ int mlx5_buf_alloc_node(struct mlx5_core_dev *dev, int size,
+                       struct mlx5_buf *buf, int node);
+ int mlx5_buf_alloc(struct mlx5_core_dev *dev, int size, struct mlx5_buf *buf);
diff --git a/queue-4.9/rocker-move-dereference-before-free.patch b/queue-4.9/rocker-move-dereference-before-free.patch
new file mode 100644 (file)
index 0000000..781fc05
--- /dev/null
@@ -0,0 +1,33 @@
+From acb4b7df48b539cb391287921de57e4e5fae3460 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Wed, 28 Jun 2017 14:44:21 +0300
+Subject: rocker: move dereference before free
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+commit acb4b7df48b539cb391287921de57e4e5fae3460 upstream.
+
+My static checker complains that ofdpa_neigh_del() can sometimes free
+"found".   It just makes sense to use it first before deleting it.
+
+Fixes: ecf244f753e0 ("rocker: fix maybe-uninitialized warning")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/ethernet/rocker/rocker_ofdpa.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/rocker/rocker_ofdpa.c
++++ b/drivers/net/ethernet/rocker/rocker_ofdpa.c
+@@ -1505,8 +1505,8 @@ static int ofdpa_port_ipv4_nh(struct ofd
+               *index = entry->index;
+               resolved = false;
+       } else if (removing) {
+-              ofdpa_neigh_del(trans, found);
+               *index = found->index;
++              ofdpa_neigh_del(trans, found);
+       } else if (updating) {
+               ofdpa_neigh_update(found, trans, NULL, false);
+               resolved = !is_zero_ether_addr(found->eth_dst);
index 770727eb557196bca7c6d881e3971c2c80d191be..bf49ecaa937a648a63b97abf48a9808e84f98b3f 100644 (file)
@@ -7,3 +7,8 @@ net-dp83640-avoid-null-pointer-dereference.patch
 tcp-reset-sk_rx_dst-in-tcp_disconnect.patch
 net-prevent-sign-extension-in-dev_get_stats.patch
 bridge-mdb-fix-leak-on-complete_info-ptr-on-fail-path.patch
+rocker-move-dereference-before-free.patch
+bpf-prevent-leaking-pointer-via-xadd-on-unpriviledged.patch
+net-handle-napi_gro_free_stolen_head-case-also-in-napi_frags_finish.patch
+net-mlx5-cancel-delayed-recovery-work-when-unloading-the-driver.patch
+liquidio-fix-bug-in-soft-reset-failure-detection.patch