commit:     001b31139e4c70e7887352c8e81d6f60c1402dfb
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Tue Nov  2 19:36:35 2021 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Tue Nov  2 19:36:35 2021 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=001b3113

Linux patch 4.14.254

Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>

 0000_README               |   4 +
 1253_linux-4.14.254.patch | 682 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 686 insertions(+)

diff --git a/0000_README b/0000_README
index d4ac84b..0bc848c 100644
--- a/0000_README
+++ b/0000_README
@@ -1059,6 +1059,10 @@ Patch:  1252_linux-4.14.253.patch
 From:   https://www.kernel.org
 Desc:   Linux 4.14.253
 
+Patch:  1253_linux-4.14.254.patch
+From:   https://www.kernel.org
+Desc:   Linux 4.14.254
+
 Patch:  1500_XATTR_USER_PREFIX.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=470644
 Desc:   Support for namespace user.pax.* on tmpfs.

diff --git a/1253_linux-4.14.254.patch b/1253_linux-4.14.254.patch
new file mode 100644
index 0000000..6fa6584
--- /dev/null
+++ b/1253_linux-4.14.254.patch
@@ -0,0 +1,682 @@
+diff --git a/Makefile b/Makefile
+index f4084bf887619..b684983722afb 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 4
+ PATCHLEVEL = 14
+-SUBLEVEL = 253
++SUBLEVEL = 254
+ EXTRAVERSION =
+ NAME = Petit Gorille
+ 
+diff --git a/arch/arm/Makefile b/arch/arm/Makefile
+index 234ee43b44384..e7455058416ef 100644
+--- a/arch/arm/Makefile
++++ b/arch/arm/Makefile
+@@ -13,7 +13,7 @@
+ # Ensure linker flags are correct
+ LDFLAGS               :=
+ 
+-LDFLAGS_vmlinux       :=-p --no-undefined -X --pic-veneer
++LDFLAGS_vmlinux       := --no-undefined -X --pic-veneer
+ ifeq ($(CONFIG_CPU_ENDIAN_BE8),y)
+ LDFLAGS_vmlinux       += --be8
+ LDFLAGS_MODULE        += --be8
+diff --git a/arch/arm/boot/bootp/Makefile b/arch/arm/boot/bootp/Makefile
+index 83e1a076a5d64..981a8d03f064c 100644
+--- a/arch/arm/boot/bootp/Makefile
++++ b/arch/arm/boot/bootp/Makefile
+@@ -8,7 +8,7 @@
+ 
+ GCOV_PROFILE  := n
+ 
+-LDFLAGS_bootp :=-p --no-undefined -X \
++LDFLAGS_bootp := --no-undefined -X \
+                --defsym initrd_phys=$(INITRD_PHYS) \
+                --defsym params_phys=$(PARAMS_PHYS) -T
+ AFLAGS_initrd.o :=-DINITRD=\"$(INITRD)\"
+diff --git a/arch/arm/boot/compressed/Makefile 
b/arch/arm/boot/compressed/Makefile
+index a61b7e4d06668..d912628e1c9f2 100644
+--- a/arch/arm/boot/compressed/Makefile
++++ b/arch/arm/boot/compressed/Makefile
+@@ -129,8 +129,6 @@ endif
+ ifeq ($(CONFIG_CPU_ENDIAN_BE8),y)
+ LDFLAGS_vmlinux += --be8
+ endif
+-# ?
+-LDFLAGS_vmlinux += -p
+ # Report unresolved symbol references
+ LDFLAGS_vmlinux += --no-undefined
+ # Delete all temporary local symbols
+diff --git a/arch/arm/boot/compressed/decompress.c 
b/arch/arm/boot/compressed/decompress.c
+index a2ac3fe7dbf8a..944534eb0bd8b 100644
+--- a/arch/arm/boot/compressed/decompress.c
++++ b/arch/arm/boot/compressed/decompress.c
+@@ -49,7 +49,10 @@ extern int memcmp(const void *cs, const void *ct, size_t 
count);
+ #endif
+ 
+ #ifdef CONFIG_KERNEL_XZ
++/* Prevent KASAN override of string helpers in decompressor */
++#undef memmove
+ #define memmove memmove
++#undef memcpy
+ #define memcpy memcpy
+ #include "../../../../lib/decompress_unxz.c"
+ #endif
+diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
+index 60ac7c5999a98..86e54447dc916 100644
+--- a/arch/arm/mm/proc-macros.S
++++ b/arch/arm/mm/proc-macros.S
+@@ -342,6 +342,7 @@ ENTRY(\name\()_cache_fns)
+ 
+ .macro define_tlb_functions name:req, flags_up:req, flags_smp
+       .type   \name\()_tlb_fns, #object
++      .align 2
+ ENTRY(\name\()_tlb_fns)
+       .long   \name\()_flush_user_tlb_range
+       .long   \name\()_flush_kern_tlb_range
+diff --git a/arch/arm/probes/kprobes/core.c b/arch/arm/probes/kprobes/core.c
+index 091e9a3c2dcb1..3cd2066c2ca3c 100644
+--- a/arch/arm/probes/kprobes/core.c
++++ b/arch/arm/probes/kprobes/core.c
+@@ -669,7 +669,7 @@ static struct undef_hook kprobes_arm_break_hook = {
+ 
+ #endif /* !CONFIG_THUMB2_KERNEL */
+ 
+-int __init arch_init_kprobes()
++int __init arch_init_kprobes(void)
+ {
+       arm_probes_decode_init();
+ #ifdef CONFIG_THUMB2_KERNEL
+diff --git a/arch/nios2/platform/Kconfig.platform 
b/arch/nios2/platform/Kconfig.platform
+index 74c1aaf588b8b..54f6dfb3b7974 100644
+--- a/arch/nios2/platform/Kconfig.platform
++++ b/arch/nios2/platform/Kconfig.platform
+@@ -37,6 +37,7 @@ config NIOS2_DTB_PHYS_ADDR
+ 
+ config NIOS2_DTB_SOURCE_BOOL
+       bool "Compile and link device tree into kernel image"
++      depends on !COMPILE_TEST
+       default n
+       help
+         This allows you to specify a dts (device tree source) file
+diff --git a/arch/powerpc/net/bpf_jit_comp64.c 
b/arch/powerpc/net/bpf_jit_comp64.c
+index 28434040cfb61..b6374f6831a27 100644
+--- a/arch/powerpc/net/bpf_jit_comp64.c
++++ b/arch/powerpc/net/bpf_jit_comp64.c
+@@ -426,8 +426,14 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 
*image,
+               case BPF_ALU64 | BPF_DIV | BPF_K: /* dst /= imm */
+                       if (imm == 0)
+                               return -EINVAL;
+-                      else if (imm == 1)
+-                              goto bpf_alu32_trunc;
++                      if (imm == 1) {
++                              if (BPF_OP(code) == BPF_DIV) {
++                                      goto bpf_alu32_trunc;
++                              } else {
++                                      PPC_LI(dst_reg, 0);
++                                      break;
++                              }
++                      }
+ 
+                       PPC_LI32(b2p[TMP_REG_1], imm);
+                       switch (BPF_CLASS(code)) {
+diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
+index 6059b030678b6..c2dc8e5cfbfc2 100644
+--- a/drivers/ata/sata_mv.c
++++ b/drivers/ata/sata_mv.c
+@@ -3907,8 +3907,8 @@ static int mv_chip_id(struct ata_host *host, unsigned 
int board_idx)
+               break;
+ 
+       default:
+-              dev_err(host->dev, "BUG: invalid board index %u\n", board_idx);
+-              return 1;
++              dev_alert(host->dev, "BUG: invalid board index %u\n", 
board_idx);
++              return -EINVAL;
+       }
+ 
+       hpriv->hp_flags = hp_flags;
+diff --git a/drivers/base/regmap/regcache-rbtree.c 
b/drivers/base/regmap/regcache-rbtree.c
+index b1e9aae9a5d0b..e9b7ce8c272c6 100644
+--- a/drivers/base/regmap/regcache-rbtree.c
++++ b/drivers/base/regmap/regcache-rbtree.c
+@@ -295,14 +295,14 @@ static int regcache_rbtree_insert_to_block(struct regmap 
*map,
+       if (!blk)
+               return -ENOMEM;
+ 
++      rbnode->block = blk;
++
+       if (BITS_TO_LONGS(blklen) > BITS_TO_LONGS(rbnode->blklen)) {
+               present = krealloc(rbnode->cache_present,
+                                  BITS_TO_LONGS(blklen) * sizeof(*present),
+                                  GFP_KERNEL);
+-              if (!present) {
+-                      kfree(blk);
++              if (!present)
+                       return -ENOMEM;
+-              }
+ 
+               memset(present + BITS_TO_LONGS(rbnode->blklen), 0,
+                      (BITS_TO_LONGS(blklen) - BITS_TO_LONGS(rbnode->blklen))
+@@ -319,7 +319,6 @@ static int regcache_rbtree_insert_to_block(struct regmap 
*map,
+       }
+ 
+       /* update the rbnode block, its size and the base register */
+-      rbnode->block = blk;
+       rbnode->blklen = blklen;
+       rbnode->base_reg = base_reg;
+       rbnode->cache_present = present;
+diff --git a/drivers/mmc/host/dw_mmc-exynos.c 
b/drivers/mmc/host/dw_mmc-exynos.c
+index a84aa3f1ae854..ae0357481041b 100644
+--- a/drivers/mmc/host/dw_mmc-exynos.c
++++ b/drivers/mmc/host/dw_mmc-exynos.c
+@@ -437,6 +437,18 @@ static s8 dw_mci_exynos_get_best_clksmpl(u8 candiates)
+               }
+       }
+ 
++      /*
++       * If there is no cadiates value, then it needs to return -EIO.
++       * If there are candiates values and don't find bset clk sample value,
++       * then use a first candiates clock sample value.
++       */
++      for (i = 0; i < iter; i++) {
++              __c = ror8(candiates, i);
++              if ((__c & 0x1) == 0x1) {
++                      loc = i;
++                      goto out;
++              }
++      }
+ out:
+       return loc;
+ }
+@@ -467,6 +479,8 @@ static int dw_mci_exynos_execute_tuning(struct dw_mci_slot 
*slot, u32 opcode)
+               priv->tuned_sample = found;
+       } else {
+               ret = -EIO;
++              dev_warn(&mmc->class_dev,
++                      "There is no candiates value about clksmpl!\n");
+       }
+ 
+       return ret;
+diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c 
b/drivers/mmc/host/sdhci-esdhc-imx.c
+index c13a83ebec8ed..3c0e78036805e 100644
+--- a/drivers/mmc/host/sdhci-esdhc-imx.c
++++ b/drivers/mmc/host/sdhci-esdhc-imx.c
+@@ -28,6 +28,7 @@
+ #include <linux/pinctrl/consumer.h>
+ #include <linux/platform_data/mmc-esdhc-imx.h>
+ #include <linux/pm_runtime.h>
++#include <linux/iopoll.h>
+ #include "sdhci-pltfm.h"
+ #include "sdhci-esdhc.h"
+ 
+@@ -927,6 +928,7 @@ static void esdhc_reset_tuning(struct sdhci_host *host)
+       struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+       struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(pltfm_host);
+       u32 ctrl;
++      int ret;
+ 
+       /* Reset the tuning circuit */
+       if (esdhc_is_usdhc(imx_data)) {
+@@ -939,7 +941,22 @@ static void esdhc_reset_tuning(struct sdhci_host *host)
+               } else if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) {
+                       ctrl = readl(host->ioaddr + SDHCI_AUTO_CMD_STATUS);
+                       ctrl &= ~ESDHC_MIX_CTRL_SMPCLK_SEL;
++                      ctrl &= ~ESDHC_MIX_CTRL_EXE_TUNE;
+                       writel(ctrl, host->ioaddr + SDHCI_AUTO_CMD_STATUS);
++                      /* Make sure ESDHC_MIX_CTRL_EXE_TUNE cleared */
++                      ret = readl_poll_timeout(host->ioaddr + 
SDHCI_AUTO_CMD_STATUS,
++                              ctrl, !(ctrl & ESDHC_MIX_CTRL_EXE_TUNE), 1, 50);
++                      if (ret == -ETIMEDOUT)
++                              dev_warn(mmc_dev(host->mmc),
++                               "Warning! clear execute tuning bit failed\n");
++                      /*
++                       * SDHCI_INT_DATA_AVAIL is W1C bit, set this bit will 
clear the
++                       * usdhc IP internal logic flag 
execute_tuning_with_clr_buf, which
++                       * will finally make sure the normal data transfer 
logic correct.
++                       */
++                      ctrl = readl(host->ioaddr + SDHCI_INT_STATUS);
++                      ctrl |= SDHCI_INT_DATA_AVAIL;
++                      writel(ctrl, host->ioaddr + SDHCI_INT_STATUS);
+               }
+       }
+ }
+diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
+index ee3ce0d34dfc5..6ef45f3fefa8a 100644
+--- a/drivers/mmc/host/sdhci.c
++++ b/drivers/mmc/host/sdhci.c
+@@ -1500,6 +1500,12 @@ void sdhci_set_power_noreg(struct sdhci_host *host, 
unsigned char mode,
+                       break;
+               case MMC_VDD_32_33:
+               case MMC_VDD_33_34:
++              /*
++               * 3.4 ~ 3.6V are valid only for those platforms where it's
++               * known that the voltage range is supported by hardware.
++               */
++              case MMC_VDD_34_35:
++              case MMC_VDD_35_36:
+                       pwr = SDHCI_POWER_330;
+                       break;
+               default:
+diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c
+index 7978ba98d0474..71e4392de25ae 100644
+--- a/drivers/mmc/host/vub300.c
++++ b/drivers/mmc/host/vub300.c
+@@ -579,7 +579,7 @@ static void check_vub300_port_status(struct 
vub300_mmc_host *vub300)
+                               GET_SYSTEM_PORT_STATUS,
+                               USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+                               0x0000, 0x0000, &vub300->system_port_status,
+-                              sizeof(vub300->system_port_status), HZ);
++                              sizeof(vub300->system_port_status), 1000);
+       if (sizeof(vub300->system_port_status) == retval)
+               new_system_port_status(vub300);
+ }
+@@ -1242,7 +1242,7 @@ static void __download_offload_pseudocode(struct 
vub300_mmc_host *vub300,
+                                               SET_INTERRUPT_PSEUDOCODE,
+                                               USB_DIR_OUT | USB_TYPE_VENDOR |
+                                               USB_RECIP_DEVICE, 0x0000, 
0x0000,
+-                                              xfer_buffer, xfer_length, HZ);
++                                              xfer_buffer, xfer_length, 1000);
+                       kfree(xfer_buffer);
+                       if (retval < 0) {
+                               strncpy(vub300->vub_name,
+@@ -1289,7 +1289,7 @@ static void __download_offload_pseudocode(struct 
vub300_mmc_host *vub300,
+                                               SET_TRANSFER_PSEUDOCODE,
+                                               USB_DIR_OUT | USB_TYPE_VENDOR |
+                                               USB_RECIP_DEVICE, 0x0000, 
0x0000,
+-                                              xfer_buffer, xfer_length, HZ);
++                                              xfer_buffer, xfer_length, 1000);
+                       kfree(xfer_buffer);
+                       if (retval < 0) {
+                               strncpy(vub300->vub_name,
+@@ -1994,7 +1994,7 @@ static void __set_clock_speed(struct vub300_mmc_host 
*vub300, u8 buf[8],
+               usb_control_msg(vub300->udev, usb_sndctrlpipe(vub300->udev, 0),
+                               SET_CLOCK_SPEED,
+                               USB_DIR_OUT | USB_TYPE_VENDOR | 
USB_RECIP_DEVICE,
+-                              0x00, 0x00, buf, buf_array_size, HZ);
++                              0x00, 0x00, buf, buf_array_size, 1000);
+       if (retval != 8) {
+               dev_err(&vub300->udev->dev, "SET_CLOCK_SPEED"
+                       " %dkHz failed with retval=%d\n", kHzClock, retval);
+@@ -2016,14 +2016,14 @@ static void vub300_mmc_set_ios(struct mmc_host *mmc, 
struct mmc_ios *ios)
+               usb_control_msg(vub300->udev, usb_sndctrlpipe(vub300->udev, 0),
+                               SET_SD_POWER,
+                               USB_DIR_OUT | USB_TYPE_VENDOR | 
USB_RECIP_DEVICE,
+-                              0x0000, 0x0000, NULL, 0, HZ);
++                              0x0000, 0x0000, NULL, 0, 1000);
+               /* must wait for the VUB300 u-proc to boot up */
+               msleep(600);
+       } else if ((ios->power_mode == MMC_POWER_UP) && !vub300->card_powered) {
+               usb_control_msg(vub300->udev, usb_sndctrlpipe(vub300->udev, 0),
+                               SET_SD_POWER,
+                               USB_DIR_OUT | USB_TYPE_VENDOR | 
USB_RECIP_DEVICE,
+-                              0x0001, 0x0000, NULL, 0, HZ);
++                              0x0001, 0x0000, NULL, 0, 1000);
+               msleep(600);
+               vub300->card_powered = 1;
+       } else if (ios->power_mode == MMC_POWER_ON) {
+@@ -2285,14 +2285,14 @@ static int vub300_probe(struct usb_interface 
*interface,
+                               GET_HC_INF0,
+                               USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+                               0x0000, 0x0000, &vub300->hc_info,
+-                              sizeof(vub300->hc_info), HZ);
++                              sizeof(vub300->hc_info), 1000);
+       if (retval < 0)
+               goto error5;
+       retval =
+               usb_control_msg(vub300->udev, usb_sndctrlpipe(vub300->udev, 0),
+                               SET_ROM_WAIT_STATES,
+                               USB_DIR_OUT | USB_TYPE_VENDOR | 
USB_RECIP_DEVICE,
+-                              firmware_rom_wait_states, 0x0000, NULL, 0, HZ);
++                              firmware_rom_wait_states, 0x0000, NULL, 0, 
1000);
+       if (retval < 0)
+               goto error5;
+       dev_info(&vub300->udev->dev,
+@@ -2307,7 +2307,7 @@ static int vub300_probe(struct usb_interface *interface,
+                               GET_SYSTEM_PORT_STATUS,
+                               USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+                               0x0000, 0x0000, &vub300->system_port_status,
+-                              sizeof(vub300->system_port_status), HZ);
++                              sizeof(vub300->system_port_status), 1000);
+       if (retval < 0) {
+               goto error4;
+       } else if (sizeof(vub300->system_port_status) == retval) {
+diff --git a/drivers/net/ethernet/nxp/lpc_eth.c 
b/drivers/net/ethernet/nxp/lpc_eth.c
+index 6bd6c261f2ba9..415ac33341c58 100644
+--- a/drivers/net/ethernet/nxp/lpc_eth.c
++++ b/drivers/net/ethernet/nxp/lpc_eth.c
+@@ -1037,9 +1037,6 @@ static int lpc_eth_close(struct net_device *ndev)
+       napi_disable(&pldat->napi);
+       netif_stop_queue(ndev);
+ 
+-      if (ndev->phydev)
+-              phy_stop(ndev->phydev);
+-
+       spin_lock_irqsave(&pldat->lock, flags);
+       __lpc_eth_reset(pldat);
+       netif_carrier_off(ndev);
+@@ -1047,6 +1044,8 @@ static int lpc_eth_close(struct net_device *ndev)
+       writel(0, LPC_ENET_MAC2(pldat->net_base));
+       spin_unlock_irqrestore(&pldat->lock, flags);
+ 
++      if (ndev->phydev)
++              phy_stop(ndev->phydev);
+       clk_disable_unprepare(pldat->clk);
+ 
+       return 0;
+diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
+index b8a38f32d27f0..5ef9bbbab3dbb 100644
+--- a/drivers/net/phy/mdio_bus.c
++++ b/drivers/net/phy/mdio_bus.c
+@@ -354,7 +354,6 @@ int __mdiobus_register(struct mii_bus *bus, struct module 
*owner)
+       err = device_register(&bus->dev);
+       if (err) {
+               pr_err("mii_bus %s failed to register\n", bus->id);
+-              put_device(&bus->dev);
+               return -EINVAL;
+       }
+ 
+diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
+index ff108611c5e48..1b30636c8bc73 100644
+--- a/drivers/net/usb/lan78xx.c
++++ b/drivers/net/usb/lan78xx.c
+@@ -3615,6 +3615,12 @@ static int lan78xx_probe(struct usb_interface *intf,
+ 
+       dev->maxpacket = usb_maxpacket(dev->udev, dev->pipe_out, 1);
+ 
++      /* Reject broken descriptors. */
++      if (dev->maxpacket == 0) {
++              ret = -ENODEV;
++              goto out4;
++      }
++
+       /* driver requires remote-wakeup capability during autosuspend. */
+       intf->needs_remote_wakeup = 1;
+ 
+diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
+index cb9a18eda798f..c83b6f05ff7f8 100644
+--- a/drivers/net/usb/usbnet.c
++++ b/drivers/net/usb/usbnet.c
+@@ -1788,6 +1788,11 @@ usbnet_probe (struct usb_interface *udev, const struct 
usb_device_id *prod)
+       if (!dev->rx_urb_size)
+               dev->rx_urb_size = dev->hard_mtu;
+       dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1);
++      if (dev->maxpacket == 0) {
++              /* that is a broken device */
++              status = -ENODEV;
++              goto out4;
++      }
+ 
+       /* let userspace know we have a random address */
+       if (ether_addr_equal(net->dev_addr, node_id))
+diff --git a/drivers/nfc/port100.c b/drivers/nfc/port100.c
+index 06bb226c62ef4..0f37acec98ab4 100644
+--- a/drivers/nfc/port100.c
++++ b/drivers/nfc/port100.c
+@@ -1012,11 +1012,11 @@ static u64 port100_get_command_type_mask(struct 
port100 *dev)
+ 
+       skb = port100_alloc_skb(dev, 0);
+       if (!skb)
+-              return -ENOMEM;
++              return 0;
+ 
+       resp = port100_send_cmd_sync(dev, PORT100_CMD_GET_COMMAND_TYPE, skb);
+       if (IS_ERR(resp))
+-              return PTR_ERR(resp);
++              return 0;
+ 
+       if (resp->len < 8)
+               mask = 0;
+diff --git a/net/batman-adv/bridge_loop_avoidance.c 
b/net/batman-adv/bridge_loop_avoidance.c
+index ae1147b8710f3..12ecde765003f 100644
+--- a/net/batman-adv/bridge_loop_avoidance.c
++++ b/net/batman-adv/bridge_loop_avoidance.c
+@@ -1574,10 +1574,14 @@ int batadv_bla_init(struct batadv_priv *bat_priv)
+               return 0;
+ 
+       bat_priv->bla.claim_hash = batadv_hash_new(128);
+-      bat_priv->bla.backbone_hash = batadv_hash_new(32);
++      if (!bat_priv->bla.claim_hash)
++              return -ENOMEM;
+ 
+-      if (!bat_priv->bla.claim_hash || !bat_priv->bla.backbone_hash)
++      bat_priv->bla.backbone_hash = batadv_hash_new(32);
++      if (!bat_priv->bla.backbone_hash) {
++              batadv_hash_destroy(bat_priv->bla.claim_hash);
+               return -ENOMEM;
++      }
+ 
+       batadv_hash_set_lock_class(bat_priv->bla.claim_hash,
+                                  &batadv_claim_hash_lock_class_key);
+diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
+index 5762e52f1d1f6..c93a75f70f015 100644
+--- a/net/batman-adv/main.c
++++ b/net/batman-adv/main.c
+@@ -180,29 +180,41 @@ int batadv_mesh_init(struct net_device *soft_iface)
+       INIT_HLIST_HEAD(&bat_priv->softif_vlan_list);
+       INIT_HLIST_HEAD(&bat_priv->tp_list);
+ 
+-      ret = batadv_v_mesh_init(bat_priv);
+-      if (ret < 0)
+-              goto err;
+-
+       ret = batadv_originator_init(bat_priv);
+-      if (ret < 0)
+-              goto err;
++      if (ret < 0) {
++              atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
++              goto err_orig;
++      }
+ 
+       ret = batadv_tt_init(bat_priv);
+-      if (ret < 0)
+-              goto err;
++      if (ret < 0) {
++              atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
++              goto err_tt;
++      }
++
++      ret = batadv_v_mesh_init(bat_priv);
++      if (ret < 0) {
++              atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
++              goto err_v;
++      }
+ 
+       ret = batadv_bla_init(bat_priv);
+-      if (ret < 0)
+-              goto err;
++      if (ret < 0) {
++              atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
++              goto err_bla;
++      }
+ 
+       ret = batadv_dat_init(bat_priv);
+-      if (ret < 0)
+-              goto err;
++      if (ret < 0) {
++              atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
++              goto err_dat;
++      }
+ 
+       ret = batadv_nc_mesh_init(bat_priv);
+-      if (ret < 0)
+-              goto err;
++      if (ret < 0) {
++              atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
++              goto err_nc;
++      }
+ 
+       batadv_gw_init(bat_priv);
+       batadv_mcast_init(bat_priv);
+@@ -212,8 +224,20 @@ int batadv_mesh_init(struct net_device *soft_iface)
+ 
+       return 0;
+ 
+-err:
+-      batadv_mesh_free(soft_iface);
++err_nc:
++      batadv_dat_free(bat_priv);
++err_dat:
++      batadv_bla_free(bat_priv);
++err_bla:
++      batadv_v_mesh_free(bat_priv);
++err_v:
++      batadv_tt_free(bat_priv);
++err_tt:
++      batadv_originator_free(bat_priv);
++err_orig:
++      batadv_purge_outstanding_packets(bat_priv, NULL);
++      atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE);
++
+       return ret;
+ }
+ 
+diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c
+index 7aacec24958eb..400e31ace4d0e 100644
+--- a/net/batman-adv/network-coding.c
++++ b/net/batman-adv/network-coding.c
+@@ -165,8 +165,10 @@ int batadv_nc_mesh_init(struct batadv_priv *bat_priv)
+                                  &batadv_nc_coding_hash_lock_class_key);
+ 
+       bat_priv->nc.decoding_hash = batadv_hash_new(128);
+-      if (!bat_priv->nc.decoding_hash)
++      if (!bat_priv->nc.decoding_hash) {
++              batadv_hash_destroy(bat_priv->nc.coding_hash);
+               goto err;
++      }
+ 
+       batadv_hash_set_lock_class(bat_priv->nc.decoding_hash,
+                                  &batadv_nc_decoding_hash_lock_class_key);
+diff --git a/net/batman-adv/translation-table.c 
b/net/batman-adv/translation-table.c
+index 9cef38f6cb4de..47b19ad5a02e1 100644
+--- a/net/batman-adv/translation-table.c
++++ b/net/batman-adv/translation-table.c
+@@ -4373,8 +4373,10 @@ int batadv_tt_init(struct batadv_priv *bat_priv)
+               return ret;
+ 
+       ret = batadv_tt_global_init(bat_priv);
+-      if (ret < 0)
++      if (ret < 0) {
++              batadv_tt_local_table_free(bat_priv);
+               return ret;
++      }
+ 
+       batadv_tvlv_handler_register(bat_priv, batadv_tt_tvlv_ogm_handler_v1,
+                                    batadv_tt_tvlv_unicast_handler_v1,
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index d67d424be9192..34cf572cc5dcd 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -640,14 +640,14 @@ static void fnhe_remove_oldest(struct fnhe_hash_bucket 
*hash)
+       kfree_rcu(oldest, rcu);
+ }
+ 
+-static inline u32 fnhe_hashfun(__be32 daddr)
++static u32 fnhe_hashfun(__be32 daddr)
+ {
+-      static u32 fnhe_hashrnd __read_mostly;
+-      u32 hval;
++      static siphash_key_t fnhe_hash_key __read_mostly;
++      u64 hval;
+ 
+-      net_get_random_once(&fnhe_hashrnd, sizeof(fnhe_hashrnd));
+-      hval = jhash_1word((__force u32) daddr, fnhe_hashrnd);
+-      return hash_32(hval, FNHE_HASH_SHIFT);
++      net_get_random_once(&fnhe_hash_key, sizeof(fnhe_hash_key));
++      hval = siphash_1u32((__force u32)daddr, &fnhe_hash_key);
++      return hash_64(hval, FNHE_HASH_SHIFT);
+ }
+ 
+ static void fill_route_from_fnhe(struct rtable *rt, struct fib_nh_exception 
*fnhe)
+diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
+index e943fb28f581b..b26067798dbf1 100644
+--- a/net/sctp/sm_statefuns.c
++++ b/net/sctp/sm_statefuns.c
+@@ -704,6 +704,9 @@ enum sctp_disposition sctp_sf_do_5_1D_ce(struct net *net,
+       struct sock *sk;
+       int error = 0;
+ 
++      if (asoc && !sctp_vtag_verify(chunk, asoc))
++              return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
++
+       /* If the packet is an OOTB packet which is temporarily on the
+        * control endpoint, respond with an ABORT.
+        */
+@@ -718,7 +721,8 @@ enum sctp_disposition sctp_sf_do_5_1D_ce(struct net *net,
+        * in sctp_unpack_cookie().
+        */
+       if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_chunkhdr)))
+-              return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
++              return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
++                                                commands);
+ 
+       /* If the endpoint is not listening or if the number of associations
+        * on the TCP-style socket exceed the max backlog, respond with an
+@@ -2080,9 +2084,11 @@ enum sctp_disposition sctp_sf_do_5_2_4_dupcook(
+        * enough for the chunk header.  Cookie length verification is
+        * done later.
+        */
+-      if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_chunkhdr)))
+-              return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
+-                                                commands);
++      if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_chunkhdr))) {
++              if (!sctp_vtag_verify(chunk, asoc))
++                      asoc = NULL;
++              return sctp_sf_violation_chunklen(net, ep, asoc, type, arg, 
commands);
++      }
+ 
+       /* "Decode" the chunk.  We have no optional parameters so we
+        * are in good shape.
+@@ -3492,6 +3498,9 @@ enum sctp_disposition sctp_sf_ootb(struct net *net,
+ 
+       SCTP_INC_STATS(net, SCTP_MIB_OUTOFBLUES);
+ 
++      if (asoc && !sctp_vtag_verify(chunk, asoc))
++              asoc = NULL;
++
+       ch = (struct sctp_chunkhdr *)chunk->chunk_hdr;
+       do {
+               /* Report violation if the chunk is less then minimal */
+@@ -3607,12 +3616,6 @@ static enum sctp_disposition sctp_sf_shut_8_4_5(
+ 
+       SCTP_INC_STATS(net, SCTP_MIB_OUTCTRLCHUNKS);
+ 
+-      /* If the chunk length is invalid, we don't want to process
+-       * the reset of the packet.
+-       */
+-      if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_chunkhdr)))
+-              return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
+-
+       /* We need to discard the rest of the packet to prevent
+        * potential bomming attacks from additional bundled chunks.
+        * This is documented in SCTP Threats ID.
+@@ -3640,6 +3643,9 @@ enum sctp_disposition sctp_sf_do_8_5_1_E_sa(struct net 
*net,
+ {
+       struct sctp_chunk *chunk = arg;
+ 
++      if (!sctp_vtag_verify(chunk, asoc))
++              asoc = NULL;
++
+       /* Make sure that the SHUTDOWN_ACK chunk has a valid length. */
+       if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_chunkhdr)))
+               return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
+@@ -4475,6 +4481,9 @@ enum sctp_disposition sctp_sf_violation(struct net *net,
+ {
+       struct sctp_chunk *chunk = arg;
+ 
++      if (!sctp_vtag_verify(chunk, asoc))
++              return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
++
+       /* Make sure that the chunk has a valid length. */
+       if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_chunkhdr)))
+               return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
+@@ -6181,6 +6190,7 @@ static struct sctp_packet *sctp_ootb_pkt_new(
+                * yet.
+                */
+               switch (chunk->chunk_hdr->type) {
++              case SCTP_CID_INIT:
+               case SCTP_CID_INIT_ACK:
+               {
+                       struct sctp_initack_chunk *initack;

Reply via email to