]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 4.4
authorSasha Levin <sashal@kernel.org>
Mon, 4 Oct 2021 03:18:16 +0000 (23:18 -0400)
committerSasha Levin <sashal@kernel.org>
Mon, 4 Oct 2021 03:18:16 +0000 (23:18 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-4.4/e100-fix-buffer-overrun-in-e100_get_regs.patch [new file with mode: 0644]
queue-4.4/e100-fix-length-calculation-in-e100_get_regs_len.patch [new file with mode: 0644]
queue-4.4/ipvs-check-that-ip_vs_conn_tab_bits-is-between-8-and.patch [new file with mode: 0644]
queue-4.4/series

diff --git a/queue-4.4/e100-fix-buffer-overrun-in-e100_get_regs.patch b/queue-4.4/e100-fix-buffer-overrun-in-e100_get_regs.patch
new file mode 100644 (file)
index 0000000..29b11cc
--- /dev/null
@@ -0,0 +1,107 @@
+From 004116671a106318292de5a3aa862d7ce7aa9595 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Sep 2021 10:52:37 -0700
+Subject: e100: fix buffer overrun in e100_get_regs
+
+From: Jacob Keller <jacob.e.keller@intel.com>
+
+[ Upstream commit 51032e6f17ce990d06123ad7307f258c50d25aa7 ]
+
+The e100_get_regs function is used to implement a simple register dump
+for the e100 device. The data is broken into a couple of MAC control
+registers, and then a series of PHY registers, followed by a memory dump
+buffer.
+
+The total length of the register dump is defined as (1 + E100_PHY_REGS)
+* sizeof(u32) + sizeof(nic->mem->dump_buf).
+
+The logic for filling in the PHY registers uses a convoluted inverted
+count for loop which counts from E100_PHY_REGS (0x1C) down to 0, and
+assigns the slots 1 + E100_PHY_REGS - i. The first loop iteration will
+fill in [1] and the final loop iteration will fill in [1 + 0x1C]. This
+is actually one more than the supposed number of PHY registers.
+
+The memory dump buffer is then filled into the space at
+[2 + E100_PHY_REGS] which will cause that memcpy to assign 4 bytes past
+the total size.
+
+The end result is that we overrun the total buffer size allocated by the
+kernel, which could lead to a panic or other issues due to memory
+corruption.
+
+It is difficult to determine the actual total number of registers
+here. The only 8255x datasheet I could find indicates there are 28 total
+MDI registers. However, we're reading 29 here, and reading them in
+reverse!
+
+In addition, the ethtool e100 register dump interface appears to read
+the first PHY register to determine if the device is in MDI or MDIx
+mode. This doesn't appear to be documented anywhere within the 8255x
+datasheet. I can only assume it must be in register 28 (the extra
+register we're reading here).
+
+Lets not change any of the intended meaning of what we copy here. Just
+extend the space by 4 bytes to account for the extra register and
+continue copying the data out in the same order.
+
+Change the E100_PHY_REGS value to be the correct total (29) so that the
+total register dump size is calculated properly. Fix the offset for
+where we copy the dump buffer so that it doesn't overrun the total size.
+
+Re-write the for loop to use counting up instead of the convoluted
+down-counting. Correct the mdio_read offset to use the 0-based register
+offsets, but maintain the bizarre reverse ordering so that we have the
+ABI expected by applications like ethtool. This requires and additional
+subtraction of 1. It seems a bit odd but it makes the flow of assignment
+into the register buffer easier to follow.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: Felicitas Hetzelt <felicitashetzelt@gmail.com>
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Tested-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/e100.c | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c
+index abb65ed9492b..aa556e4f9051 100644
+--- a/drivers/net/ethernet/intel/e100.c
++++ b/drivers/net/ethernet/intel/e100.c
+@@ -2462,7 +2462,7 @@ static void e100_get_drvinfo(struct net_device *netdev,
+               sizeof(info->bus_info));
+ }
+-#define E100_PHY_REGS 0x1C
++#define E100_PHY_REGS 0x1D
+ static int e100_get_regs_len(struct net_device *netdev)
+ {
+       struct nic *nic = netdev_priv(netdev);
+@@ -2484,14 +2484,18 @@ static void e100_get_regs(struct net_device *netdev,
+       buff[0] = ioread8(&nic->csr->scb.cmd_hi) << 24 |
+               ioread8(&nic->csr->scb.cmd_lo) << 16 |
+               ioread16(&nic->csr->scb.status);
+-      for (i = E100_PHY_REGS; i >= 0; i--)
+-              buff[1 + E100_PHY_REGS - i] =
+-                      mdio_read(netdev, nic->mii.phy_id, i);
++      for (i = 0; i < E100_PHY_REGS; i++)
++              /* Note that we read the registers in reverse order. This
++               * ordering is the ABI apparently used by ethtool and other
++               * applications.
++               */
++              buff[1 + i] = mdio_read(netdev, nic->mii.phy_id,
++                                      E100_PHY_REGS - 1 - i);
+       memset(nic->mem->dump_buf, 0, sizeof(nic->mem->dump_buf));
+       e100_exec_cb(nic, NULL, e100_dump);
+       msleep(10);
+-      memcpy(&buff[2 + E100_PHY_REGS], nic->mem->dump_buf,
+-              sizeof(nic->mem->dump_buf));
++      memcpy(&buff[1 + E100_PHY_REGS], nic->mem->dump_buf,
++             sizeof(nic->mem->dump_buf));
+ }
+ static void e100_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+-- 
+2.33.0
+
diff --git a/queue-4.4/e100-fix-length-calculation-in-e100_get_regs_len.patch b/queue-4.4/e100-fix-length-calculation-in-e100_get_regs_len.patch
new file mode 100644 (file)
index 0000000..2836b80
--- /dev/null
@@ -0,0 +1,50 @@
+From 8cfd3ae240712ba73712371baed07f7c5ffa0e4a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Sep 2021 10:52:36 -0700
+Subject: e100: fix length calculation in e100_get_regs_len
+
+From: Jacob Keller <jacob.e.keller@intel.com>
+
+[ Upstream commit 4329c8dc110b25d5f04ed20c6821bb60deff279f ]
+
+commit abf9b902059f ("e100: cleanup unneeded math") tried to simplify
+e100_get_regs_len and remove a double 'divide and then multiply'
+calculation that the e100_reg_regs_len function did.
+
+This change broke the size calculation entirely as it failed to account
+for the fact that the numbered registers are actually 4 bytes wide and
+not 1 byte. This resulted in a significant under allocation of the
+register buffer used by e100_get_regs.
+
+Fix this by properly multiplying the register count by u32 first before
+adding the size of the dump buffer.
+
+Fixes: abf9b902059f ("e100: cleanup unneeded math")
+Reported-by: Felicitas Hetzelt <felicitashetzelt@gmail.com>
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/e100.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c
+index 9035cb5fc70d..abb65ed9492b 100644
+--- a/drivers/net/ethernet/intel/e100.c
++++ b/drivers/net/ethernet/intel/e100.c
+@@ -2466,7 +2466,11 @@ static void e100_get_drvinfo(struct net_device *netdev,
+ static int e100_get_regs_len(struct net_device *netdev)
+ {
+       struct nic *nic = netdev_priv(netdev);
+-      return 1 + E100_PHY_REGS + sizeof(nic->mem->dump_buf);
++
++      /* We know the number of registers, and the size of the dump buffer.
++       * Calculate the total size in bytes.
++       */
++      return (1 + E100_PHY_REGS) * sizeof(u32) + sizeof(nic->mem->dump_buf);
+ }
+ static void e100_get_regs(struct net_device *netdev,
+-- 
+2.33.0
+
diff --git a/queue-4.4/ipvs-check-that-ip_vs_conn_tab_bits-is-between-8-and.patch b/queue-4.4/ipvs-check-that-ip_vs_conn_tab_bits-is-between-8-and.patch
new file mode 100644 (file)
index 0000000..4577c62
--- /dev/null
@@ -0,0 +1,46 @@
+From 6505162c5bcb25c72031afd538e4a5a6562ea0cf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Sep 2021 18:08:39 +0200
+Subject: ipvs: check that ip_vs_conn_tab_bits is between 8 and 20
+
+From: Andrea Claudi <aclaudi@redhat.com>
+
+[ Upstream commit 69e73dbfda14fbfe748d3812da1244cce2928dcb ]
+
+ip_vs_conn_tab_bits may be provided by the user through the
+conn_tab_bits module parameter. If this value is greater than 31, or
+less than 0, the shift operator used to derive tab_size causes undefined
+behaviour.
+
+Fix this checking ip_vs_conn_tab_bits value to be in the range specified
+in ipvs Kconfig. If not, simply use default value.
+
+Fixes: 6f7edb4881bf ("IPVS: Allow boot time change of hash size")
+Reported-by: Yi Chen <yiche@redhat.com>
+Signed-off-by: Andrea Claudi <aclaudi@redhat.com>
+Acked-by: Julian Anastasov <ja@ssi.bg>
+Acked-by: Simon Horman <horms@verge.net.au>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/ipvs/ip_vs_conn.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
+index 85ca189bdc3d..de196dd95dcd 100644
+--- a/net/netfilter/ipvs/ip_vs_conn.c
++++ b/net/netfilter/ipvs/ip_vs_conn.c
+@@ -1368,6 +1368,10 @@ int __init ip_vs_conn_init(void)
+       int idx;
+       /* Compute size and mask */
++      if (ip_vs_conn_tab_bits < 8 || ip_vs_conn_tab_bits > 20) {
++              pr_info("conn_tab_bits not in [8, 20]. Using default value\n");
++              ip_vs_conn_tab_bits = CONFIG_IP_VS_TAB_BITS;
++      }
+       ip_vs_conn_tab_size = 1 << ip_vs_conn_tab_bits;
+       ip_vs_conn_tab_mask = ip_vs_conn_tab_size - 1;
+-- 
+2.33.0
+
index 20d458121107dae0193033541969786a94eddc93..304e4a7887ba1c288fb0390fb03e3aafacc1f2ae 100644 (file)
@@ -24,3 +24,6 @@ spi-fix-tegra20-build-with-config_pm-n.patch
 qnx4-work-around-gcc-false-positive-warning-bug.patch
 tty-fix-out-of-bound-vmalloc-access-in-imageblit.patch
 mac80211-fix-use-after-free-in-ccmp-gcmp-rx.patch
+ipvs-check-that-ip_vs_conn_tab_bits-is-between-8-and.patch
+e100-fix-length-calculation-in-e100_get_regs_len.patch
+e100-fix-buffer-overrun-in-e100_get_regs.patch