From 15a535519172fe129b0dd7de1172385e6026a959 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Sat, 18 Dec 2021 22:02:47 -0500 Subject: [PATCH] Fixes for 4.9 Signed-off-by: Sasha Levin --- ...igbvf-fix-double-free-in-igbvf_probe.patch | 80 +++++++++++++++++++ ...550-mdio-speed-before-talking-to-phy.patch | 56 +++++++++++++ queue-4.9/series | 3 + ...e-fix-bitwise-vs.-logical-or-warning.patch | 76 ++++++++++++++++++ 4 files changed, 215 insertions(+) create mode 100644 queue-4.9/igbvf-fix-double-free-in-igbvf_probe.patch create mode 100644 queue-4.9/ixgbe-set-x550-mdio-speed-before-talking-to-phy.patch create mode 100644 queue-4.9/soc-tegra-fuse-fix-bitwise-vs.-logical-or-warning.patch diff --git a/queue-4.9/igbvf-fix-double-free-in-igbvf_probe.patch b/queue-4.9/igbvf-fix-double-free-in-igbvf_probe.patch new file mode 100644 index 00000000000..f0e7e755ac4 --- /dev/null +++ b/queue-4.9/igbvf-fix-double-free-in-igbvf_probe.patch @@ -0,0 +1,80 @@ +From d18c1a70407682047e026f51d77f28c0993c2e88 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 13 Nov 2021 11:42:34 +0800 +Subject: igbvf: fix double free in `igbvf_probe` + +From: Letu Ren + +[ Upstream commit b6d335a60dc624c0d279333b22c737faa765b028 ] + +In `igbvf_probe`, if register_netdev() fails, the program will go to +label err_hw_init, and then to label err_ioremap. In free_netdev() which +is just below label err_ioremap, there is `list_for_each_entry_safe` and +`netif_napi_del` which aims to delete all entries in `dev->napi_list`. +The program has added an entry `adapter->rx_ring->napi` which is added by +`netif_napi_add` in igbvf_alloc_queues(). However, adapter->rx_ring has +been freed below label err_hw_init. So this a UAF. + +In terms of how to patch the problem, we can refer to igbvf_remove() and +delete the entry before `adapter->rx_ring`. + +The KASAN logs are as follows: + +[ 35.126075] BUG: KASAN: use-after-free in free_netdev+0x1fd/0x450 +[ 35.127170] Read of size 8 at addr ffff88810126d990 by task modprobe/366 +[ 35.128360] +[ 35.128643] CPU: 1 PID: 366 Comm: modprobe Not tainted 5.15.0-rc2+ #14 +[ 35.129789] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.12.0-59-gc9ba5276e321-prebuilt.qemu.org 04/01/2014 +[ 35.131749] Call Trace: +[ 35.132199] dump_stack_lvl+0x59/0x7b +[ 35.132865] print_address_description+0x7c/0x3b0 +[ 35.133707] ? free_netdev+0x1fd/0x450 +[ 35.134378] __kasan_report+0x160/0x1c0 +[ 35.135063] ? free_netdev+0x1fd/0x450 +[ 35.135738] kasan_report+0x4b/0x70 +[ 35.136367] free_netdev+0x1fd/0x450 +[ 35.137006] igbvf_probe+0x121d/0x1a10 [igbvf] +[ 35.137808] ? igbvf_vlan_rx_add_vid+0x100/0x100 [igbvf] +[ 35.138751] local_pci_probe+0x13c/0x1f0 +[ 35.139461] pci_device_probe+0x37e/0x6c0 +[ 35.165526] +[ 35.165806] Allocated by task 366: +[ 35.166414] ____kasan_kmalloc+0xc4/0xf0 +[ 35.167117] foo_kmem_cache_alloc_trace+0x3c/0x50 [igbvf] +[ 35.168078] igbvf_probe+0x9c5/0x1a10 [igbvf] +[ 35.168866] local_pci_probe+0x13c/0x1f0 +[ 35.169565] pci_device_probe+0x37e/0x6c0 +[ 35.179713] +[ 35.179993] Freed by task 366: +[ 35.180539] kasan_set_track+0x4c/0x80 +[ 35.181211] kasan_set_free_info+0x1f/0x40 +[ 35.181942] ____kasan_slab_free+0x103/0x140 +[ 35.182703] kfree+0xe3/0x250 +[ 35.183239] igbvf_probe+0x1173/0x1a10 [igbvf] +[ 35.184040] local_pci_probe+0x13c/0x1f0 + +Fixes: d4e0fe01a38a0 (igbvf: add new driver to support 82576 virtual functions) +Reported-by: Zheyu Ma +Signed-off-by: Letu Ren +Tested-by: Konrad Jankowski +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/igbvf/netdev.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c +index 5428e39fa4e5c..7587a8f98619a 100644 +--- a/drivers/net/ethernet/intel/igbvf/netdev.c ++++ b/drivers/net/ethernet/intel/igbvf/netdev.c +@@ -2846,6 +2846,7 @@ static int igbvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + return 0; + + err_hw_init: ++ netif_napi_del(&adapter->rx_ring->napi); + kfree(adapter->tx_ring); + kfree(adapter->rx_ring); + err_sw_init: +-- +2.33.0 + diff --git a/queue-4.9/ixgbe-set-x550-mdio-speed-before-talking-to-phy.patch b/queue-4.9/ixgbe-set-x550-mdio-speed-before-talking-to-phy.patch new file mode 100644 index 00000000000..68b1efed010 --- /dev/null +++ b/queue-4.9/ixgbe-set-x550-mdio-speed-before-talking-to-phy.patch @@ -0,0 +1,56 @@ +From 17d5c93dc9170cff6bacc6ae1cae14c5c7a8007d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 1 Nov 2021 18:39:36 -0700 +Subject: ixgbe: set X550 MDIO speed before talking to PHY + +From: Cyril Novikov + +[ Upstream commit bf0a375055bd1afbbf02a0ef45f7655da7b71317 ] + +The MDIO bus speed must be initialized before talking to the PHY the first +time in order to avoid talking to it using a speed that the PHY doesn't +support. + +This fixes HW initialization error -17 (IXGBE_ERR_PHY_ADDR_INVALID) on +Denverton CPUs (a.k.a. the Atom C3000 family) on ports with a 10Gb network +plugged in. On those devices, HLREG0[MDCSPD] resets to 1, which combined +with the 10Gb network results in a 24MHz MDIO speed, which is apparently +too fast for the connected PHY. PHY register reads over MDIO bus return +garbage, leading to initialization failure. + +Reproduced with Linux kernel 4.19 and 5.15-rc7. Can be reproduced using +the following setup: + +* Use an Atom C3000 family system with at least one X552 LAN on the SoC +* Disable PXE or other BIOS network initialization if possible + (the interface must not be initialized before Linux boots) +* Connect a live 10Gb Ethernet cable to an X550 port +* Power cycle (not reset, doesn't always work) the system and boot Linux +* Observe: ixgbe interfaces w/ 10GbE cables plugged in fail with error -17 + +Fixes: e84db7272798 ("ixgbe: Introduce function to control MDIO speed") +Signed-off-by: Cyril Novikov +Reviewed-by: Andrew Lunn +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c +index 8466f3874a285..5029db8835d7d 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c +@@ -2597,6 +2597,9 @@ static s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw) + /* flush pending Tx transactions */ + ixgbe_clear_tx_pending(hw); + ++ /* set MDIO speed before talking to the PHY in case it's the 1st time */ ++ ixgbe_set_mdio_speed(hw); ++ + /* PHY ops must be identified and initialized prior to reset */ + + /* Identify PHY and related function pointers */ +-- +2.33.0 + diff --git a/queue-4.9/series b/queue-4.9/series index 2c7bff991d1..7e14415e9cc 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -9,3 +9,6 @@ mac80211-send-addba-requests-using-the-tid-queue-of-the-aggregation-session.patc recordmcount.pl-look-for-jgnop-instruction-as-well-as-bcrl-on-s390.patch dm-btree-remove-fix-use-after-free-in-rebalance_children.patch nfsd-fix-use-after-free-due-to-delegation-race.patch +soc-tegra-fuse-fix-bitwise-vs.-logical-or-warning.patch +igbvf-fix-double-free-in-igbvf_probe.patch +ixgbe-set-x550-mdio-speed-before-talking-to-phy.patch diff --git a/queue-4.9/soc-tegra-fuse-fix-bitwise-vs.-logical-or-warning.patch b/queue-4.9/soc-tegra-fuse-fix-bitwise-vs.-logical-or-warning.patch new file mode 100644 index 00000000000..405ff6d34b2 --- /dev/null +++ b/queue-4.9/soc-tegra-fuse-fix-bitwise-vs.-logical-or-warning.patch @@ -0,0 +1,76 @@ +From 73a51c91d7d6f0616d7220cad487311ca3293d2f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Dec 2021 09:55:29 -0700 +Subject: soc/tegra: fuse: Fix bitwise vs. logical OR warning +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Nathan Chancellor + +[ Upstream commit a7083763619f7485ccdade160deb81737cf2732f ] + +A new warning in clang points out two instances where boolean +expressions are being used with a bitwise OR instead of logical OR: + +drivers/soc/tegra/fuse/speedo-tegra20.c:72:9: warning: use of bitwise '|' with boolean operands [-Wbitwise-instead-of-logical] + reg = tegra_fuse_read_spare(i) | + ^~~~~~~~~~~~~~~~~~~~~~~~~~ + || +drivers/soc/tegra/fuse/speedo-tegra20.c:72:9: note: cast one or both operands to int to silence this warning +drivers/soc/tegra/fuse/speedo-tegra20.c:87:9: warning: use of bitwise '|' with boolean operands [-Wbitwise-instead-of-logical] + reg = tegra_fuse_read_spare(i) | + ^~~~~~~~~~~~~~~~~~~~~~~~~~ + || +drivers/soc/tegra/fuse/speedo-tegra20.c:87:9: note: cast one or both operands to int to silence this warning +2 warnings generated. + +The motivation for the warning is that logical operations short circuit +while bitwise operations do not. + +In this instance, tegra_fuse_read_spare() is not semantically returning +a boolean, it is returning a bit value. Use u32 for its return type so +that it can be used with either bitwise or boolean operators without any +warnings. + +Fixes: 25cd5a391478 ("ARM: tegra: Add speedo-based process identification") +Link: https://github.com/ClangBuiltLinux/linux/issues/1488 +Suggested-by: Michał Mirosław +Signed-off-by: Nathan Chancellor +Reviewed-by: Nick Desaulniers +Signed-off-by: Thierry Reding +Signed-off-by: Sasha Levin +--- + drivers/soc/tegra/fuse/fuse-tegra.c | 2 +- + drivers/soc/tegra/fuse/fuse.h | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c +index c4f5e5bbb8dce..9397e8ba26469 100644 +--- a/drivers/soc/tegra/fuse/fuse-tegra.c ++++ b/drivers/soc/tegra/fuse/fuse-tegra.c +@@ -176,7 +176,7 @@ static struct platform_driver tegra_fuse_driver = { + }; + module_platform_driver(tegra_fuse_driver); + +-bool __init tegra_fuse_read_spare(unsigned int spare) ++u32 __init tegra_fuse_read_spare(unsigned int spare) + { + unsigned int offset = fuse->soc->info->spare + spare * 4; + +diff --git a/drivers/soc/tegra/fuse/fuse.h b/drivers/soc/tegra/fuse/fuse.h +index 10c2076d5089a..f368bd5373088 100644 +--- a/drivers/soc/tegra/fuse/fuse.h ++++ b/drivers/soc/tegra/fuse/fuse.h +@@ -62,7 +62,7 @@ struct tegra_fuse { + void tegra_init_revision(void); + void tegra_init_apbmisc(void); + +-bool __init tegra_fuse_read_spare(unsigned int spare); ++u32 __init tegra_fuse_read_spare(unsigned int spare); + u32 __init tegra_fuse_read_early(unsigned int offset); + + #ifdef CONFIG_ARCH_TEGRA_2x_SOC +-- +2.33.0 + -- 2.47.3