]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 11 Mar 2021 18:32:11 +0000 (19:32 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 11 Mar 2021 18:32:11 +0000 (19:32 +0100)
added patches:
can-flexcan-assert-frz-bit-in-flexcan_chip_freeze.patch
can-flexcan-enable-rx-fifo-after-frz-halt-valid.patch
can-flexcan-invoke-flexcan_chip_freeze-to-enter-freeze-mode.patch
can-skb-can_skb_set_owner-fix-ref-counting-if-socket-was-closed-before-setting-skb-ownership.patch
can-tcan4x5x-tcan4x5x_init-fix-initialization-clear-mram-before-entering-normal-mode.patch
gpiolib-acpi-allow-to-find-gpioint-resource-by-name-and-index.patch
gpiolib-read-gpio-line-names-from-a-firmware-node.patch
ibmvnic-always-store-valid-mac-address.patch
ibmvnic-fix-possibly-uninitialized-old_num_tx_queues-variable-warning.patch
libbpf-clear-map_info-before-each-bpf_obj_get_info_by_fd.patch
mt76-dma-do-not-report-truncated-frames-to-mac80211.patch
net-always-use-icmp-v6-_ndo_send-from-ndo_start_xmit.patch
net-l2tp-reduce-log-level-of-messages-in-receive-path-add-counter-instead.patch
net-phy-fix-save-wrong-speed-and-duplex-problem-if-autoneg-is-on.patch
netfilter-nf_nat-undo-erroneous-tcp-edemux-lookup.patch
netfilter-x_tables-gpf-inside-xt_find_revision.patch
samples-bpf-add-missing-munmap-in-xdpsock.patch
selftests-bpf-mask-bpf_csum_diff-return-value-to-16-bits-in-test_verifier.patch
selftests-bpf-no-need-to-drop-the-packet-when-there-is-no-geneve-opt.patch
selftests-bpf-use-the-last-page-in-test_snprintf_btf-on-s390.patch
tcp-add-sanity-tests-to-tcp_queue_seq.patch
tcp-fix-sign-comparison-bug-in-getsockopt-tcp_zerocopy_receive.patch

23 files changed:
queue-5.10/can-flexcan-assert-frz-bit-in-flexcan_chip_freeze.patch [new file with mode: 0644]
queue-5.10/can-flexcan-enable-rx-fifo-after-frz-halt-valid.patch [new file with mode: 0644]
queue-5.10/can-flexcan-invoke-flexcan_chip_freeze-to-enter-freeze-mode.patch [new file with mode: 0644]
queue-5.10/can-skb-can_skb_set_owner-fix-ref-counting-if-socket-was-closed-before-setting-skb-ownership.patch [new file with mode: 0644]
queue-5.10/can-tcan4x5x-tcan4x5x_init-fix-initialization-clear-mram-before-entering-normal-mode.patch [new file with mode: 0644]
queue-5.10/gpiolib-acpi-allow-to-find-gpioint-resource-by-name-and-index.patch [new file with mode: 0644]
queue-5.10/gpiolib-read-gpio-line-names-from-a-firmware-node.patch [new file with mode: 0644]
queue-5.10/ibmvnic-always-store-valid-mac-address.patch [new file with mode: 0644]
queue-5.10/ibmvnic-fix-possibly-uninitialized-old_num_tx_queues-variable-warning.patch [new file with mode: 0644]
queue-5.10/libbpf-clear-map_info-before-each-bpf_obj_get_info_by_fd.patch [new file with mode: 0644]
queue-5.10/mt76-dma-do-not-report-truncated-frames-to-mac80211.patch [new file with mode: 0644]
queue-5.10/net-always-use-icmp-v6-_ndo_send-from-ndo_start_xmit.patch [new file with mode: 0644]
queue-5.10/net-l2tp-reduce-log-level-of-messages-in-receive-path-add-counter-instead.patch [new file with mode: 0644]
queue-5.10/net-phy-fix-save-wrong-speed-and-duplex-problem-if-autoneg-is-on.patch [new file with mode: 0644]
queue-5.10/netfilter-nf_nat-undo-erroneous-tcp-edemux-lookup.patch [new file with mode: 0644]
queue-5.10/netfilter-x_tables-gpf-inside-xt_find_revision.patch [new file with mode: 0644]
queue-5.10/samples-bpf-add-missing-munmap-in-xdpsock.patch [new file with mode: 0644]
queue-5.10/selftests-bpf-mask-bpf_csum_diff-return-value-to-16-bits-in-test_verifier.patch [new file with mode: 0644]
queue-5.10/selftests-bpf-no-need-to-drop-the-packet-when-there-is-no-geneve-opt.patch [new file with mode: 0644]
queue-5.10/selftests-bpf-use-the-last-page-in-test_snprintf_btf-on-s390.patch [new file with mode: 0644]
queue-5.10/series
queue-5.10/tcp-add-sanity-tests-to-tcp_queue_seq.patch [new file with mode: 0644]
queue-5.10/tcp-fix-sign-comparison-bug-in-getsockopt-tcp_zerocopy_receive.patch [new file with mode: 0644]

diff --git a/queue-5.10/can-flexcan-assert-frz-bit-in-flexcan_chip_freeze.patch b/queue-5.10/can-flexcan-assert-frz-bit-in-flexcan_chip_freeze.patch
new file mode 100644 (file)
index 0000000..a0be943
--- /dev/null
@@ -0,0 +1,35 @@
+From 449052cfebf624b670faa040245d3feed770d22f Mon Sep 17 00:00:00 2001
+From: Joakim Zhang <qiangqing.zhang@nxp.com>
+Date: Thu, 18 Feb 2021 19:00:35 +0800
+Subject: can: flexcan: assert FRZ bit in flexcan_chip_freeze()
+
+From: Joakim Zhang <qiangqing.zhang@nxp.com>
+
+commit 449052cfebf624b670faa040245d3feed770d22f upstream.
+
+Assert HALT bit to enter freeze mode, there is a premise that FRZ bit is
+asserted. This patch asserts FRZ bit in flexcan_chip_freeze, although
+the reset value is 1b'1. This is a prepare patch, later patch will
+invoke flexcan_chip_freeze() to enter freeze mode, which polling freeze
+mode acknowledge.
+
+Fixes: b1aa1c7a2165b ("can: flexcan: fix transition from and to freeze mode in chip_{,un}freeze")
+Link: https://lore.kernel.org/r/20210218110037.16591-2-qiangqing.zhang@nxp.com
+Signed-off-by: Joakim Zhang <qiangqing.zhang@nxp.com>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/can/flexcan.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/can/flexcan.c
++++ b/drivers/net/can/flexcan.c
+@@ -662,7 +662,7 @@ static int flexcan_chip_freeze(struct fl
+       u32 reg;
+       reg = priv->read(&regs->mcr);
+-      reg |= FLEXCAN_MCR_HALT;
++      reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT;
+       priv->write(reg, &regs->mcr);
+       while (timeout-- && !(priv->read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
diff --git a/queue-5.10/can-flexcan-enable-rx-fifo-after-frz-halt-valid.patch b/queue-5.10/can-flexcan-enable-rx-fifo-after-frz-halt-valid.patch
new file mode 100644 (file)
index 0000000..84ffe84
--- /dev/null
@@ -0,0 +1,53 @@
+From ec15e27cc8904605846a354bb1f808ea1432f853 Mon Sep 17 00:00:00 2001
+From: Joakim Zhang <qiangqing.zhang@nxp.com>
+Date: Thu, 18 Feb 2021 19:00:36 +0800
+Subject: can: flexcan: enable RX FIFO after FRZ/HALT valid
+
+From: Joakim Zhang <qiangqing.zhang@nxp.com>
+
+commit ec15e27cc8904605846a354bb1f808ea1432f853 upstream.
+
+RX FIFO enable failed could happen when do system reboot stress test:
+
+[    0.303958] flexcan 5a8d0000.can: 5a8d0000.can supply xceiver not found, using dummy regulator
+[    0.304281] flexcan 5a8d0000.can (unnamed net_device) (uninitialized): Could not enable RX FIFO, unsupported core
+[    0.314640] flexcan 5a8d0000.can: registering netdev failed
+[    0.320728] flexcan 5a8e0000.can: 5a8e0000.can supply xceiver not found, using dummy regulator
+[    0.320991] flexcan 5a8e0000.can (unnamed net_device) (uninitialized): Could not enable RX FIFO, unsupported core
+[    0.331360] flexcan 5a8e0000.can: registering netdev failed
+[    0.337444] flexcan 5a8f0000.can: 5a8f0000.can supply xceiver not found, using dummy regulator
+[    0.337716] flexcan 5a8f0000.can (unnamed net_device) (uninitialized): Could not enable RX FIFO, unsupported core
+[    0.348117] flexcan 5a8f0000.can: registering netdev failed
+
+RX FIFO should be enabled after the FRZ/HALT are valid. But the current
+code enable RX FIFO and FRZ/HALT at the same time.
+
+Fixes: e955cead03117 ("CAN: Add Flexcan CAN controller driver")
+Link: https://lore.kernel.org/r/20210218110037.16591-3-qiangqing.zhang@nxp.com
+Signed-off-by: Joakim Zhang <qiangqing.zhang@nxp.com>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/can/flexcan.c |   10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/can/flexcan.c
++++ b/drivers/net/can/flexcan.c
+@@ -1800,10 +1800,14 @@ static int register_flexcandev(struct ne
+       if (err)
+               goto out_chip_disable;
+-      /* set freeze, halt and activate FIFO, restrict register access */
++      /* set freeze, halt */
++      err = flexcan_chip_freeze(priv);
++      if (err)
++              goto out_chip_disable;
++
++      /* activate FIFO, restrict register access */
+       reg = priv->read(&regs->mcr);
+-      reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT |
+-              FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV;
++      reg |=  FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV;
+       priv->write(reg, &regs->mcr);
+       /* Currently we only support newer versions of this core
diff --git a/queue-5.10/can-flexcan-invoke-flexcan_chip_freeze-to-enter-freeze-mode.patch b/queue-5.10/can-flexcan-invoke-flexcan_chip_freeze-to-enter-freeze-mode.patch
new file mode 100644 (file)
index 0000000..f0a9d64
--- /dev/null
@@ -0,0 +1,51 @@
+From c63820045e2000f05657467a08715c18c9f490d9 Mon Sep 17 00:00:00 2001
+From: Joakim Zhang <qiangqing.zhang@nxp.com>
+Date: Thu, 18 Feb 2021 19:00:37 +0800
+Subject: can: flexcan: invoke flexcan_chip_freeze() to enter freeze mode
+
+From: Joakim Zhang <qiangqing.zhang@nxp.com>
+
+commit c63820045e2000f05657467a08715c18c9f490d9 upstream.
+
+Invoke flexcan_chip_freeze() to enter freeze mode, since need poll
+freeze mode acknowledge.
+
+Fixes: e955cead03117 ("CAN: Add Flexcan CAN controller driver")
+Link: https://lore.kernel.org/r/20210218110037.16591-4-qiangqing.zhang@nxp.com
+Signed-off-by: Joakim Zhang <qiangqing.zhang@nxp.com>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/can/flexcan.c |   12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/can/flexcan.c
++++ b/drivers/net/can/flexcan.c
+@@ -1375,10 +1375,13 @@ static int flexcan_chip_start(struct net
+       flexcan_set_bittiming(dev);
++      /* set freeze, halt */
++      err = flexcan_chip_freeze(priv);
++      if (err)
++              goto out_chip_disable;
++
+       /* MCR
+        *
+-       * enable freeze
+-       * halt now
+        * only supervisor access
+        * enable warning int
+        * enable individual RX masking
+@@ -1387,9 +1390,8 @@ static int flexcan_chip_start(struct net
+        */
+       reg_mcr = priv->read(&regs->mcr);
+       reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff);
+-      reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV |
+-              FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_IRMQ | FLEXCAN_MCR_IDAM_C |
+-              FLEXCAN_MCR_MAXMB(priv->tx_mb_idx);
++      reg_mcr |= FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_IRMQ |
++              FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_MAXMB(priv->tx_mb_idx);
+       /* MCR
+        *
diff --git a/queue-5.10/can-skb-can_skb_set_owner-fix-ref-counting-if-socket-was-closed-before-setting-skb-ownership.patch b/queue-5.10/can-skb-can_skb_set_owner-fix-ref-counting-if-socket-was-closed-before-setting-skb-ownership.patch
new file mode 100644 (file)
index 0000000..aae1c9b
--- /dev/null
@@ -0,0 +1,71 @@
+From e940e0895a82c6fbaa259f2615eb52b57ee91a7e Mon Sep 17 00:00:00 2001
+From: Oleksij Rempel <o.rempel@pengutronix.de>
+Date: Fri, 26 Feb 2021 10:24:56 +0100
+Subject: can: skb: can_skb_set_owner(): fix ref counting if socket was closed before setting skb ownership
+
+From: Oleksij Rempel <o.rempel@pengutronix.de>
+
+commit e940e0895a82c6fbaa259f2615eb52b57ee91a7e upstream.
+
+There are two ref count variables controlling the free()ing of a socket:
+- struct sock::sk_refcnt - which is changed by sock_hold()/sock_put()
+- struct sock::sk_wmem_alloc - which accounts the memory allocated by
+  the skbs in the send path.
+
+In case there are still TX skbs on the fly and the socket() is closed,
+the struct sock::sk_refcnt reaches 0. In the TX-path the CAN stack
+clones an "echo" skb, calls sock_hold() on the original socket and
+references it. This produces the following back trace:
+
+| WARNING: CPU: 0 PID: 280 at lib/refcount.c:25 refcount_warn_saturate+0x114/0x134
+| refcount_t: addition on 0; use-after-free.
+| Modules linked in: coda_vpu(E) v4l2_jpeg(E) videobuf2_vmalloc(E) imx_vdoa(E)
+| CPU: 0 PID: 280 Comm: test_can.sh Tainted: G            E     5.11.0-04577-gf8ff6603c617 #203
+| Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
+| Backtrace:
+| [<80bafea4>] (dump_backtrace) from [<80bb0280>] (show_stack+0x20/0x24) r7:00000000 r6:600f0113 r5:00000000 r4:81441220
+| [<80bb0260>] (show_stack) from [<80bb593c>] (dump_stack+0xa0/0xc8)
+| [<80bb589c>] (dump_stack) from [<8012b268>] (__warn+0xd4/0x114) r9:00000019 r8:80f4a8c2 r7:83e4150c r6:00000000 r5:00000009 r4:80528f90
+| [<8012b194>] (__warn) from [<80bb09c4>] (warn_slowpath_fmt+0x88/0xc8) r9:83f26400 r8:80f4a8d1 r7:00000009 r6:80528f90 r5:00000019 r4:80f4a8c2
+| [<80bb0940>] (warn_slowpath_fmt) from [<80528f90>] (refcount_warn_saturate+0x114/0x134) r8:00000000 r7:00000000 r6:82b44000 r5:834e5600 r4:83f4d540
+| [<80528e7c>] (refcount_warn_saturate) from [<8079a4c8>] (__refcount_add.constprop.0+0x4c/0x50)
+| [<8079a47c>] (__refcount_add.constprop.0) from [<8079a57c>] (can_put_echo_skb+0xb0/0x13c)
+| [<8079a4cc>] (can_put_echo_skb) from [<8079ba98>] (flexcan_start_xmit+0x1c4/0x230) r9:00000010 r8:83f48610 r7:0fdc0000 r6:0c080000 r5:82b44000 r4:834e5600
+| [<8079b8d4>] (flexcan_start_xmit) from [<80969078>] (netdev_start_xmit+0x44/0x70) r9:814c0ba0 r8:80c8790c r7:00000000 r6:834e5600 r5:82b44000 r4:82ab1f00
+| [<80969034>] (netdev_start_xmit) from [<809725a4>] (dev_hard_start_xmit+0x19c/0x318) r9:814c0ba0 r8:00000000 r7:82ab1f00 r6:82b44000 r5:00000000 r4:834e5600
+| [<80972408>] (dev_hard_start_xmit) from [<809c6584>] (sch_direct_xmit+0xcc/0x264) r10:834e5600 r9:00000000 r8:00000000 r7:82b44000 r6:82ab1f00 r5:834e5600 r4:83f27400
+| [<809c64b8>] (sch_direct_xmit) from [<809c6c0c>] (__qdisc_run+0x4f0/0x534)
+
+To fix this problem, only set skb ownership to sockets which have still
+a ref count > 0.
+
+Fixes: 0ae89beb283a ("can: add destructor for self generated skbs")
+Cc: Oliver Hartkopp <socketcan@hartkopp.net>
+Cc: Andre Naujoks <nautsch2@gmail.com>
+Link: https://lore.kernel.org/r/20210226092456.27126-1-o.rempel@pengutronix.de
+Suggested-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Reviewed-by: Oliver Hartkopp <socketcan@hartkopp.net>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/can/skb.h |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/include/linux/can/skb.h
++++ b/include/linux/can/skb.h
+@@ -49,8 +49,12 @@ static inline void can_skb_reserve(struc
+ static inline void can_skb_set_owner(struct sk_buff *skb, struct sock *sk)
+ {
+-      if (sk) {
+-              sock_hold(sk);
++      /* If the socket has already been closed by user space, the
++       * refcount may already be 0 (and the socket will be freed
++       * after the last TX skb has been freed). So only increase
++       * socket refcount if the refcount is > 0.
++       */
++      if (sk && refcount_inc_not_zero(&sk->sk_refcnt)) {
+               skb->destructor = sock_efree;
+               skb->sk = sk;
+       }
diff --git a/queue-5.10/can-tcan4x5x-tcan4x5x_init-fix-initialization-clear-mram-before-entering-normal-mode.patch b/queue-5.10/can-tcan4x5x-tcan4x5x_init-fix-initialization-clear-mram-before-entering-normal-mode.patch
new file mode 100644 (file)
index 0000000..c6db0e0
--- /dev/null
@@ -0,0 +1,47 @@
+From 2712625200ed69c642b9abc3a403830c4643364c Mon Sep 17 00:00:00 2001
+From: Torin Cooper-Bennun <torin@maxiluxsystems.com>
+Date: Fri, 26 Feb 2021 16:34:41 +0000
+Subject: can: tcan4x5x: tcan4x5x_init(): fix initialization - clear MRAM before entering Normal Mode
+
+From: Torin Cooper-Bennun <torin@maxiluxsystems.com>
+
+commit 2712625200ed69c642b9abc3a403830c4643364c upstream.
+
+This patch prevents a potentially destructive race condition. The
+device is fully operational on the bus after entering Normal Mode, so
+zeroing the MRAM after entering this mode may lead to loss of
+information, e.g. new received messages.
+
+This patch fixes the problem by first initializing the MRAM, then
+bringing the device into Normale Mode.
+
+Fixes: 5443c226ba91 ("can: tcan4x5x: Add tcan4x5x driver to the kernel")
+Link: https://lore.kernel.org/r/20210226163440.313628-1-torin@maxiluxsystems.com
+Suggested-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Torin Cooper-Bennun <torin@maxiluxsystems.com>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/can/m_can/tcan4x5x.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/can/m_can/tcan4x5x.c
++++ b/drivers/net/can/m_can/tcan4x5x.c
+@@ -328,14 +328,14 @@ static int tcan4x5x_init(struct m_can_cl
+       if (ret)
+               return ret;
++      /* Zero out the MCAN buffers */
++      m_can_init_ram(cdev);
++
+       ret = regmap_update_bits(tcan4x5x->regmap, TCAN4X5X_CONFIG,
+                                TCAN4X5X_MODE_SEL_MASK, TCAN4X5X_MODE_NORMAL);
+       if (ret)
+               return ret;
+-      /* Zero out the MCAN buffers */
+-      m_can_init_ram(cdev);
+-
+       return ret;
+ }
diff --git a/queue-5.10/gpiolib-acpi-allow-to-find-gpioint-resource-by-name-and-index.patch b/queue-5.10/gpiolib-acpi-allow-to-find-gpioint-resource-by-name-and-index.patch
new file mode 100644 (file)
index 0000000..587fa41
--- /dev/null
@@ -0,0 +1,101 @@
+From 809390219fb9c2421239afe5c9eb862d73978ba0 Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Date: Thu, 25 Feb 2021 18:33:19 +0200
+Subject: gpiolib: acpi: Allow to find GpioInt() resource by name and index
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+commit 809390219fb9c2421239afe5c9eb862d73978ba0 upstream.
+
+Currently only search by index is supported. However, in some cases
+we might need to pass the quirks to the acpi_dev_gpio_irq_get().
+
+For this, split out acpi_dev_gpio_irq_get_by() and replace
+acpi_dev_gpio_irq_get() by calling above with NULL for name parameter.
+
+Fixes: ba8c90c61847 ("gpio: pca953x: Override IRQ for one of the expanders on Galileo Gen 2")
+Depends-on: 0ea683931adb ("gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Acked-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpio/gpiolib-acpi.c |   12 ++++++++----
+ include/linux/acpi.h        |   10 ++++++++--
+ 2 files changed, 16 insertions(+), 6 deletions(-)
+
+--- a/drivers/gpio/gpiolib-acpi.c
++++ b/drivers/gpio/gpiolib-acpi.c
+@@ -911,8 +911,9 @@ struct gpio_desc *acpi_node_get_gpiod(st
+ }
+ /**
+- * acpi_dev_gpio_irq_get() - Find GpioInt and translate it to Linux IRQ number
++ * acpi_dev_gpio_irq_get_by() - Find GpioInt and translate it to Linux IRQ number
+  * @adev: pointer to a ACPI device to get IRQ from
++ * @name: optional name of GpioInt resource
+  * @index: index of GpioInt resource (starting from %0)
+  *
+  * If the device has one or more GpioInt resources, this function can be
+@@ -922,9 +923,12 @@ struct gpio_desc *acpi_node_get_gpiod(st
+  * The function is idempotent, though each time it runs it will configure GPIO
+  * pin direction according to the flags in GpioInt resource.
+  *
++ * The function takes optional @name parameter. If the resource has a property
++ * name, then only those will be taken into account.
++ *
+  * Return: Linux IRQ number (> %0) on success, negative errno on failure.
+  */
+-int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index)
++int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, const char *name, int index)
+ {
+       int idx, i;
+       unsigned int irq_flags;
+@@ -934,7 +938,7 @@ int acpi_dev_gpio_irq_get(struct acpi_de
+               struct acpi_gpio_info info;
+               struct gpio_desc *desc;
+-              desc = acpi_get_gpiod_by_index(adev, NULL, i, &info);
++              desc = acpi_get_gpiod_by_index(adev, name, i, &info);
+               /* Ignore -EPROBE_DEFER, it only matters if idx matches */
+               if (IS_ERR(desc) && PTR_ERR(desc) != -EPROBE_DEFER)
+@@ -971,7 +975,7 @@ int acpi_dev_gpio_irq_get(struct acpi_de
+       }
+       return -ENOENT;
+ }
+-EXPORT_SYMBOL_GPL(acpi_dev_gpio_irq_get);
++EXPORT_SYMBOL_GPL(acpi_dev_gpio_irq_get_by);
+ static acpi_status
+ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address,
+--- a/include/linux/acpi.h
++++ b/include/linux/acpi.h
+@@ -1072,19 +1072,25 @@ void __acpi_handle_debug(struct _ddebug
+ #if defined(CONFIG_ACPI) && defined(CONFIG_GPIOLIB)
+ bool acpi_gpio_get_irq_resource(struct acpi_resource *ares,
+                               struct acpi_resource_gpio **agpio);
+-int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index);
++int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, const char *name, int index);
+ #else
+ static inline bool acpi_gpio_get_irq_resource(struct acpi_resource *ares,
+                                             struct acpi_resource_gpio **agpio)
+ {
+       return false;
+ }
+-static inline int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index)
++static inline int acpi_dev_gpio_irq_get_by(struct acpi_device *adev,
++                                         const char *name, int index)
+ {
+       return -ENXIO;
+ }
+ #endif
++static inline int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index)
++{
++      return acpi_dev_gpio_irq_get_by(adev, NULL, index);
++}
++
+ /* Device properties */
+ #ifdef CONFIG_ACPI
diff --git a/queue-5.10/gpiolib-read-gpio-line-names-from-a-firmware-node.patch b/queue-5.10/gpiolib-read-gpio-line-names-from-a-firmware-node.patch
new file mode 100644 (file)
index 0000000..4b82110
--- /dev/null
@@ -0,0 +1,77 @@
+From b41ba2ec54a70908067034f139aa23d0dd2985ce Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Date: Fri, 5 Mar 2021 14:02:40 +0200
+Subject: gpiolib: Read "gpio-line-names" from a firmware node
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+commit b41ba2ec54a70908067034f139aa23d0dd2985ce upstream.
+
+On STM32MP1, the GPIO banks are subnodes of pin-controller@50002000,
+see arch/arm/boot/dts/stm32mp151.dtsi. The driver for
+pin-controller@50002000 is in drivers/pinctrl/stm32/pinctrl-stm32.c
+and iterates over all of its DT subnodes when registering each GPIO
+bank gpiochip. Each gpiochip has:
+
+  - gpio_chip.parent = dev,
+    where dev is the device node of the pin controller
+  - gpio_chip.of_node = np,
+    which is the OF node of the GPIO bank
+
+Therefore, dev_fwnode(chip->parent) != of_fwnode_handle(chip.of_node),
+i.e. pin-controller@50002000 != pin-controller@50002000/gpio@5000*000.
+
+The original code behaved correctly, as it extracted the "gpio-line-names"
+from of_fwnode_handle(chip.of_node) = pin-controller@50002000/gpio@5000*000.
+
+To achieve the same behaviour, read property from the firmware node.
+
+Fixes: 7cba1a4d5e162 ("gpiolib: generalize devprop_gpiochip_set_names() for device properties")
+Reported-by: Marek Vasut <marex@denx.de>
+Reported-by: Roman Guskov <rguskov@dh-electronics.com>
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Tested-by: Marek Vasut <marex@denx.de>
+Reviewed-by: Marek Vasut <marex@denx.de>
+Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpio/gpiolib.c |   12 ++++--------
+ 1 file changed, 4 insertions(+), 8 deletions(-)
+
+--- a/drivers/gpio/gpiolib.c
++++ b/drivers/gpio/gpiolib.c
+@@ -364,22 +364,18 @@ static int gpiochip_set_desc_names(struc
+  *
+  * Looks for device property "gpio-line-names" and if it exists assigns
+  * GPIO line names for the chip. The memory allocated for the assigned
+- * names belong to the underlying software node and should not be released
++ * names belong to the underlying firmware node and should not be released
+  * by the caller.
+  */
+ static int devprop_gpiochip_set_names(struct gpio_chip *chip)
+ {
+       struct gpio_device *gdev = chip->gpiodev;
+-      struct device *dev = chip->parent;
++      struct fwnode_handle *fwnode = dev_fwnode(&gdev->dev);
+       const char **names;
+       int ret, i;
+       int count;
+-      /* GPIO chip may not have a parent device whose properties we inspect. */
+-      if (!dev)
+-              return 0;
+-
+-      count = device_property_string_array_count(dev, "gpio-line-names");
++      count = fwnode_property_string_array_count(fwnode, "gpio-line-names");
+       if (count < 0)
+               return 0;
+@@ -393,7 +389,7 @@ static int devprop_gpiochip_set_names(st
+       if (!names)
+               return -ENOMEM;
+-      ret = device_property_read_string_array(dev, "gpio-line-names",
++      ret = fwnode_property_read_string_array(fwnode, "gpio-line-names",
+                                               names, count);
+       if (ret < 0) {
+               dev_warn(&gdev->dev, "failed to read GPIO line names\n");
diff --git a/queue-5.10/ibmvnic-always-store-valid-mac-address.patch b/queue-5.10/ibmvnic-always-store-valid-mac-address.patch
new file mode 100644 (file)
index 0000000..f4483ee
--- /dev/null
@@ -0,0 +1,53 @@
+From 67eb211487f0c993d9f402d1c196ef159fd6a3b5 Mon Sep 17 00:00:00 2001
+From: Jiri Wiesner <jwiesner@suse.com>
+Date: Thu, 4 Mar 2021 17:18:28 +0100
+Subject: ibmvnic: always store valid MAC address
+
+From: Jiri Wiesner <jwiesner@suse.com>
+
+commit 67eb211487f0c993d9f402d1c196ef159fd6a3b5 upstream.
+
+The last change to ibmvnic_set_mac(), 8fc3672a8ad3, meant to prevent
+users from setting an invalid MAC address on an ibmvnic interface
+that has not been brought up yet. The change also prevented the
+requested MAC address from being stored by the adapter object for an
+ibmvnic interface when the state of the ibmvnic interface is
+VNIC_PROBED - that is after probing has finished but before the
+ibmvnic interface is brought up. The MAC address stored by the
+adapter object is used and sent to the hypervisor for checking when
+an ibmvnic interface is brought up.
+
+The ibmvnic driver ignoring the requested MAC address when in
+VNIC_PROBED state caused LACP bonds (bonds in 802.3ad mode) with more
+than one slave to malfunction. The bonding code must be able to
+change the MAC address of its slaves before they are brought up
+during enslaving. The inability of kernels with 8fc3672a8ad3 to set
+the MAC addresses of bonding slaves is observable in the output of
+"ip address show". The MAC addresses of the slaves are the same as
+the MAC address of the bond on a working system whereas the slaves
+retain their original MAC addresses on a system with a malfunctioning
+LACP bond.
+
+Fixes: 8fc3672a8ad3 ("ibmvnic: fix ibmvnic_set_mac")
+Signed-off-by: Jiri Wiesner <jwiesner@suse.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/ibm/ibmvnic.c |    5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/ethernet/ibm/ibmvnic.c
++++ b/drivers/net/ethernet/ibm/ibmvnic.c
+@@ -1832,10 +1832,9 @@ static int ibmvnic_set_mac(struct net_de
+       if (!is_valid_ether_addr(addr->sa_data))
+               return -EADDRNOTAVAIL;
+-      if (adapter->state != VNIC_PROBED) {
+-              ether_addr_copy(adapter->mac_addr, addr->sa_data);
++      ether_addr_copy(adapter->mac_addr, addr->sa_data);
++      if (adapter->state != VNIC_PROBED)
+               rc = __ibmvnic_set_mac(netdev, addr->sa_data);
+-      }
+       return rc;
+ }
diff --git a/queue-5.10/ibmvnic-fix-possibly-uninitialized-old_num_tx_queues-variable-warning.patch b/queue-5.10/ibmvnic-fix-possibly-uninitialized-old_num_tx_queues-variable-warning.patch
new file mode 100644 (file)
index 0000000..c8a8b7f
--- /dev/null
@@ -0,0 +1,49 @@
+From 6881b07fdd24850def1f03761c66042b983ff86e Mon Sep 17 00:00:00 2001
+From: Michal Suchanek <msuchanek@suse.de>
+Date: Tue, 2 Mar 2021 20:47:47 +0100
+Subject: ibmvnic: Fix possibly uninitialized old_num_tx_queues variable warning.
+
+From: Michal Suchanek <msuchanek@suse.de>
+
+commit 6881b07fdd24850def1f03761c66042b983ff86e upstream.
+
+GCC 7.5 reports:
+../drivers/net/ethernet/ibm/ibmvnic.c: In function 'ibmvnic_reset_init':
+../drivers/net/ethernet/ibm/ibmvnic.c:5373:51: warning: 'old_num_tx_queues' may be used uninitialized in this function [-Wmaybe-uninitialized]
+../drivers/net/ethernet/ibm/ibmvnic.c:5373:6: warning: 'old_num_rx_queues' may be used uninitialized in this function [-Wmaybe-uninitialized]
+
+The variable is initialized only if(reset) and used only if(reset &&
+something) so this is a false positive. However, there is no reason to
+not initialize the variables unconditionally avoiding the warning.
+
+Fixes: 635e442f4a48 ("ibmvnic: merge ibmvnic_reset_init and ibmvnic_init")
+Signed-off-by: Michal Suchanek <msuchanek@suse.de>
+Reviewed-by: Sukadev Bhattiprolu <sukadev@linux.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/ibm/ibmvnic.c |    8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/ethernet/ibm/ibmvnic.c
++++ b/drivers/net/ethernet/ibm/ibmvnic.c
+@@ -5176,16 +5176,14 @@ static int ibmvnic_reset_init(struct ibm
+ {
+       struct device *dev = &adapter->vdev->dev;
+       unsigned long timeout = msecs_to_jiffies(20000);
+-      u64 old_num_rx_queues, old_num_tx_queues;
++      u64 old_num_rx_queues = adapter->req_rx_queues;
++      u64 old_num_tx_queues = adapter->req_tx_queues;
+       int rc;
+       adapter->from_passive_init = false;
+-      if (reset) {
+-              old_num_rx_queues = adapter->req_rx_queues;
+-              old_num_tx_queues = adapter->req_tx_queues;
++      if (reset)
+               reinit_completion(&adapter->init_done);
+-      }
+       adapter->init_done_rc = 0;
+       rc = ibmvnic_send_crq_init(adapter);
diff --git a/queue-5.10/libbpf-clear-map_info-before-each-bpf_obj_get_info_by_fd.patch b/queue-5.10/libbpf-clear-map_info-before-each-bpf_obj_get_info_by_fd.patch
new file mode 100644 (file)
index 0000000..19fa629
--- /dev/null
@@ -0,0 +1,62 @@
+From 2b2aedabc44e9660f90ccf7ba1ca2706d75f411f Mon Sep 17 00:00:00 2001
+From: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
+Date: Wed, 3 Mar 2021 19:56:36 +0100
+Subject: libbpf: Clear map_info before each bpf_obj_get_info_by_fd
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
+
+commit 2b2aedabc44e9660f90ccf7ba1ca2706d75f411f upstream.
+
+xsk_lookup_bpf_maps, based on prog_fd, looks whether current prog has a
+reference to XSKMAP. BPF prog can include insns that work on various BPF
+maps and this is covered by iterating through map_ids.
+
+The bpf_map_info that is passed to bpf_obj_get_info_by_fd for filling
+needs to be cleared at each iteration, so that it doesn't contain any
+outdated fields and that is currently missing in the function of
+interest.
+
+To fix that, zero-init map_info via memset before each
+bpf_obj_get_info_by_fd call.
+
+Also, since the area of this code is touched, in general strcmp is
+considered harmful, so let's convert it to strncmp and provide the
+size of the array name for current map_info.
+
+While at it, do s/continue/break/ once we have found the xsks_map to
+terminate the search.
+
+Fixes: 5750902a6e9b ("libbpf: proper XSKMAP cleanup")
+Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Björn Töpel <bjorn.topel@intel.com>
+Link: https://lore.kernel.org/bpf/20210303185636.18070-4-maciej.fijalkowski@intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/lib/bpf/xsk.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/tools/lib/bpf/xsk.c
++++ b/tools/lib/bpf/xsk.c
+@@ -535,15 +535,16 @@ static int xsk_lookup_bpf_maps(struct xs
+               if (fd < 0)
+                       continue;
++              memset(&map_info, 0, map_len);
+               err = bpf_obj_get_info_by_fd(fd, &map_info, &map_len);
+               if (err) {
+                       close(fd);
+                       continue;
+               }
+-              if (!strcmp(map_info.name, "xsks_map")) {
++              if (!strncmp(map_info.name, "xsks_map", sizeof(map_info.name))) {
+                       ctx->xsks_map_fd = fd;
+-                      continue;
++                      break;
+               }
+               close(fd);
diff --git a/queue-5.10/mt76-dma-do-not-report-truncated-frames-to-mac80211.patch b/queue-5.10/mt76-dma-do-not-report-truncated-frames-to-mac80211.patch
new file mode 100644 (file)
index 0000000..7f3eb09
--- /dev/null
@@ -0,0 +1,57 @@
+From d0bd52c591a1070c54dc428e926660eb4f981099 Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Sun, 7 Feb 2021 12:48:31 +0100
+Subject: mt76: dma: do not report truncated frames to mac80211
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+commit d0bd52c591a1070c54dc428e926660eb4f981099 upstream.
+
+Commit b102f0c522cf6 ("mt76: fix array overflow on receiving too many
+fragments for a packet") fixes a possible OOB access but it introduces a
+memory leak since the pending frame is not released to page_frag_cache
+if the frag array of skb_shared_info is full. Commit 93a1d4791c10
+("mt76: dma: fix a possible memory leak in mt76_add_fragment()") fixes
+the issue but does not free the truncated skb that is forwarded to
+mac80211 layer. Fix the leftover issue discarding even truncated skbs.
+
+Fixes: 93a1d4791c10 ("mt76: dma: fix a possible memory leak in mt76_add_fragment()")
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/a03166fcc8214644333c68674a781836e0f57576.1612697217.git.lorenzo@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wireless/mediatek/mt76/dma.c |   11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/wireless/mediatek/mt76/dma.c
++++ b/drivers/net/wireless/mediatek/mt76/dma.c
+@@ -521,13 +521,13 @@ mt76_add_fragment(struct mt76_dev *dev,
+ {
+       struct sk_buff *skb = q->rx_head;
+       struct skb_shared_info *shinfo = skb_shinfo(skb);
++      int nr_frags = shinfo->nr_frags;
+-      if (shinfo->nr_frags < ARRAY_SIZE(shinfo->frags)) {
++      if (nr_frags < ARRAY_SIZE(shinfo->frags)) {
+               struct page *page = virt_to_head_page(data);
+               int offset = data - page_address(page) + q->buf_offset;
+-              skb_add_rx_frag(skb, shinfo->nr_frags, page, offset, len,
+-                              q->buf_size);
++              skb_add_rx_frag(skb, nr_frags, page, offset, len, q->buf_size);
+       } else {
+               skb_free_frag(data);
+       }
+@@ -536,7 +536,10 @@ mt76_add_fragment(struct mt76_dev *dev,
+               return;
+       q->rx_head = NULL;
+-      dev->drv->rx_skb(dev, q - dev->q_rx, skb);
++      if (nr_frags < ARRAY_SIZE(shinfo->frags))
++              dev->drv->rx_skb(dev, q - dev->q_rx, skb);
++      else
++              dev_kfree_skb(skb);
+ }
+ static int
diff --git a/queue-5.10/net-always-use-icmp-v6-_ndo_send-from-ndo_start_xmit.patch b/queue-5.10/net-always-use-icmp-v6-_ndo_send-from-ndo_start_xmit.patch
new file mode 100644 (file)
index 0000000..615a463
--- /dev/null
@@ -0,0 +1,186 @@
+From 4372339efc06bc2a796f4cc9d0a7a929dfda4967 Mon Sep 17 00:00:00 2001
+From: "Jason A. Donenfeld" <Jason@zx2c4.com>
+Date: Sat, 27 Feb 2021 01:40:19 +0100
+Subject: net: always use icmp{,v6}_ndo_send from ndo_start_xmit
+
+From: Jason A. Donenfeld <Jason@zx2c4.com>
+
+commit 4372339efc06bc2a796f4cc9d0a7a929dfda4967 upstream.
+
+There were a few remaining tunnel drivers that didn't receive the prior
+conversion to icmp{,v6}_ndo_send. Knowing now that this could lead to
+memory corrution (see ee576c47db60 ("net: icmp: pass zeroed opts from
+icmp{,v6}_ndo_send before sending") for details), there's even more
+imperative to have these all converted. So this commit goes through the
+remaining cases that I could find and does a boring translation to the
+ndo variety.
+
+The Fixes: line below is the merge that originally added icmp{,v6}_
+ndo_send and converted the first batch of icmp{,v6}_send users. The
+rationale then for the change applies equally to this patch. It's just
+that these drivers were left out of the initial conversion because these
+network devices are hiding in net/ rather than in drivers/net/.
+
+Cc: Florian Westphal <fw@strlen.de>
+Cc: Willem de Bruijn <willemb@google.com>
+Cc: David S. Miller <davem@davemloft.net>
+Cc: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
+Cc: David Ahern <dsahern@kernel.org>
+Cc: Jakub Kicinski <kuba@kernel.org>
+Cc: Steffen Klassert <steffen.klassert@secunet.com>
+Fixes: 803381f9f117 ("Merge branch 'icmp-account-for-NAT-when-sending-icmps-from-ndo-layer'")
+Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
+Acked-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/ip_tunnel.c  |    5 ++---
+ net/ipv4/ip_vti.c     |    6 +++---
+ net/ipv6/ip6_gre.c    |   16 ++++++++--------
+ net/ipv6/ip6_tunnel.c |   10 +++++-----
+ net/ipv6/ip6_vti.c    |    6 +++---
+ net/ipv6/sit.c        |    2 +-
+ 6 files changed, 22 insertions(+), 23 deletions(-)
+
+--- a/net/ipv4/ip_tunnel.c
++++ b/net/ipv4/ip_tunnel.c
+@@ -502,8 +502,7 @@ static int tnl_update_pmtu(struct net_de
+               if (!skb_is_gso(skb) &&
+                   (inner_iph->frag_off & htons(IP_DF)) &&
+                   mtu < pkt_size) {
+-                      memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
+-                      icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
++                      icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
+                       return -E2BIG;
+               }
+       }
+@@ -527,7 +526,7 @@ static int tnl_update_pmtu(struct net_de
+               if (!skb_is_gso(skb) && mtu >= IPV6_MIN_MTU &&
+                                       mtu < pkt_size) {
+-                      icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
++                      icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
+                       return -E2BIG;
+               }
+       }
+--- a/net/ipv4/ip_vti.c
++++ b/net/ipv4/ip_vti.c
+@@ -238,13 +238,13 @@ static netdev_tx_t vti_xmit(struct sk_bu
+       if (skb->len > mtu) {
+               skb_dst_update_pmtu_no_confirm(skb, mtu);
+               if (skb->protocol == htons(ETH_P_IP)) {
+-                      icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
+-                                htonl(mtu));
++                      icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
++                                    htonl(mtu));
+               } else {
+                       if (mtu < IPV6_MIN_MTU)
+                               mtu = IPV6_MIN_MTU;
+-                      icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
++                      icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
+               }
+               dst_release(dst);
+--- a/net/ipv6/ip6_gre.c
++++ b/net/ipv6/ip6_gre.c
+@@ -678,8 +678,8 @@ static int prepare_ip6gre_xmit_ipv6(stru
+               tel = (struct ipv6_tlv_tnl_enc_lim *)&skb_network_header(skb)[offset];
+               if (tel->encap_limit == 0) {
+-                      icmpv6_send(skb, ICMPV6_PARAMPROB,
+-                                  ICMPV6_HDR_FIELD, offset + 2);
++                      icmpv6_ndo_send(skb, ICMPV6_PARAMPROB,
++                                      ICMPV6_HDR_FIELD, offset + 2);
+                       return -1;
+               }
+               *encap_limit = tel->encap_limit - 1;
+@@ -805,8 +805,8 @@ static inline int ip6gre_xmit_ipv4(struc
+       if (err != 0) {
+               /* XXX: send ICMP error even if DF is not set. */
+               if (err == -EMSGSIZE)
+-                      icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
+-                                htonl(mtu));
++                      icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
++                                    htonl(mtu));
+               return -1;
+       }
+@@ -837,7 +837,7 @@ static inline int ip6gre_xmit_ipv6(struc
+                         &mtu, skb->protocol);
+       if (err != 0) {
+               if (err == -EMSGSIZE)
+-                      icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
++                      icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
+               return -1;
+       }
+@@ -1063,10 +1063,10 @@ static netdev_tx_t ip6erspan_tunnel_xmit
+               /* XXX: send ICMP error even if DF is not set. */
+               if (err == -EMSGSIZE) {
+                       if (skb->protocol == htons(ETH_P_IP))
+-                              icmp_send(skb, ICMP_DEST_UNREACH,
+-                                        ICMP_FRAG_NEEDED, htonl(mtu));
++                              icmp_ndo_send(skb, ICMP_DEST_UNREACH,
++                                            ICMP_FRAG_NEEDED, htonl(mtu));
+                       else
+-                              icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
++                              icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
+               }
+               goto tx_err;
+--- a/net/ipv6/ip6_tunnel.c
++++ b/net/ipv6/ip6_tunnel.c
+@@ -1363,8 +1363,8 @@ ipxip6_tnl_xmit(struct sk_buff *skb, str
+                               tel = (void *)&skb_network_header(skb)[offset];
+                               if (tel->encap_limit == 0) {
+-                                      icmpv6_send(skb, ICMPV6_PARAMPROB,
+-                                              ICMPV6_HDR_FIELD, offset + 2);
++                                      icmpv6_ndo_send(skb, ICMPV6_PARAMPROB,
++                                                      ICMPV6_HDR_FIELD, offset + 2);
+                                       return -1;
+                               }
+                               encap_limit = tel->encap_limit - 1;
+@@ -1416,11 +1416,11 @@ ipxip6_tnl_xmit(struct sk_buff *skb, str
+               if (err == -EMSGSIZE)
+                       switch (protocol) {
+                       case IPPROTO_IPIP:
+-                              icmp_send(skb, ICMP_DEST_UNREACH,
+-                                        ICMP_FRAG_NEEDED, htonl(mtu));
++                              icmp_ndo_send(skb, ICMP_DEST_UNREACH,
++                                            ICMP_FRAG_NEEDED, htonl(mtu));
+                               break;
+                       case IPPROTO_IPV6:
+-                              icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
++                              icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
+                               break;
+                       default:
+                               break;
+--- a/net/ipv6/ip6_vti.c
++++ b/net/ipv6/ip6_vti.c
+@@ -520,10 +520,10 @@ vti6_xmit(struct sk_buff *skb, struct ne
+                       if (mtu < IPV6_MIN_MTU)
+                               mtu = IPV6_MIN_MTU;
+-                      icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
++                      icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
+               } else {
+-                      icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
+-                                htonl(mtu));
++                      icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
++                                    htonl(mtu));
+               }
+               err = -EMSGSIZE;
+--- a/net/ipv6/sit.c
++++ b/net/ipv6/sit.c
+@@ -987,7 +987,7 @@ static netdev_tx_t ipip6_tunnel_xmit(str
+                       skb_dst_update_pmtu_no_confirm(skb, mtu);
+               if (skb->len > mtu && !skb_is_gso(skb)) {
+-                      icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
++                      icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
+                       ip_rt_put(rt);
+                       goto tx_error;
+               }
diff --git a/queue-5.10/net-l2tp-reduce-log-level-of-messages-in-receive-path-add-counter-instead.patch b/queue-5.10/net-l2tp-reduce-log-level-of-messages-in-receive-path-add-counter-instead.patch
new file mode 100644 (file)
index 0000000..e8b06ea
--- /dev/null
@@ -0,0 +1,188 @@
+From 3e59e8856758eb5a2dfe1f831ef53b168fd58105 Mon Sep 17 00:00:00 2001
+From: Matthias Schiffer <mschiffer@universe-factory.net>
+Date: Wed, 3 Mar 2021 16:50:49 +0100
+Subject: net: l2tp: reduce log level of messages in receive path, add counter instead
+
+From: Matthias Schiffer <mschiffer@universe-factory.net>
+
+commit 3e59e8856758eb5a2dfe1f831ef53b168fd58105 upstream.
+
+Commit 5ee759cda51b ("l2tp: use standard API for warning log messages")
+changed a number of warnings about invalid packets in the receive path
+so that they are always shown, instead of only when a special L2TP debug
+flag is set. Even with rate limiting these warnings can easily cause
+significant log spam - potentially triggered by a malicious party
+sending invalid packets on purpose.
+
+In addition these warnings were noticed by projects like Tunneldigger [1],
+which uses L2TP for its data path, but implements its own control
+protocol (which is sufficiently different from L2TP data packets that it
+would always be passed up to userspace even with future extensions of
+L2TP).
+
+Some of the warnings were already redundant, as l2tp_stats has a counter
+for these packets. This commit adds one additional counter for invalid
+packets that are passed up to userspace. Packets with unknown session are
+not counted as invalid, as there is nothing wrong with the format of
+these packets.
+
+With the additional counter, all of these messages are either redundant
+or benign, so we reduce them to pr_debug_ratelimited().
+
+[1] https://github.com/wlanslovenija/tunneldigger/issues/160
+
+Fixes: 5ee759cda51b ("l2tp: use standard API for warning log messages")
+Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/uapi/linux/l2tp.h |    1 +
+ net/l2tp/l2tp_core.c      |   41 ++++++++++++++++++++++-------------------
+ net/l2tp/l2tp_core.h      |    1 +
+ net/l2tp/l2tp_netlink.c   |    6 ++++++
+ 4 files changed, 30 insertions(+), 19 deletions(-)
+
+--- a/include/uapi/linux/l2tp.h
++++ b/include/uapi/linux/l2tp.h
+@@ -145,6 +145,7 @@ enum {
+       L2TP_ATTR_RX_ERRORS,            /* u64 */
+       L2TP_ATTR_STATS_PAD,
+       L2TP_ATTR_RX_COOKIE_DISCARDS,   /* u64 */
++      L2TP_ATTR_RX_INVALID,           /* u64 */
+       __L2TP_ATTR_STATS_MAX,
+ };
+--- a/net/l2tp/l2tp_core.c
++++ b/net/l2tp/l2tp_core.c
+@@ -649,9 +649,9 @@ void l2tp_recv_common(struct l2tp_sessio
+       /* Parse and check optional cookie */
+       if (session->peer_cookie_len > 0) {
+               if (memcmp(ptr, &session->peer_cookie[0], session->peer_cookie_len)) {
+-                      pr_warn_ratelimited("%s: cookie mismatch (%u/%u). Discarding.\n",
+-                                          tunnel->name, tunnel->tunnel_id,
+-                                          session->session_id);
++                      pr_debug_ratelimited("%s: cookie mismatch (%u/%u). Discarding.\n",
++                                           tunnel->name, tunnel->tunnel_id,
++                                           session->session_id);
+                       atomic_long_inc(&session->stats.rx_cookie_discards);
+                       goto discard;
+               }
+@@ -702,8 +702,8 @@ void l2tp_recv_common(struct l2tp_sessio
+                * If user has configured mandatory sequence numbers, discard.
+                */
+               if (session->recv_seq) {
+-                      pr_warn_ratelimited("%s: recv data has no seq numbers when required. Discarding.\n",
+-                                          session->name);
++                      pr_debug_ratelimited("%s: recv data has no seq numbers when required. Discarding.\n",
++                                           session->name);
+                       atomic_long_inc(&session->stats.rx_seq_discards);
+                       goto discard;
+               }
+@@ -718,8 +718,8 @@ void l2tp_recv_common(struct l2tp_sessio
+                       session->send_seq = 0;
+                       l2tp_session_set_header_len(session, tunnel->version);
+               } else if (session->send_seq) {
+-                      pr_warn_ratelimited("%s: recv data has no seq numbers when required. Discarding.\n",
+-                                          session->name);
++                      pr_debug_ratelimited("%s: recv data has no seq numbers when required. Discarding.\n",
++                                           session->name);
+                       atomic_long_inc(&session->stats.rx_seq_discards);
+                       goto discard;
+               }
+@@ -809,9 +809,9 @@ static int l2tp_udp_recv_core(struct l2t
+       /* Short packet? */
+       if (!pskb_may_pull(skb, L2TP_HDR_SIZE_MAX)) {
+-              pr_warn_ratelimited("%s: recv short packet (len=%d)\n",
+-                                  tunnel->name, skb->len);
+-              goto error;
++              pr_debug_ratelimited("%s: recv short packet (len=%d)\n",
++                                   tunnel->name, skb->len);
++              goto invalid;
+       }
+       /* Point to L2TP header */
+@@ -824,9 +824,9 @@ static int l2tp_udp_recv_core(struct l2t
+       /* Check protocol version */
+       version = hdrflags & L2TP_HDR_VER_MASK;
+       if (version != tunnel->version) {
+-              pr_warn_ratelimited("%s: recv protocol version mismatch: got %d expected %d\n",
+-                                  tunnel->name, version, tunnel->version);
+-              goto error;
++              pr_debug_ratelimited("%s: recv protocol version mismatch: got %d expected %d\n",
++                                   tunnel->name, version, tunnel->version);
++              goto invalid;
+       }
+       /* Get length of L2TP packet */
+@@ -834,7 +834,7 @@ static int l2tp_udp_recv_core(struct l2t
+       /* If type is control packet, it is handled by userspace. */
+       if (hdrflags & L2TP_HDRFLAG_T)
+-              goto error;
++              goto pass;
+       /* Skip flags */
+       ptr += 2;
+@@ -863,21 +863,24 @@ static int l2tp_udp_recv_core(struct l2t
+                       l2tp_session_dec_refcount(session);
+               /* Not found? Pass to userspace to deal with */
+-              pr_warn_ratelimited("%s: no session found (%u/%u). Passing up.\n",
+-                                  tunnel->name, tunnel_id, session_id);
+-              goto error;
++              pr_debug_ratelimited("%s: no session found (%u/%u). Passing up.\n",
++                                   tunnel->name, tunnel_id, session_id);
++              goto pass;
+       }
+       if (tunnel->version == L2TP_HDR_VER_3 &&
+           l2tp_v3_ensure_opt_in_linear(session, skb, &ptr, &optr))
+-              goto error;
++              goto invalid;
+       l2tp_recv_common(session, skb, ptr, optr, hdrflags, length);
+       l2tp_session_dec_refcount(session);
+       return 0;
+-error:
++invalid:
++      atomic_long_inc(&tunnel->stats.rx_invalid);
++
++pass:
+       /* Put UDP header back */
+       __skb_push(skb, sizeof(struct udphdr));
+--- a/net/l2tp/l2tp_core.h
++++ b/net/l2tp/l2tp_core.h
+@@ -39,6 +39,7 @@ struct l2tp_stats {
+       atomic_long_t           rx_oos_packets;
+       atomic_long_t           rx_errors;
+       atomic_long_t           rx_cookie_discards;
++      atomic_long_t           rx_invalid;
+ };
+ struct l2tp_tunnel;
+--- a/net/l2tp/l2tp_netlink.c
++++ b/net/l2tp/l2tp_netlink.c
+@@ -428,6 +428,9 @@ static int l2tp_nl_tunnel_send(struct sk
+                             L2TP_ATTR_STATS_PAD) ||
+           nla_put_u64_64bit(skb, L2TP_ATTR_RX_ERRORS,
+                             atomic_long_read(&tunnel->stats.rx_errors),
++                            L2TP_ATTR_STATS_PAD) ||
++          nla_put_u64_64bit(skb, L2TP_ATTR_RX_INVALID,
++                            atomic_long_read(&tunnel->stats.rx_invalid),
+                             L2TP_ATTR_STATS_PAD))
+               goto nla_put_failure;
+       nla_nest_end(skb, nest);
+@@ -771,6 +774,9 @@ static int l2tp_nl_session_send(struct s
+                             L2TP_ATTR_STATS_PAD) ||
+           nla_put_u64_64bit(skb, L2TP_ATTR_RX_ERRORS,
+                             atomic_long_read(&session->stats.rx_errors),
++                            L2TP_ATTR_STATS_PAD) ||
++          nla_put_u64_64bit(skb, L2TP_ATTR_RX_INVALID,
++                            atomic_long_read(&session->stats.rx_invalid),
+                             L2TP_ATTR_STATS_PAD))
+               goto nla_put_failure;
+       nla_nest_end(skb, nest);
diff --git a/queue-5.10/net-phy-fix-save-wrong-speed-and-duplex-problem-if-autoneg-is-on.patch b/queue-5.10/net-phy-fix-save-wrong-speed-and-duplex-problem-if-autoneg-is-on.patch
new file mode 100644 (file)
index 0000000..3e1a614
--- /dev/null
@@ -0,0 +1,51 @@
+From d9032dba5a2b2bbf0fdce67c8795300ec9923b43 Mon Sep 17 00:00:00 2001
+From: Guangbin Huang <huangguangbin2@huawei.com>
+Date: Sat, 27 Feb 2021 11:05:58 +0800
+Subject: net: phy: fix save wrong speed and duplex problem if autoneg is on
+
+From: Guangbin Huang <huangguangbin2@huawei.com>
+
+commit d9032dba5a2b2bbf0fdce67c8795300ec9923b43 upstream.
+
+If phy uses generic driver and autoneg is on, enter command
+"ethtool -s eth0 speed 50" will not change phy speed actually, but
+command "ethtool eth0" shows speed is 50Mb/s because phydev->speed
+has been set to 50 and no update later.
+
+And duplex setting has same problem too.
+
+However, if autoneg is on, phy only changes speed and duplex according to
+phydev->advertising, but not phydev->speed and phydev->duplex. So in this
+case, phydev->speed and phydev->duplex don't need to be set in function
+phy_ethtool_ksettings_set() if autoneg is on.
+
+Fixes: 51e2a3846eab ("PHY: Avoid unnecessary aneg restarts")
+Signed-off-by: Guangbin Huang <huangguangbin2@huawei.com>
+Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/phy/phy.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/phy/phy.c
++++ b/drivers/net/phy/phy.c
+@@ -293,14 +293,16 @@ int phy_ethtool_ksettings_set(struct phy
+       phydev->autoneg = autoneg;
+-      phydev->speed = speed;
++      if (autoneg == AUTONEG_DISABLE) {
++              phydev->speed = speed;
++              phydev->duplex = duplex;
++      }
+       linkmode_copy(phydev->advertising, advertising);
+       linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
+                        phydev->advertising, autoneg == AUTONEG_ENABLE);
+-      phydev->duplex = duplex;
+       phydev->master_slave_set = cmd->base.master_slave_cfg;
+       phydev->mdix_ctrl = cmd->base.eth_tp_mdix_ctrl;
diff --git a/queue-5.10/netfilter-nf_nat-undo-erroneous-tcp-edemux-lookup.patch b/queue-5.10/netfilter-nf_nat-undo-erroneous-tcp-edemux-lookup.patch
new file mode 100644 (file)
index 0000000..d9876b8
--- /dev/null
@@ -0,0 +1,120 @@
+From 03a3ca37e4c6478e3a84f04c8429dd5889e107fd Mon Sep 17 00:00:00 2001
+From: Florian Westphal <fw@strlen.de>
+Date: Wed, 24 Feb 2021 17:23:19 +0100
+Subject: netfilter: nf_nat: undo erroneous tcp edemux lookup
+
+From: Florian Westphal <fw@strlen.de>
+
+commit 03a3ca37e4c6478e3a84f04c8429dd5889e107fd upstream.
+
+Under extremely rare conditions TCP early demux will retrieve the wrong
+socket.
+
+1. local machine establishes a connection to a remote server, S, on port
+   p.
+
+   This gives:
+   laddr:lport -> S:p
+   ... both in tcp and conntrack.
+
+2. local machine establishes a connection to host H, on port p2.
+   2a. TCP stack choses same laddr:lport, so we have
+   laddr:lport -> H:p2 from TCP point of view.
+   2b). There is a destination NAT rewrite in place, translating
+        H:p2 to S:p.  This results in following conntrack entries:
+
+   I)  laddr:lport -> S:p  (origin)  S:p -> laddr:lport (reply)
+   II) laddr:lport -> H:p2 (origin)  S:p -> laddr:lport2 (reply)
+
+   NAT engine has rewritten laddr:lport to laddr:lport2 to map
+   the reply packet to the correct origin.
+
+   When server sends SYN/ACK to laddr:lport2, the PREROUTING hook
+   will undo-the SNAT transformation, rewriting IP header to
+   S:p -> laddr:lport
+
+   This causes TCP early demux to associate the skb with the TCP socket
+   of the first connection.
+
+   The INPUT hook will then reverse the DNAT transformation, rewriting
+   the IP header to H:p2 -> laddr:lport.
+
+Because packet ends up with the wrong socket, the new connection
+never completes: originator stays in SYN_SENT and conntrack entry
+remains in SYN_RECV until timeout, and responder retransmits SYN/ACK
+until it gives up.
+
+To resolve this, orphan the skb after the input rewrite:
+Because the source IP address changed, the socket must be incorrect.
+We can't move the DNAT undo to prerouting due to backwards
+compatibility, doing so will make iptables/nftables rules to no longer
+match the way they did.
+
+After orphan, the packet will be handed to the next protocol layer
+(tcp, udp, ...) and that will repeat the socket lookup just like as if
+early demux was disabled.
+
+Fixes: 41063e9dd1195 ("ipv4: Early TCP socket demux.")
+Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1427
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/netfilter/nf_nat_proto.c |   25 +++++++++++++++++++++----
+ 1 file changed, 21 insertions(+), 4 deletions(-)
+
+--- a/net/netfilter/nf_nat_proto.c
++++ b/net/netfilter/nf_nat_proto.c
+@@ -646,8 +646,8 @@ nf_nat_ipv4_fn(void *priv, struct sk_buf
+ }
+ static unsigned int
+-nf_nat_ipv4_in(void *priv, struct sk_buff *skb,
+-             const struct nf_hook_state *state)
++nf_nat_ipv4_pre_routing(void *priv, struct sk_buff *skb,
++                      const struct nf_hook_state *state)
+ {
+       unsigned int ret;
+       __be32 daddr = ip_hdr(skb)->daddr;
+@@ -660,6 +660,23 @@ nf_nat_ipv4_in(void *priv, struct sk_buf
+ }
+ static unsigned int
++nf_nat_ipv4_local_in(void *priv, struct sk_buff *skb,
++                   const struct nf_hook_state *state)
++{
++      __be32 saddr = ip_hdr(skb)->saddr;
++      struct sock *sk = skb->sk;
++      unsigned int ret;
++
++      ret = nf_nat_ipv4_fn(priv, skb, state);
++
++      if (ret == NF_ACCEPT && sk && saddr != ip_hdr(skb)->saddr &&
++          !inet_sk_transparent(sk))
++              skb_orphan(skb); /* TCP edemux obtained wrong socket */
++
++      return ret;
++}
++
++static unsigned int
+ nf_nat_ipv4_out(void *priv, struct sk_buff *skb,
+               const struct nf_hook_state *state)
+ {
+@@ -736,7 +753,7 @@ nf_nat_ipv4_local_fn(void *priv, struct
+ static const struct nf_hook_ops nf_nat_ipv4_ops[] = {
+       /* Before packet filtering, change destination */
+       {
+-              .hook           = nf_nat_ipv4_in,
++              .hook           = nf_nat_ipv4_pre_routing,
+               .pf             = NFPROTO_IPV4,
+               .hooknum        = NF_INET_PRE_ROUTING,
+               .priority       = NF_IP_PRI_NAT_DST,
+@@ -757,7 +774,7 @@ static const struct nf_hook_ops nf_nat_i
+       },
+       /* After packet filtering, change source */
+       {
+-              .hook           = nf_nat_ipv4_fn,
++              .hook           = nf_nat_ipv4_local_in,
+               .pf             = NFPROTO_IPV4,
+               .hooknum        = NF_INET_LOCAL_IN,
+               .priority       = NF_IP_PRI_NAT_SRC,
diff --git a/queue-5.10/netfilter-x_tables-gpf-inside-xt_find_revision.patch b/queue-5.10/netfilter-x_tables-gpf-inside-xt_find_revision.patch
new file mode 100644 (file)
index 0000000..ff8292f
--- /dev/null
@@ -0,0 +1,89 @@
+From 8e24edddad152b998b37a7f583175137ed2e04a5 Mon Sep 17 00:00:00 2001
+From: Vasily Averin <vvs@virtuozzo.com>
+Date: Sat, 27 Feb 2021 11:27:45 +0300
+Subject: netfilter: x_tables: gpf inside xt_find_revision()
+
+From: Vasily Averin <vvs@virtuozzo.com>
+
+commit 8e24edddad152b998b37a7f583175137ed2e04a5 upstream.
+
+nested target/match_revfn() calls work with xt[NFPROTO_UNSPEC] lists
+without taking xt[NFPROTO_UNSPEC].mutex. This can race with module unload
+and cause host to crash:
+
+general protection fault: 0000 [#1]
+Modules linked in: ... [last unloaded: xt_cluster]
+CPU: 0 PID: 542455 Comm: iptables
+RIP: 0010:[<ffffffff8ffbd518>]  [<ffffffff8ffbd518>] strcmp+0x18/0x40
+RDX: 0000000000000003 RSI: ffff9a5a5d9abe10 RDI: dead000000000111
+R13: ffff9a5a5d9abe10 R14: ffff9a5a5d9abd8c R15: dead000000000100
+(VvS: %R15 -- &xt_match,  %RDI -- &xt_match.name,
+xt_cluster unregister match in xt[NFPROTO_UNSPEC].match list)
+Call Trace:
+ [<ffffffff902ccf44>] match_revfn+0x54/0xc0
+ [<ffffffff902ccf9f>] match_revfn+0xaf/0xc0
+ [<ffffffff902cd01e>] xt_find_revision+0x6e/0xf0
+ [<ffffffffc05a5be0>] do_ipt_get_ctl+0x100/0x420 [ip_tables]
+ [<ffffffff902cc6bf>] nf_getsockopt+0x4f/0x70
+ [<ffffffff902dd99e>] ip_getsockopt+0xde/0x100
+ [<ffffffff903039b5>] raw_getsockopt+0x25/0x50
+ [<ffffffff9026c5da>] sock_common_getsockopt+0x1a/0x20
+ [<ffffffff9026b89d>] SyS_getsockopt+0x7d/0xf0
+ [<ffffffff903cbf92>] system_call_fastpath+0x25/0x2a
+
+Fixes: 656caff20e1 ("netfilter 04/09: x_tables: fix match/target revision lookup")
+Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
+Reviewed-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/netfilter/x_tables.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/net/netfilter/x_tables.c
++++ b/net/netfilter/x_tables.c
+@@ -330,6 +330,7 @@ static int match_revfn(u8 af, const char
+       const struct xt_match *m;
+       int have_rev = 0;
++      mutex_lock(&xt[af].mutex);
+       list_for_each_entry(m, &xt[af].match, list) {
+               if (strcmp(m->name, name) == 0) {
+                       if (m->revision > *bestp)
+@@ -338,6 +339,7 @@ static int match_revfn(u8 af, const char
+                               have_rev = 1;
+               }
+       }
++      mutex_unlock(&xt[af].mutex);
+       if (af != NFPROTO_UNSPEC && !have_rev)
+               return match_revfn(NFPROTO_UNSPEC, name, revision, bestp);
+@@ -350,6 +352,7 @@ static int target_revfn(u8 af, const cha
+       const struct xt_target *t;
+       int have_rev = 0;
++      mutex_lock(&xt[af].mutex);
+       list_for_each_entry(t, &xt[af].target, list) {
+               if (strcmp(t->name, name) == 0) {
+                       if (t->revision > *bestp)
+@@ -358,6 +361,7 @@ static int target_revfn(u8 af, const cha
+                               have_rev = 1;
+               }
+       }
++      mutex_unlock(&xt[af].mutex);
+       if (af != NFPROTO_UNSPEC && !have_rev)
+               return target_revfn(NFPROTO_UNSPEC, name, revision, bestp);
+@@ -371,12 +375,10 @@ int xt_find_revision(u8 af, const char *
+ {
+       int have_rev, best = -1;
+-      mutex_lock(&xt[af].mutex);
+       if (target == 1)
+               have_rev = target_revfn(af, name, revision, &best);
+       else
+               have_rev = match_revfn(af, name, revision, &best);
+-      mutex_unlock(&xt[af].mutex);
+       /* Nothing at all?  Return 0 to try loading module. */
+       if (best == -1) {
diff --git a/queue-5.10/samples-bpf-add-missing-munmap-in-xdpsock.patch b/queue-5.10/samples-bpf-add-missing-munmap-in-xdpsock.patch
new file mode 100644 (file)
index 0000000..84ca0fc
--- /dev/null
@@ -0,0 +1,35 @@
+From 6bc6699881012b5bd5d49fa861a69a37fc01b49c Mon Sep 17 00:00:00 2001
+From: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
+Date: Wed, 3 Mar 2021 19:56:35 +0100
+Subject: samples, bpf: Add missing munmap in xdpsock
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
+
+commit 6bc6699881012b5bd5d49fa861a69a37fc01b49c upstream.
+
+We mmap the umem region, but we never munmap it.
+Add the missing call at the end of the cleanup.
+
+Fixes: 3945b37a975d ("samples/bpf: use hugepages in xdpsock app")
+Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Björn Töpel <bjorn.topel@intel.com>
+Link: https://lore.kernel.org/bpf/20210303185636.18070-3-maciej.fijalkowski@intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ samples/bpf/xdpsock_user.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/samples/bpf/xdpsock_user.c
++++ b/samples/bpf/xdpsock_user.c
+@@ -1543,5 +1543,7 @@ int main(int argc, char **argv)
+       xdpsock_cleanup();
++      munmap(bufs, NUM_FRAMES * opt_xsk_frame_size);
++
+       return 0;
+ }
diff --git a/queue-5.10/selftests-bpf-mask-bpf_csum_diff-return-value-to-16-bits-in-test_verifier.patch b/queue-5.10/selftests-bpf-mask-bpf_csum_diff-return-value-to-16-bits-in-test_verifier.patch
new file mode 100644 (file)
index 0000000..ee0ac08
--- /dev/null
@@ -0,0 +1,57 @@
+From 6185266c5a853bb0f2a459e3ff594546f277609b Mon Sep 17 00:00:00 2001
+From: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
+Date: Sun, 28 Feb 2021 12:30:17 +0200
+Subject: selftests/bpf: Mask bpf_csum_diff() return value to 16 bits in test_verifier
+
+From: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
+
+commit 6185266c5a853bb0f2a459e3ff594546f277609b upstream.
+
+The verifier test labelled "valid read map access into a read-only array
+2" calls the bpf_csum_diff() helper and checks its return value. However,
+architecture implementations of csum_partial() (which is what the helper
+uses) differ in whether they fold the return value to 16 bit or not. For
+example, x86 version has ...
+
+       if (unlikely(odd)) {
+               result = from32to16(result);
+               result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
+       }
+
+... while generic lib/checksum.c does:
+
+       result = from32to16(result);
+       if (odd)
+               result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
+
+This makes the helper return different values on different architectures,
+breaking the test on non-x86. To fix this, add an additional instruction
+to always mask the return value to 16 bits, and update the expected return
+value accordingly.
+
+Fixes: fb2abb73e575 ("bpf, selftest: test {rd, wr}only flags and direct value access")
+Signed-off-by: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Link: https://lore.kernel.org/bpf/20210228103017.320240-1-yauheni.kaliuta@redhat.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/bpf/verifier/array_access.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/tools/testing/selftests/bpf/verifier/array_access.c
++++ b/tools/testing/selftests/bpf/verifier/array_access.c
+@@ -250,12 +250,13 @@
+       BPF_MOV64_IMM(BPF_REG_5, 0),
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+                    BPF_FUNC_csum_diff),
++      BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xffff),
+       BPF_EXIT_INSN(),
+       },
+       .prog_type = BPF_PROG_TYPE_SCHED_CLS,
+       .fixup_map_array_ro = { 3 },
+       .result = ACCEPT,
+-      .retval = -29,
++      .retval = 65507,
+ },
+ {
+       "invalid write map access into a read-only array 1",
diff --git a/queue-5.10/selftests-bpf-no-need-to-drop-the-packet-when-there-is-no-geneve-opt.patch b/queue-5.10/selftests-bpf-no-need-to-drop-the-packet-when-there-is-no-geneve-opt.patch
new file mode 100644 (file)
index 0000000..6e81dbb
--- /dev/null
@@ -0,0 +1,46 @@
+From 557c223b643a35effec9654958d8edc62fd2603a Mon Sep 17 00:00:00 2001
+From: Hangbin Liu <liuhangbin@gmail.com>
+Date: Wed, 24 Feb 2021 16:14:03 +0800
+Subject: selftests/bpf: No need to drop the packet when there is no geneve opt
+
+From: Hangbin Liu <liuhangbin@gmail.com>
+
+commit 557c223b643a35effec9654958d8edc62fd2603a upstream.
+
+In bpf geneve tunnel test we set geneve option on tx side. On rx side we
+only call bpf_skb_get_tunnel_opt(). Since commit 9c2e14b48119 ("ip_tunnels:
+Set tunnel option flag when tunnel metadata is present") geneve_rx() will
+not add TUNNEL_GENEVE_OPT flag if there is no geneve option, which cause
+bpf_skb_get_tunnel_opt() return ENOENT and _geneve_get_tunnel() in
+test_tunnel_kern.c drop the packet.
+
+As it should be valid that bpf_skb_get_tunnel_opt() return error when
+there is not tunnel option, there is no need to drop the packet and
+break all geneve rx traffic. Just set opt_class to 0 in this test and
+keep returning TC_ACT_OK.
+
+Fixes: 933a741e3b82 ("selftests/bpf: bpf tunnel test.")
+Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: William Tu <u9012063@gmail.com>
+Link: https://lore.kernel.org/bpf/20210224081403.1425474-1-liuhangbin@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/bpf/progs/test_tunnel_kern.c |    6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/tools/testing/selftests/bpf/progs/test_tunnel_kern.c
++++ b/tools/testing/selftests/bpf/progs/test_tunnel_kern.c
+@@ -446,10 +446,8 @@ int _geneve_get_tunnel(struct __sk_buff
+       }
+       ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt));
+-      if (ret < 0) {
+-              ERROR(ret);
+-              return TC_ACT_SHOT;
+-      }
++      if (ret < 0)
++              gopt.opt_class = 0;
+       bpf_trace_printk(fmt, sizeof(fmt),
+                       key.tunnel_id, key.remote_ipv4, gopt.opt_class);
diff --git a/queue-5.10/selftests-bpf-use-the-last-page-in-test_snprintf_btf-on-s390.patch b/queue-5.10/selftests-bpf-use-the-last-page-in-test_snprintf_btf-on-s390.patch
new file mode 100644 (file)
index 0000000..fc710d7
--- /dev/null
@@ -0,0 +1,58 @@
+From 42a382a466a967dc053c73b969cd2ac2fec502cf Mon Sep 17 00:00:00 2001
+From: Ilya Leoshkevich <iii@linux.ibm.com>
+Date: Sat, 27 Feb 2021 06:17:26 +0100
+Subject: selftests/bpf: Use the last page in test_snprintf_btf on s390
+
+From: Ilya Leoshkevich <iii@linux.ibm.com>
+
+commit 42a382a466a967dc053c73b969cd2ac2fec502cf upstream.
+
+test_snprintf_btf fails on s390, because NULL points to a readable
+struct lowcore there. Fix by using the last page instead.
+
+Error message example:
+
+    printing fffffffffffff000 should generate error, got (361)
+
+Fixes: 076a95f5aff2 ("selftests/bpf: Add bpf_snprintf_btf helper tests")
+Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Heiko Carstens <hca@linux.ibm.com>
+Acked-by: Yonghong Song <yhs@fb.com>
+Link: https://lore.kernel.org/bpf/20210227051726.121256-1-iii@linux.ibm.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/bpf/progs/netif_receive_skb.c |   13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+--- a/tools/testing/selftests/bpf/progs/netif_receive_skb.c
++++ b/tools/testing/selftests/bpf/progs/netif_receive_skb.c
+@@ -16,6 +16,13 @@ bool skip = false;
+ #define STRSIZE                       2048
+ #define EXPECTED_STRSIZE      256
++#if defined(bpf_target_s390)
++/* NULL points to a readable struct lowcore on s390, so take the last page */
++#define BADPTR                        ((void *)0xFFFFFFFFFFFFF000ULL)
++#else
++#define BADPTR                        0
++#endif
++
+ #ifndef ARRAY_SIZE
+ #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+ #endif
+@@ -113,11 +120,11 @@ int BPF_PROG(trace_netif_receive_skb, st
+       }
+       /* Check invalid ptr value */
+-      p.ptr = 0;
++      p.ptr = BADPTR;
+       __ret = bpf_snprintf_btf(str, STRSIZE, &p, sizeof(p), 0);
+       if (__ret >= 0) {
+-              bpf_printk("printing NULL should generate error, got (%d)",
+-                         __ret);
++              bpf_printk("printing %llx should generate error, got (%d)",
++                         (unsigned long long)BADPTR, __ret);
+               ret = -ERANGE;
+       }
index 800c3453075de9d42c59f2c45fb10f87cb91b7cc..e3edc00446311cbeb069618bfecd23501814e284 100644 (file)
@@ -7,3 +7,25 @@ ath9k-fix-transmitting-to-stations-in-dynamic-smps-mode.patch
 net-fix-gro-aggregation-for-udp-encaps-with-zero-csum.patch
 net-check-if-protocol-extracted-by-virtio_net_hdr_set_proto-is-correct.patch
 net-avoid-infinite-loop-in-mpls_gso_segment-when-mpls_hlen-0.patch
+net-l2tp-reduce-log-level-of-messages-in-receive-path-add-counter-instead.patch
+gpiolib-acpi-allow-to-find-gpioint-resource-by-name-and-index.patch
+gpiolib-read-gpio-line-names-from-a-firmware-node.patch
+can-skb-can_skb_set_owner-fix-ref-counting-if-socket-was-closed-before-setting-skb-ownership.patch
+can-flexcan-assert-frz-bit-in-flexcan_chip_freeze.patch
+can-flexcan-enable-rx-fifo-after-frz-halt-valid.patch
+can-flexcan-invoke-flexcan_chip_freeze-to-enter-freeze-mode.patch
+can-tcan4x5x-tcan4x5x_init-fix-initialization-clear-mram-before-entering-normal-mode.patch
+tcp-fix-sign-comparison-bug-in-getsockopt-tcp_zerocopy_receive.patch
+tcp-add-sanity-tests-to-tcp_queue_seq.patch
+netfilter-nf_nat-undo-erroneous-tcp-edemux-lookup.patch
+netfilter-x_tables-gpf-inside-xt_find_revision.patch
+net-always-use-icmp-v6-_ndo_send-from-ndo_start_xmit.patch
+net-phy-fix-save-wrong-speed-and-duplex-problem-if-autoneg-is-on.patch
+selftests-bpf-use-the-last-page-in-test_snprintf_btf-on-s390.patch
+selftests-bpf-no-need-to-drop-the-packet-when-there-is-no-geneve-opt.patch
+selftests-bpf-mask-bpf_csum_diff-return-value-to-16-bits-in-test_verifier.patch
+samples-bpf-add-missing-munmap-in-xdpsock.patch
+libbpf-clear-map_info-before-each-bpf_obj_get_info_by_fd.patch
+ibmvnic-fix-possibly-uninitialized-old_num_tx_queues-variable-warning.patch
+ibmvnic-always-store-valid-mac-address.patch
+mt76-dma-do-not-report-truncated-frames-to-mac80211.patch
diff --git a/queue-5.10/tcp-add-sanity-tests-to-tcp_queue_seq.patch b/queue-5.10/tcp-add-sanity-tests-to-tcp_queue_seq.patch
new file mode 100644 (file)
index 0000000..3dc2593
--- /dev/null
@@ -0,0 +1,79 @@
+From 8811f4a9836e31c14ecdf79d9f3cb7c5d463265d Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Mon, 1 Mar 2021 10:29:17 -0800
+Subject: tcp: add sanity tests to TCP_QUEUE_SEQ
+
+From: Eric Dumazet <edumazet@google.com>
+
+commit 8811f4a9836e31c14ecdf79d9f3cb7c5d463265d upstream.
+
+Qingyu Li reported a syzkaller bug where the repro
+changes RCV SEQ _after_ restoring data in the receive queue.
+
+mprotect(0x4aa000, 12288, PROT_READ)    = 0
+mmap(0x1ffff000, 4096, PROT_NONE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x1ffff000
+mmap(0x20000000, 16777216, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x20000000
+mmap(0x21000000, 4096, PROT_NONE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x21000000
+socket(AF_INET6, SOCK_STREAM, IPPROTO_IP) = 3
+setsockopt(3, SOL_TCP, TCP_REPAIR, [1], 4) = 0
+connect(3, {sa_family=AF_INET6, sin6_port=htons(0), sin6_flowinfo=htonl(0), inet_pton(AF_INET6, "::1", &sin6_addr), sin6_scope_id=0}, 28) = 0
+setsockopt(3, SOL_TCP, TCP_REPAIR_QUEUE, [1], 4) = 0
+sendmsg(3, {msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="0x0000000000000003\0\0", iov_len=20}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 20
+setsockopt(3, SOL_TCP, TCP_REPAIR, [0], 4) = 0
+setsockopt(3, SOL_TCP, TCP_QUEUE_SEQ, [128], 4) = 0
+recvfrom(3, NULL, 20, 0, NULL, NULL)    = -1 ECONNRESET (Connection reset by peer)
+
+syslog shows:
+[  111.205099] TCP recvmsg seq # bug 2: copied 80, seq 0, rcvnxt 80, fl 0
+[  111.207894] WARNING: CPU: 1 PID: 356 at net/ipv4/tcp.c:2343 tcp_recvmsg_locked+0x90e/0x29a0
+
+This should not be allowed. TCP_QUEUE_SEQ should only be used
+when queues are empty.
+
+This patch fixes this case, and the tx path as well.
+
+Fixes: ee9952831cfd ("tcp: Initial repair mode")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Pavel Emelyanov <xemul@parallels.com>
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=212005
+Reported-by: Qingyu Li <ieatmuttonchuan@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/tcp.c |   23 +++++++++++++++--------
+ 1 file changed, 15 insertions(+), 8 deletions(-)
+
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -3164,16 +3164,23 @@ static int do_tcp_setsockopt(struct sock
+               break;
+       case TCP_QUEUE_SEQ:
+-              if (sk->sk_state != TCP_CLOSE)
++              if (sk->sk_state != TCP_CLOSE) {
+                       err = -EPERM;
+-              else if (tp->repair_queue == TCP_SEND_QUEUE)
+-                      WRITE_ONCE(tp->write_seq, val);
+-              else if (tp->repair_queue == TCP_RECV_QUEUE) {
+-                      WRITE_ONCE(tp->rcv_nxt, val);
+-                      WRITE_ONCE(tp->copied_seq, val);
+-              }
+-              else
++              } else if (tp->repair_queue == TCP_SEND_QUEUE) {
++                      if (!tcp_rtx_queue_empty(sk))
++                              err = -EPERM;
++                      else
++                              WRITE_ONCE(tp->write_seq, val);
++              } else if (tp->repair_queue == TCP_RECV_QUEUE) {
++                      if (tp->rcv_nxt != tp->copied_seq) {
++                              err = -EPERM;
++                      } else {
++                              WRITE_ONCE(tp->rcv_nxt, val);
++                              WRITE_ONCE(tp->copied_seq, val);
++                      }
++              } else {
+                       err = -EINVAL;
++              }
+               break;
+       case TCP_REPAIR_OPTIONS:
diff --git a/queue-5.10/tcp-fix-sign-comparison-bug-in-getsockopt-tcp_zerocopy_receive.patch b/queue-5.10/tcp-fix-sign-comparison-bug-in-getsockopt-tcp_zerocopy_receive.patch
new file mode 100644 (file)
index 0000000..8c92554
--- /dev/null
@@ -0,0 +1,47 @@
+From 2107d45f17bedd7dbf4178462da0ac223835a2a7 Mon Sep 17 00:00:00 2001
+From: Arjun Roy <arjunroy@google.com>
+Date: Thu, 25 Feb 2021 15:26:28 -0800
+Subject: tcp: Fix sign comparison bug in getsockopt(TCP_ZEROCOPY_RECEIVE)
+
+From: Arjun Roy <arjunroy@google.com>
+
+commit 2107d45f17bedd7dbf4178462da0ac223835a2a7 upstream.
+
+getsockopt(TCP_ZEROCOPY_RECEIVE) has a bug where we read a
+user-provided "len" field of type signed int, and then compare the
+value to the result of an "offsetofend" operation, which is unsigned.
+
+Negative values provided by the user will be promoted to large
+positive numbers; thus checking that len < offsetofend() will return
+false when the intention was that it return true.
+
+Note that while len is originally checked for negative values earlier
+on in do_tcp_getsockopt(), subsequent calls to get_user() re-read the
+value from userspace which may have changed in the meantime.
+
+Therefore, re-add the check for negative values after the call to
+get_user in the handler code for TCP_ZEROCOPY_RECEIVE.
+
+Fixes: c8856c051454 ("tcp-zerocopy: Return inq along with tcp receive zerocopy.")
+Reported-by: kernel test robot <lkp@intel.com>
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Arjun Roy <arjunroy@google.com>
+Link: https://lore.kernel.org/r/20210225232628.4033281-1-arjunroy.kdev@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/tcp.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -3829,7 +3829,8 @@ static int do_tcp_getsockopt(struct sock
+               if (get_user(len, optlen))
+                       return -EFAULT;
+-              if (len < offsetofend(struct tcp_zerocopy_receive, length))
++              if (len < 0 ||
++                  len < offsetofend(struct tcp_zerocopy_receive, length))
+                       return -EINVAL;
+               if (len > sizeof(zc)) {
+                       len = sizeof(zc);