From: Sasha Levin Date: Mon, 4 Oct 2021 03:18:16 +0000 (-0400) Subject: Fixes for 4.4 X-Git-Tag: v4.4.286~42 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=910d8d35efb2aeedbc00362fad2af5a73d8d9c2c;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 4.4 Signed-off-by: Sasha Levin --- 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 index 00000000000..29b11cc1407 --- /dev/null +++ b/queue-4.4/e100-fix-buffer-overrun-in-e100_get_regs.patch @@ -0,0 +1,107 @@ +From 004116671a106318292de5a3aa862d7ce7aa9595 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Sep 2021 10:52:37 -0700 +Subject: e100: fix buffer overrun in e100_get_regs + +From: Jacob Keller + +[ 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 +Signed-off-by: Jacob Keller +Tested-by: Jacob Keller +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..2836b80f425 --- /dev/null +++ b/queue-4.4/e100-fix-length-calculation-in-e100_get_regs_len.patch @@ -0,0 +1,50 @@ +From 8cfd3ae240712ba73712371baed07f7c5ffa0e4a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Sep 2021 10:52:36 -0700 +Subject: e100: fix length calculation in e100_get_regs_len + +From: Jacob Keller + +[ 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 +Signed-off-by: Jacob Keller +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..4577c62649b --- /dev/null +++ b/queue-4.4/ipvs-check-that-ip_vs_conn_tab_bits-is-between-8-and.patch @@ -0,0 +1,46 @@ +From 6505162c5bcb25c72031afd538e4a5a6562ea0cf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Andrea Claudi +Acked-by: Julian Anastasov +Acked-by: Simon Horman +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-4.4/series b/queue-4.4/series index 20d45812110..304e4a7887b 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -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