From: Sasha Levin Date: Mon, 30 Jan 2023 03:56:03 +0000 (-0500) Subject: Fixes for 5.10 X-Git-Tag: v5.10.166~41 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a936bfbd466830b1d64f218b81a44480e5e3ceb8;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.10 Signed-off-by: Sasha Levin --- diff --git a/queue-5.10/i2c-designware-use-casting-of-u64-in-clock-multiplic.patch b/queue-5.10/i2c-designware-use-casting-of-u64-in-clock-multiplic.patch new file mode 100644 index 00000000000..98148f4b031 --- /dev/null +++ b/queue-5.10/i2c-designware-use-casting-of-u64-in-clock-multiplic.patch @@ -0,0 +1,66 @@ +From 715c91e4e18ca616eabc3e373958cbabb91311c8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 Dec 2022 19:59:00 +0000 +Subject: i2c: designware: use casting of u64 in clock multiplication to avoid + overflow + +From: Lareine Khawaly + +[ Upstream commit c8c37bc514514999e62a17e95160ed9ebf75ca8d ] + +In functions i2c_dw_scl_lcnt() and i2c_dw_scl_hcnt() may have overflow +by depending on the values of the given parameters including the ic_clk. +For example in our use case where ic_clk is larger than one million, +multiplication of ic_clk * 4700 will result in 32 bit overflow. + +Add cast of u64 to the calculation to avoid multiplication overflow, and +use the corresponding define for divide. + +Fixes: 2373f6b9744d ("i2c-designware: split of i2c-designware.c into core and bus specific parts") +Signed-off-by: Lareine Khawaly +Signed-off-by: Hanna Hawa +Reviewed-by: Andy Shevchenko +Acked-by: Jarkko Nikula +Signed-off-by: Wolfram Sang +Signed-off-by: Sasha Levin +--- + drivers/i2c/busses/i2c-designware-common.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/i2c/busses/i2c-designware-common.c b/drivers/i2c/busses/i2c-designware-common.c +index 73a4ef8130e6..682fffaab2b4 100644 +--- a/drivers/i2c/busses/i2c-designware-common.c ++++ b/drivers/i2c/busses/i2c-designware-common.c +@@ -348,7 +348,8 @@ u32 i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset) + * + * If your hardware is free from tHD;STA issue, try this one. + */ +- return DIV_ROUND_CLOSEST(ic_clk * tSYMBOL, MICRO) - 8 + offset; ++ return DIV_ROUND_CLOSEST_ULL((u64)ic_clk * tSYMBOL, MICRO) - ++ 8 + offset; + else + /* + * Conditional expression: +@@ -364,7 +365,8 @@ u32 i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset) + * The reason why we need to take into account "tf" here, + * is the same as described in i2c_dw_scl_lcnt(). + */ +- return DIV_ROUND_CLOSEST(ic_clk * (tSYMBOL + tf), MICRO) - 3 + offset; ++ return DIV_ROUND_CLOSEST_ULL((u64)ic_clk * (tSYMBOL + tf), MICRO) - ++ 3 + offset; + } + + u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset) +@@ -380,7 +382,8 @@ u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset) + * account the fall time of SCL signal (tf). Default tf value + * should be 0.3 us, for safety. + */ +- return DIV_ROUND_CLOSEST(ic_clk * (tLOW + tf), MICRO) - 1 + offset; ++ return DIV_ROUND_CLOSEST_ULL((u64)ic_clk * (tLOW + tf), MICRO) - ++ 1 + offset; + } + + int i2c_dw_set_sda_hold(struct dw_i2c_dev *dev) +-- +2.39.0 + diff --git a/queue-5.10/i2c-designware-use-div_round_closest-macro.patch b/queue-5.10/i2c-designware-use-div_round_closest-macro.patch new file mode 100644 index 00000000000..e12fa6fe115 --- /dev/null +++ b/queue-5.10/i2c-designware-use-div_round_closest-macro.patch @@ -0,0 +1,94 @@ +From b7dda10960004c3cc6ad9dcf084abb3e28c9adb0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 12 Jul 2021 17:20:26 +0300 +Subject: i2c: designware: Use DIV_ROUND_CLOSEST() macro + +From: Andy Shevchenko + +[ Upstream commit c045214a0f31dd5d6be716ed2f119b57b6c5d3a2 ] + +Instead of open-coding DIV_ROUND_CLOSEST() and similar use the macros directly. +While at it, replace numbers with predefined SI metric prefixes. + +No functional change intended. + +Signed-off-by: Andy Shevchenko +Signed-off-by: Wolfram Sang +Stable-dep-of: c8c37bc51451 ("i2c: designware: use casting of u64 in clock multiplication to avoid overflow") +Signed-off-by: Sasha Levin +--- + drivers/i2c/busses/i2c-designware-common.c | 8 ++++---- + drivers/i2c/busses/i2c-designware-platdrv.c | 5 +++-- + 2 files changed, 7 insertions(+), 6 deletions(-) + +diff --git a/drivers/i2c/busses/i2c-designware-common.c b/drivers/i2c/busses/i2c-designware-common.c +index 9468c6c89b3f..73a4ef8130e6 100644 +--- a/drivers/i2c/busses/i2c-designware-common.c ++++ b/drivers/i2c/busses/i2c-designware-common.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + + #include "i2c-designware-core.h" + +@@ -347,7 +348,7 @@ u32 i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset) + * + * If your hardware is free from tHD;STA issue, try this one. + */ +- return (ic_clk * tSYMBOL + 500000) / 1000000 - 8 + offset; ++ return DIV_ROUND_CLOSEST(ic_clk * tSYMBOL, MICRO) - 8 + offset; + else + /* + * Conditional expression: +@@ -363,8 +364,7 @@ u32 i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset) + * The reason why we need to take into account "tf" here, + * is the same as described in i2c_dw_scl_lcnt(). + */ +- return (ic_clk * (tSYMBOL + tf) + 500000) / 1000000 +- - 3 + offset; ++ return DIV_ROUND_CLOSEST(ic_clk * (tSYMBOL + tf), MICRO) - 3 + offset; + } + + u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset) +@@ -380,7 +380,7 @@ u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset) + * account the fall time of SCL signal (tf). Default tf value + * should be 0.3 us, for safety. + */ +- return ((ic_clk * (tLOW + tf) + 500000) / 1000000) - 1 + offset; ++ return DIV_ROUND_CLOSEST(ic_clk * (tLOW + tf), MICRO) - 1 + offset; + } + + int i2c_dw_set_sda_hold(struct dw_i2c_dev *dev) +diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c +index ad91c7c0faa5..474754151725 100644 +--- a/drivers/i2c/busses/i2c-designware-platdrv.c ++++ b/drivers/i2c/busses/i2c-designware-platdrv.c +@@ -32,12 +32,13 @@ + #include + #include + #include ++#include + + #include "i2c-designware-core.h" + + static u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev) + { +- return clk_get_rate(dev->clk)/1000; ++ return clk_get_rate(dev->clk) / KILO; + } + + #ifdef CONFIG_ACPI +@@ -284,7 +285,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) + + if (!dev->sda_hold_time && t->sda_hold_ns) + dev->sda_hold_time = +- div_u64(clk_khz * t->sda_hold_ns + 500000, 1000000); ++ DIV_S64_ROUND_CLOSEST(clk_khz * t->sda_hold_ns, MICRO); + } + + adap = &dev->adapter; +-- +2.39.0 + diff --git a/queue-5.10/ipv4-prevent-potential-spectre-v1-gadget-in-fib_metr.patch b/queue-5.10/ipv4-prevent-potential-spectre-v1-gadget-in-fib_metr.patch new file mode 100644 index 00000000000..4b8bfd4a0ac --- /dev/null +++ b/queue-5.10/ipv4-prevent-potential-spectre-v1-gadget-in-fib_metr.patch @@ -0,0 +1,51 @@ +From 2ab1727ad1a2941ee595b6e767cba968be0bf8b3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Jan 2023 13:31:40 +0000 +Subject: ipv4: prevent potential spectre v1 gadget in fib_metrics_match() + +From: Eric Dumazet + +[ Upstream commit 5e9398a26a92fc402d82ce1f97cc67d832527da0 ] + +if (!type) + continue; + if (type > RTAX_MAX) + return false; + ... + fi_val = fi->fib_metrics->metrics[type - 1]; + +@type being used as an array index, we need to prevent +cpu speculation or risk leaking kernel memory content. + +Fixes: 5f9ae3d9e7e4 ("ipv4: do metrics match when looking up and deleting a route") +Signed-off-by: Eric Dumazet +Link: https://lore.kernel.org/r/20230120133140.3624204-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv4/fib_semantics.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c +index ab9fcc6231b8..4e94796ccdbd 100644 +--- a/net/ipv4/fib_semantics.c ++++ b/net/ipv4/fib_semantics.c +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -1021,6 +1022,7 @@ bool fib_metrics_match(struct fib_config *cfg, struct fib_info *fi) + if (type > RTAX_MAX) + return false; + ++ type = array_index_nospec(type, RTAX_MAX + 1); + if (type == RTAX_CC_ALGO) { + char tmp[TCP_CA_NAME_MAX]; + bool ecn_ca = false; +-- +2.39.0 + diff --git a/queue-5.10/ipv4-prevent-potential-spectre-v1-gadget-in-ip_metri.patch b/queue-5.10/ipv4-prevent-potential-spectre-v1-gadget-in-ip_metri.patch new file mode 100644 index 00000000000..cea6c7ee499 --- /dev/null +++ b/queue-5.10/ipv4-prevent-potential-spectre-v1-gadget-in-ip_metri.patch @@ -0,0 +1,50 @@ +From 5ccf5d4453633f28c71472146bb3691ba58f594a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Jan 2023 13:30:40 +0000 +Subject: ipv4: prevent potential spectre v1 gadget in ip_metrics_convert() + +From: Eric Dumazet + +[ Upstream commit 1d1d63b612801b3f0a39b7d4467cad0abd60e5c8 ] + +if (!type) + continue; + if (type > RTAX_MAX) + return -EINVAL; + ... + metrics[type - 1] = val; + +@type being used as an array index, we need to prevent +cpu speculation or risk leaking kernel memory content. + +Fixes: 6cf9dfd3bd62 ("net: fib: move metrics parsing to a helper") +Signed-off-by: Eric Dumazet +Link: https://lore.kernel.org/r/20230120133040.3623463-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv4/metrics.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/net/ipv4/metrics.c b/net/ipv4/metrics.c +index 3205d5f7c8c9..4966ac2aaf87 100644 +--- a/net/ipv4/metrics.c ++++ b/net/ipv4/metrics.c +@@ -1,5 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0-only + #include ++#include + #include + #include + #include +@@ -28,6 +29,7 @@ static int ip_metrics_convert(struct net *net, struct nlattr *fc_mx, + return -EINVAL; + } + ++ type = array_index_nospec(type, RTAX_MAX + 1); + if (type == RTAX_CC_ALGO) { + char tmp[TCP_CA_NAME_MAX]; + +-- +2.39.0 + diff --git a/queue-5.10/net-fix-uaf-in-netns-ops-registration-error-path.patch b/queue-5.10/net-fix-uaf-in-netns-ops-registration-error-path.patch new file mode 100644 index 00000000000..d65ebd35f64 --- /dev/null +++ b/queue-5.10/net-fix-uaf-in-netns-ops-registration-error-path.patch @@ -0,0 +1,84 @@ +From b23a0e8f839eca99bd06e600296647465a0a141c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Jan 2023 19:55:45 +0100 +Subject: net: fix UaF in netns ops registration error path + +From: Paolo Abeni + +[ Upstream commit 71ab9c3e2253619136c31c89dbb2c69305cc89b1 ] + +If net_assign_generic() fails, the current error path in ops_init() tries +to clear the gen pointer slot. Anyway, in such error path, the gen pointer +itself has not been modified yet, and the existing and accessed one is +smaller than the accessed index, causing an out-of-bounds error: + + BUG: KASAN: slab-out-of-bounds in ops_init+0x2de/0x320 + Write of size 8 at addr ffff888109124978 by task modprobe/1018 + + CPU: 2 PID: 1018 Comm: modprobe Not tainted 6.2.0-rc2.mptcp_ae5ac65fbed5+ #1641 + Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.1-2.fc37 04/01/2014 + Call Trace: + + dump_stack_lvl+0x6a/0x9f + print_address_description.constprop.0+0x86/0x2b5 + print_report+0x11b/0x1fb + kasan_report+0x87/0xc0 + ops_init+0x2de/0x320 + register_pernet_operations+0x2e4/0x750 + register_pernet_subsys+0x24/0x40 + tcf_register_action+0x9f/0x560 + do_one_initcall+0xf9/0x570 + do_init_module+0x190/0x650 + load_module+0x1fa5/0x23c0 + __do_sys_finit_module+0x10d/0x1b0 + do_syscall_64+0x58/0x80 + entry_SYSCALL_64_after_hwframe+0x72/0xdc + RIP: 0033:0x7f42518f778d + Code: 00 c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 + 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff + ff 73 01 c3 48 8b 0d cb 56 2c 00 f7 d8 64 89 01 48 + RSP: 002b:00007fff96869688 EFLAGS: 00000246 ORIG_RAX: 0000000000000139 + RAX: ffffffffffffffda RBX: 00005568ef7f7c90 RCX: 00007f42518f778d + RDX: 0000000000000000 RSI: 00005568ef41d796 RDI: 0000000000000003 + RBP: 00005568ef41d796 R08: 0000000000000000 R09: 0000000000000000 + R10: 0000000000000003 R11: 0000000000000246 R12: 0000000000000000 + R13: 00005568ef7f7d30 R14: 0000000000040000 R15: 0000000000000000 + + +This change addresses the issue by skipping the gen pointer +de-reference in the mentioned error-path. + +Found by code inspection and verified with explicit error injection +on a kasan-enabled kernel. + +Fixes: d266935ac43d ("net: fix UAF issue in nfqnl_nf_hook_drop() when ops_init() failed") +Signed-off-by: Paolo Abeni +Reviewed-by: Simon Horman +Link: https://lore.kernel.org/r/cec4e0f3bb2c77ac03a6154a8508d3930beb5f0f.1674154348.git.pabeni@redhat.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/core/net_namespace.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c +index a3b7d965e9c0..e05dd4f3279a 100644 +--- a/net/core/net_namespace.c ++++ b/net/core/net_namespace.c +@@ -155,12 +155,12 @@ static int ops_init(const struct pernet_operations *ops, struct net *net) + return 0; + + if (ops->id && ops->size) { +-cleanup: + ng = rcu_dereference_protected(net->gen, + lockdep_is_held(&pernet_ops_rwsem)); + ng->ptr[*ops->id] = NULL; + } + ++cleanup: + kfree(data); + + out: +-- +2.39.0 + diff --git a/queue-5.10/net-mdio-mux-meson-g12a-force-internal-phy-off-on-mu.patch b/queue-5.10/net-mdio-mux-meson-g12a-force-internal-phy-off-on-mu.patch new file mode 100644 index 00000000000..60fd601d4d6 --- /dev/null +++ b/queue-5.10/net-mdio-mux-meson-g12a-force-internal-phy-off-on-mu.patch @@ -0,0 +1,80 @@ +From 47e3db8f3df48691fc2351ac783fe5ee12cb1aa7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Jan 2023 11:11:57 +0100 +Subject: net: mdio-mux-meson-g12a: force internal PHY off on mux switch + +From: Jerome Brunet + +[ Upstream commit 7083df59abbc2b7500db312cac706493be0273ff ] + +Force the internal PHY off then on when switching to the internal path. +This fixes problems where the PHY ID is not properly set. + +Fixes: 7090425104db ("net: phy: add amlogic g12a mdio mux support") +Suggested-by: Qi Duan +Co-developed-by: Heiner Kallweit +Signed-off-by: Heiner Kallweit +Signed-off-by: Jerome Brunet +Link: https://lore.kernel.org/r/20230124101157.232234-1-jbrunet@baylibre.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/mdio/mdio-mux-meson-g12a.c | 23 ++++++++++++++++------- + 1 file changed, 16 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/mdio/mdio-mux-meson-g12a.c b/drivers/net/mdio/mdio-mux-meson-g12a.c +index bf86c9c7a288..ab863530c9e8 100644 +--- a/drivers/net/mdio/mdio-mux-meson-g12a.c ++++ b/drivers/net/mdio/mdio-mux-meson-g12a.c +@@ -4,6 +4,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -150,6 +151,7 @@ static const struct clk_ops g12a_ephy_pll_ops = { + + static int g12a_enable_internal_mdio(struct g12a_mdio_mux *priv) + { ++ u32 value; + int ret; + + /* Enable the phy clock */ +@@ -163,18 +165,25 @@ static int g12a_enable_internal_mdio(struct g12a_mdio_mux *priv) + + /* Initialize ephy control */ + writel(EPHY_G12A_ID, priv->regs + ETH_PHY_CNTL0); +- writel(FIELD_PREP(PHY_CNTL1_ST_MODE, 3) | +- FIELD_PREP(PHY_CNTL1_ST_PHYADD, EPHY_DFLT_ADD) | +- FIELD_PREP(PHY_CNTL1_MII_MODE, EPHY_MODE_RMII) | +- PHY_CNTL1_CLK_EN | +- PHY_CNTL1_CLKFREQ | +- PHY_CNTL1_PHY_ENB, +- priv->regs + ETH_PHY_CNTL1); ++ ++ /* Make sure we get a 0 -> 1 transition on the enable bit */ ++ value = FIELD_PREP(PHY_CNTL1_ST_MODE, 3) | ++ FIELD_PREP(PHY_CNTL1_ST_PHYADD, EPHY_DFLT_ADD) | ++ FIELD_PREP(PHY_CNTL1_MII_MODE, EPHY_MODE_RMII) | ++ PHY_CNTL1_CLK_EN | ++ PHY_CNTL1_CLKFREQ; ++ writel(value, priv->regs + ETH_PHY_CNTL1); + writel(PHY_CNTL2_USE_INTERNAL | + PHY_CNTL2_SMI_SRC_MAC | + PHY_CNTL2_RX_CLK_EPHY, + priv->regs + ETH_PHY_CNTL2); + ++ value |= PHY_CNTL1_PHY_ENB; ++ writel(value, priv->regs + ETH_PHY_CNTL1); ++ ++ /* The phy needs a bit of time to power up */ ++ mdelay(10); ++ + return 0; + } + +-- +2.39.0 + diff --git a/queue-5.10/net-ravb-fix-possible-hang-if-ris2_qff1-happen.patch b/queue-5.10/net-ravb-fix-possible-hang-if-ris2_qff1-happen.patch new file mode 100644 index 00000000000..a2c9b0c84cf --- /dev/null +++ b/queue-5.10/net-ravb-fix-possible-hang-if-ris2_qff1-happen.patch @@ -0,0 +1,49 @@ +From 76edf057e7e221d70787fbd939eb5a30598027a5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Jan 2023 09:02:11 +0900 +Subject: net: ravb: Fix possible hang if RIS2_QFF1 happen + +From: Yoshihiro Shimoda + +[ Upstream commit f3c07758c9007a6bfff5290d9e19d3c41930c897 ] + +Since this driver enables the interrupt by RIC2_QFE1, this driver +should clear the interrupt flag if it happens. Otherwise, the interrupt +causes to hang the system. + +Note that this also fix a minor coding style (a comment indentation) +around the fixed code. + +Fixes: c156633f1353 ("Renesas Ethernet AVB driver proper") +Signed-off-by: Yoshihiro Shimoda +Reviewed-by: Sergey Shtylyov +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/renesas/ravb_main.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c +index 9ec6d63691aa..410ccd28f653 100644 +--- a/drivers/net/ethernet/renesas/ravb_main.c ++++ b/drivers/net/ethernet/renesas/ravb_main.c +@@ -736,14 +736,14 @@ static void ravb_error_interrupt(struct net_device *ndev) + ravb_write(ndev, ~(EIS_QFS | EIS_RESERVED), EIS); + if (eis & EIS_QFS) { + ris2 = ravb_read(ndev, RIS2); +- ravb_write(ndev, ~(RIS2_QFF0 | RIS2_RFFF | RIS2_RESERVED), ++ ravb_write(ndev, ~(RIS2_QFF0 | RIS2_QFF1 | RIS2_RFFF | RIS2_RESERVED), + RIS2); + + /* Receive Descriptor Empty int */ + if (ris2 & RIS2_QFF0) + priv->stats[RAVB_BE].rx_over_errors++; + +- /* Receive Descriptor Empty int */ ++ /* Receive Descriptor Empty int */ + if (ris2 & RIS2_QFF1) + priv->stats[RAVB_NC].rx_over_errors++; + +-- +2.39.0 + diff --git a/queue-5.10/net-sched-sch_taprio-do-not-schedule-in-taprio_reset.patch b/queue-5.10/net-sched-sch_taprio-do-not-schedule-in-taprio_reset.patch new file mode 100644 index 00000000000..17cdfdfdca5 --- /dev/null +++ b/queue-5.10/net-sched-sch_taprio-do-not-schedule-in-taprio_reset.patch @@ -0,0 +1,89 @@ +From e5bc5f9bd38b928961e9aac8d8687a7e3f113b5b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Jan 2023 08:45:52 +0000 +Subject: net/sched: sch_taprio: do not schedule in taprio_reset() + +From: Eric Dumazet + +[ Upstream commit ea4fdbaa2f7798cb25adbe4fd52ffc6356f097bb ] + +As reported by syzbot and hinted by Vinicius, I should not have added +a qdisc_synchronize() call in taprio_reset() + +taprio_reset() can be called with qdisc spinlock held (and BH disabled) +as shown in included syzbot report [1]. + +Only taprio_destroy() needed this synchronization, as explained +in the blamed commit changelog. + +[1] + +BUG: scheduling while atomic: syz-executor150/5091/0x00000202 +2 locks held by syz-executor150/5091: +Modules linked in: +Preemption disabled at: +[<0000000000000000>] 0x0 +Kernel panic - not syncing: scheduling while atomic: panic_on_warn set ... +CPU: 1 PID: 5091 Comm: syz-executor150 Not tainted 6.2.0-rc3-syzkaller-00219-g010a74f52203 #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/12/2023 +Call Trace: + +__dump_stack lib/dump_stack.c:88 [inline] +dump_stack_lvl+0xd1/0x138 lib/dump_stack.c:106 +panic+0x2cc/0x626 kernel/panic.c:318 +check_panic_on_warn.cold+0x19/0x35 kernel/panic.c:238 +__schedule_bug.cold+0xd5/0xfe kernel/sched/core.c:5836 +schedule_debug kernel/sched/core.c:5865 [inline] +__schedule+0x34e4/0x5450 kernel/sched/core.c:6500 +schedule+0xde/0x1b0 kernel/sched/core.c:6682 +schedule_timeout+0x14e/0x2a0 kernel/time/timer.c:2167 +schedule_timeout_uninterruptible kernel/time/timer.c:2201 [inline] +msleep+0xb6/0x100 kernel/time/timer.c:2322 +qdisc_synchronize include/net/sch_generic.h:1295 [inline] +taprio_reset+0x93/0x270 net/sched/sch_taprio.c:1703 +qdisc_reset+0x10c/0x770 net/sched/sch_generic.c:1022 +dev_reset_queue+0x92/0x130 net/sched/sch_generic.c:1285 +netdev_for_each_tx_queue include/linux/netdevice.h:2464 [inline] +dev_deactivate_many+0x36d/0x9f0 net/sched/sch_generic.c:1351 +dev_deactivate+0xed/0x1b0 net/sched/sch_generic.c:1374 +qdisc_graft+0xe4a/0x1380 net/sched/sch_api.c:1080 +tc_modify_qdisc+0xb6b/0x19a0 net/sched/sch_api.c:1689 +rtnetlink_rcv_msg+0x43e/0xca0 net/core/rtnetlink.c:6141 +netlink_rcv_skb+0x165/0x440 net/netlink/af_netlink.c:2564 +netlink_unicast_kernel net/netlink/af_netlink.c:1330 [inline] +netlink_unicast+0x547/0x7f0 net/netlink/af_netlink.c:1356 +netlink_sendmsg+0x91b/0xe10 net/netlink/af_netlink.c:1932 +sock_sendmsg_nosec net/socket.c:714 [inline] +sock_sendmsg+0xd3/0x120 net/socket.c:734 +____sys_sendmsg+0x712/0x8c0 net/socket.c:2476 +___sys_sendmsg+0x110/0x1b0 net/socket.c:2530 +__sys_sendmsg+0xf7/0x1c0 net/socket.c:2559 +do_syscall_x64 arch/x86/entry/common.c:50 [inline] + +Fixes: 3a415d59c1db ("net/sched: sch_taprio: fix possible use-after-free") +Link: https://lore.kernel.org/netdev/167387581653.2747.13878941339893288655.git-patchwork-notify@kernel.org/T/ +Reported-by: syzbot +Signed-off-by: Eric Dumazet +Cc: Vinicius Costa Gomes +Link: https://lore.kernel.org/r/20230123084552.574396-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sched/sch_taprio.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c +index 5411bb4cdfc8..e25fe44899ff 100644 +--- a/net/sched/sch_taprio.c ++++ b/net/sched/sch_taprio.c +@@ -1621,7 +1621,6 @@ static void taprio_reset(struct Qdisc *sch) + int i; + + hrtimer_cancel(&q->advance_timer); +- qdisc_synchronize(sch); + + if (q->qdiscs) { + for (i = 0; i < dev->num_tx_queues; i++) +-- +2.39.0 + diff --git a/queue-5.10/net-tg3-resolve-deadlock-in-tg3_reset_task-during-ee.patch b/queue-5.10/net-tg3-resolve-deadlock-in-tg3_reset_task-during-ee.patch new file mode 100644 index 00000000000..b19776e45a5 --- /dev/null +++ b/queue-5.10/net-tg3-resolve-deadlock-in-tg3_reset_task-during-ee.patch @@ -0,0 +1,119 @@ +From 1aacfbf04abbff740671f2d550a2ce66ef6ebef8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Jan 2023 13:53:39 -0500 +Subject: net/tg3: resolve deadlock in tg3_reset_task() during EEH + +From: David Christensen + +[ Upstream commit 6c4ca03bd890566d873e3593b32d034bf2f5a087 ] + +During EEH error injection testing, a deadlock was encountered in the tg3 +driver when tg3_io_error_detected() was attempting to cancel outstanding +reset tasks: + +crash> foreach UN bt +... +PID: 159 TASK: c0000000067c6000 CPU: 8 COMMAND: "eehd" +... + #5 [c00000000681f990] __cancel_work_timer at c00000000019fd18 + #6 [c00000000681fa30] tg3_io_error_detected at c00800000295f098 [tg3] + #7 [c00000000681faf0] eeh_report_error at c00000000004e25c +... + +PID: 290 TASK: c000000036e5f800 CPU: 6 COMMAND: "kworker/6:1" +... + #4 [c00000003721fbc0] rtnl_lock at c000000000c940d8 + #5 [c00000003721fbe0] tg3_reset_task at c008000002969358 [tg3] + #6 [c00000003721fc60] process_one_work at c00000000019e5c4 +... + +PID: 296 TASK: c000000037a65800 CPU: 21 COMMAND: "kworker/21:1" +... + #4 [c000000037247bc0] rtnl_lock at c000000000c940d8 + #5 [c000000037247be0] tg3_reset_task at c008000002969358 [tg3] + #6 [c000000037247c60] process_one_work at c00000000019e5c4 +... + +PID: 655 TASK: c000000036f49000 CPU: 16 COMMAND: "kworker/16:2" +...:1 + + #4 [c0000000373ebbc0] rtnl_lock at c000000000c940d8 + #5 [c0000000373ebbe0] tg3_reset_task at c008000002969358 [tg3] + #6 [c0000000373ebc60] process_one_work at c00000000019e5c4 +... + +Code inspection shows that both tg3_io_error_detected() and +tg3_reset_task() attempt to acquire the RTNL lock at the beginning of +their code blocks. If tg3_reset_task() should happen to execute between +the times when tg3_io_error_deteced() acquires the RTNL lock and +tg3_reset_task_cancel() is called, a deadlock will occur. + +Moving tg3_reset_task_cancel() call earlier within the code block, prior +to acquiring RTNL, prevents this from happening, but also exposes another +deadlock issue where tg3_reset_task() may execute AFTER +tg3_io_error_detected() has executed: + +crash> foreach UN bt +PID: 159 TASK: c0000000067d2000 CPU: 9 COMMAND: "eehd" +... + #4 [c000000006867a60] rtnl_lock at c000000000c940d8 + #5 [c000000006867a80] tg3_io_slot_reset at c0080000026c2ea8 [tg3] + #6 [c000000006867b00] eeh_report_reset at c00000000004de88 +... +PID: 363 TASK: c000000037564000 CPU: 6 COMMAND: "kworker/6:1" +... + #3 [c000000036c1bb70] msleep at c000000000259e6c + #4 [c000000036c1bba0] napi_disable at c000000000c6b848 + #5 [c000000036c1bbe0] tg3_reset_task at c0080000026d942c [tg3] + #6 [c000000036c1bc60] process_one_work at c00000000019e5c4 +... + +This issue can be avoided by aborting tg3_reset_task() if EEH error +recovery is already in progress. + +Fixes: db84bf43ef23 ("tg3: tg3_reset_task() needs to use rtnl_lock to synchronize") +Signed-off-by: David Christensen +Reviewed-by: Pavan Chebbi +Link: https://lore.kernel.org/r/20230124185339.225806-1-drc@linux.vnet.ibm.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/tg3.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c +index be96116dc2cc..613ca6124e3c 100644 +--- a/drivers/net/ethernet/broadcom/tg3.c ++++ b/drivers/net/ethernet/broadcom/tg3.c +@@ -11185,7 +11185,7 @@ static void tg3_reset_task(struct work_struct *work) + rtnl_lock(); + tg3_full_lock(tp, 0); + +- if (!netif_running(tp->dev)) { ++ if (tp->pcierr_recovery || !netif_running(tp->dev)) { + tg3_flag_clear(tp, RESET_TASK_PENDING); + tg3_full_unlock(tp); + rtnl_unlock(); +@@ -18179,6 +18179,9 @@ static pci_ers_result_t tg3_io_error_detected(struct pci_dev *pdev, + + netdev_info(netdev, "PCI I/O error detected\n"); + ++ /* Want to make sure that the reset task doesn't run */ ++ tg3_reset_task_cancel(tp); ++ + rtnl_lock(); + + /* Could be second call or maybe we don't have netdev yet */ +@@ -18195,9 +18198,6 @@ static pci_ers_result_t tg3_io_error_detected(struct pci_dev *pdev, + + tg3_timer_stop(tp); + +- /* Want to make sure that the reset task doesn't run */ +- tg3_reset_task_cancel(tp); +- + netif_device_detach(netdev); + + /* Clean up software state, even if MMIO is blocked */ +-- +2.39.0 + diff --git a/queue-5.10/netfilter-conntrack-fix-bug-in-for_each_sctp_chunk.patch b/queue-5.10/netfilter-conntrack-fix-bug-in-for_each_sctp_chunk.patch new file mode 100644 index 00000000000..a663e3b65b6 --- /dev/null +++ b/queue-5.10/netfilter-conntrack-fix-bug-in-for_each_sctp_chunk.patch @@ -0,0 +1,42 @@ +From 07139657761a88eee6f967790f87aef0324c9e1f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Jan 2023 02:47:19 +0100 +Subject: netfilter: conntrack: fix bug in for_each_sctp_chunk + +From: Sriram Yagnaraman + +[ Upstream commit 98ee0077452527f971567db01386de3c3d97ce13 ] + +skb_header_pointer() will return NULL if offset + sizeof(_sch) exceeds +skb->len, so this offset < skb->len test is redundant. + +if sch->length == 0, this will end up in an infinite loop, add a check +for sch->length > 0 + +Fixes: 9fb9cbb1082d ("[NETFILTER]: Add nf_conntrack subsystem.") +Suggested-by: Florian Westphal +Signed-off-by: Sriram Yagnaraman +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_conntrack_proto_sctp.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c +index 72d0aa603cd6..c0264bbc8466 100644 +--- a/net/netfilter/nf_conntrack_proto_sctp.c ++++ b/net/netfilter/nf_conntrack_proto_sctp.c +@@ -155,8 +155,8 @@ static void sctp_print_conntrack(struct seq_file *s, struct nf_conn *ct) + + #define for_each_sctp_chunk(skb, sch, _sch, offset, dataoff, count) \ + for ((offset) = (dataoff) + sizeof(struct sctphdr), (count) = 0; \ +- (offset) < (skb)->len && \ +- ((sch) = skb_header_pointer((skb), (offset), sizeof(_sch), &(_sch))); \ ++ ((sch) = skb_header_pointer((skb), (offset), sizeof(_sch), &(_sch))) && \ ++ (sch)->length; \ + (offset) += (ntohs((sch)->length) + 3) & ~3, (count)++) + + /* Some validity checks to make sure the chunks are fine */ +-- +2.39.0 + diff --git a/queue-5.10/netfilter-conntrack-fix-vtag-checks-for-abort-shutdo.patch b/queue-5.10/netfilter-conntrack-fix-vtag-checks-for-abort-shutdo.patch new file mode 100644 index 00000000000..20021714f6f --- /dev/null +++ b/queue-5.10/netfilter-conntrack-fix-vtag-checks-for-abort-shutdo.patch @@ -0,0 +1,71 @@ +From 2f471eeffd3820435703071c1d11c644aabcd5d1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Jan 2023 02:47:18 +0100 +Subject: netfilter: conntrack: fix vtag checks for ABORT/SHUTDOWN_COMPLETE + +From: Sriram Yagnaraman + +[ Upstream commit a9993591fa94246b16b444eea55d84c54608282a ] + +RFC 9260, Sec 8.5.1 states that for ABORT/SHUTDOWN_COMPLETE, the chunk +MUST be accepted if the vtag of the packet matches its own tag and the +T bit is not set OR if it is set to its peer's vtag and the T bit is set +in chunk flags. Otherwise the packet MUST be silently dropped. + +Update vtag verification for ABORT/SHUTDOWN_COMPLETE based on the above +description. + +Fixes: 9fb9cbb1082d ("[NETFILTER]: Add nf_conntrack subsystem.") +Signed-off-by: Sriram Yagnaraman +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_conntrack_proto_sctp.c | 25 ++++++++++++++++--------- + 1 file changed, 16 insertions(+), 9 deletions(-) + +diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c +index 7626f3e1c70a..72d0aa603cd6 100644 +--- a/net/netfilter/nf_conntrack_proto_sctp.c ++++ b/net/netfilter/nf_conntrack_proto_sctp.c +@@ -412,22 +412,29 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct, + for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) { + /* Special cases of Verification tag check (Sec 8.5.1) */ + if (sch->type == SCTP_CID_INIT) { +- /* Sec 8.5.1 (A) */ ++ /* (A) vtag MUST be zero */ + if (sh->vtag != 0) + goto out_unlock; + } else if (sch->type == SCTP_CID_ABORT) { +- /* Sec 8.5.1 (B) */ +- if (sh->vtag != ct->proto.sctp.vtag[dir] && +- sh->vtag != ct->proto.sctp.vtag[!dir]) ++ /* (B) vtag MUST match own vtag if T flag is unset OR ++ * MUST match peer's vtag if T flag is set ++ */ ++ if ((!(sch->flags & SCTP_CHUNK_FLAG_T) && ++ sh->vtag != ct->proto.sctp.vtag[dir]) || ++ ((sch->flags & SCTP_CHUNK_FLAG_T) && ++ sh->vtag != ct->proto.sctp.vtag[!dir])) + goto out_unlock; + } else if (sch->type == SCTP_CID_SHUTDOWN_COMPLETE) { +- /* Sec 8.5.1 (C) */ +- if (sh->vtag != ct->proto.sctp.vtag[dir] && +- sh->vtag != ct->proto.sctp.vtag[!dir] && +- sch->flags & SCTP_CHUNK_FLAG_T) ++ /* (C) vtag MUST match own vtag if T flag is unset OR ++ * MUST match peer's vtag if T flag is set ++ */ ++ if ((!(sch->flags & SCTP_CHUNK_FLAG_T) && ++ sh->vtag != ct->proto.sctp.vtag[dir]) || ++ ((sch->flags & SCTP_CHUNK_FLAG_T) && ++ sh->vtag != ct->proto.sctp.vtag[!dir])) + goto out_unlock; + } else if (sch->type == SCTP_CID_COOKIE_ECHO) { +- /* Sec 8.5.1 (D) */ ++ /* (D) vtag must be same as init_vtag as found in INIT_ACK */ + if (sh->vtag != ct->proto.sctp.vtag[dir]) + goto out_unlock; + } else if (sch->type == SCTP_CID_HEARTBEAT) { +-- +2.39.0 + diff --git a/queue-5.10/netfilter-nft_set_rbtree-skip-elements-in-transactio.patch b/queue-5.10/netfilter-nft_set_rbtree-skip-elements-in-transactio.patch new file mode 100644 index 00000000000..9ab456e1de4 --- /dev/null +++ b/queue-5.10/netfilter-nft_set_rbtree-skip-elements-in-transactio.patch @@ -0,0 +1,69 @@ +From f303afd694c16345d71da728e90413ffd49c6049 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 14 Jan 2023 23:49:46 +0100 +Subject: netfilter: nft_set_rbtree: skip elements in transaction from garbage + collection + +From: Pablo Neira Ayuso + +[ Upstream commit 5d235d6ce75c12a7fdee375eb211e4116f7ab01b ] + +Skip interference with an ongoing transaction, do not perform garbage +collection on inactive elements. Reset annotated previous end interval +if the expired element is marked as busy (control plane removed the +element right before expiration). + +Fixes: 8d8540c4f5e0 ("netfilter: nft_set_rbtree: add timeout support") +Reviewed-by: Stefano Brivio +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nft_set_rbtree.c | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +diff --git a/net/netfilter/nft_set_rbtree.c b/net/netfilter/nft_set_rbtree.c +index 81c747008da3..4b9a499fe8f4 100644 +--- a/net/netfilter/nft_set_rbtree.c ++++ b/net/netfilter/nft_set_rbtree.c +@@ -562,23 +562,37 @@ static void nft_rbtree_gc(struct work_struct *work) + struct nft_rbtree *priv; + struct rb_node *node; + struct nft_set *set; ++ struct net *net; ++ u8 genmask; + + priv = container_of(work, struct nft_rbtree, gc_work.work); + set = nft_set_container_of(priv); ++ net = read_pnet(&set->net); ++ genmask = nft_genmask_cur(net); + + write_lock_bh(&priv->lock); + write_seqcount_begin(&priv->count); + for (node = rb_first(&priv->root); node != NULL; node = rb_next(node)) { + rbe = rb_entry(node, struct nft_rbtree_elem, node); + ++ if (!nft_set_elem_active(&rbe->ext, genmask)) ++ continue; ++ ++ /* elements are reversed in the rbtree for historical reasons, ++ * from highest to lowest value, that is why end element is ++ * always visited before the start element. ++ */ + if (nft_rbtree_interval_end(rbe)) { + rbe_end = rbe; + continue; + } + if (!nft_set_elem_expired(&rbe->ext)) + continue; +- if (nft_set_elem_mark_busy(&rbe->ext)) ++ ++ if (nft_set_elem_mark_busy(&rbe->ext)) { ++ rbe_end = NULL; + continue; ++ } + + if (rbe_prev) { + rb_erase(&rbe_prev->node, &priv->root); +-- +2.39.0 + diff --git a/queue-5.10/netfilter-nft_set_rbtree-switch-to-node-list-walk-fo.patch b/queue-5.10/netfilter-nft_set_rbtree-switch-to-node-list-walk-fo.patch new file mode 100644 index 00000000000..1ecfcaef2a6 --- /dev/null +++ b/queue-5.10/netfilter-nft_set_rbtree-switch-to-node-list-walk-fo.patch @@ -0,0 +1,428 @@ +From 5375185f1513dca8178115cb9b216ac11912c3ec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 14 Jan 2023 23:38:32 +0100 +Subject: netfilter: nft_set_rbtree: Switch to node list walk for overlap + detection + +From: Pablo Neira Ayuso + +[ Upstream commit c9e6978e2725a7d4b6cd23b2facd3f11422c0643 ] + +...instead of a tree descent, which became overly complicated in an +attempt to cover cases where expired or inactive elements would affect +comparisons with the new element being inserted. + +Further, it turned out that it's probably impossible to cover all those +cases, as inactive nodes might entirely hide subtrees consisting of a +complete interval plus a node that makes the current insertion not +overlap. + +To speed up the overlap check, descent the tree to find a greater +element that is closer to the key value to insert. Then walk down the +node list for overlap detection. Starting the overlap check from +rb_first() unconditionally is slow, it takes 10 times longer due to the +full linear traversal of the list. + +Moreover, perform garbage collection of expired elements when walking +down the node list to avoid bogus overlap reports. + +For the insertion operation itself, this essentially reverts back to the +implementation before commit 7c84d41416d8 ("netfilter: nft_set_rbtree: +Detect partial overlaps on insertion"), except that cases of complete +overlap are already handled in the overlap detection phase itself, which +slightly simplifies the loop to find the insertion point. + +Based on initial patch from Stefano Brivio, including text from the +original patch description too. + +Fixes: 7c84d41416d8 ("netfilter: nft_set_rbtree: Detect partial overlaps on insertion") +Reviewed-by: Stefano Brivio +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nft_set_rbtree.c | 316 ++++++++++++++++++++------------- + 1 file changed, 189 insertions(+), 127 deletions(-) + +diff --git a/net/netfilter/nft_set_rbtree.c b/net/netfilter/nft_set_rbtree.c +index 94a5446c5eae..81c747008da3 100644 +--- a/net/netfilter/nft_set_rbtree.c ++++ b/net/netfilter/nft_set_rbtree.c +@@ -38,10 +38,12 @@ static bool nft_rbtree_interval_start(const struct nft_rbtree_elem *rbe) + return !nft_rbtree_interval_end(rbe); + } + +-static bool nft_rbtree_equal(const struct nft_set *set, const void *this, +- const struct nft_rbtree_elem *interval) ++static int nft_rbtree_cmp(const struct nft_set *set, ++ const struct nft_rbtree_elem *e1, ++ const struct nft_rbtree_elem *e2) + { +- return memcmp(this, nft_set_ext_key(&interval->ext), set->klen) == 0; ++ return memcmp(nft_set_ext_key(&e1->ext), nft_set_ext_key(&e2->ext), ++ set->klen); + } + + static bool __nft_rbtree_lookup(const struct net *net, const struct nft_set *set, +@@ -52,7 +54,6 @@ static bool __nft_rbtree_lookup(const struct net *net, const struct nft_set *set + const struct nft_rbtree_elem *rbe, *interval = NULL; + u8 genmask = nft_genmask_cur(net); + const struct rb_node *parent; +- const void *this; + int d; + + parent = rcu_dereference_raw(priv->root.rb_node); +@@ -62,12 +63,11 @@ static bool __nft_rbtree_lookup(const struct net *net, const struct nft_set *set + + rbe = rb_entry(parent, struct nft_rbtree_elem, node); + +- this = nft_set_ext_key(&rbe->ext); +- d = memcmp(this, key, set->klen); ++ d = memcmp(nft_set_ext_key(&rbe->ext), key, set->klen); + if (d < 0) { + parent = rcu_dereference_raw(parent->rb_left); + if (interval && +- nft_rbtree_equal(set, this, interval) && ++ !nft_rbtree_cmp(set, rbe, interval) && + nft_rbtree_interval_end(rbe) && + nft_rbtree_interval_start(interval)) + continue; +@@ -214,154 +214,216 @@ static void *nft_rbtree_get(const struct net *net, const struct nft_set *set, + return rbe; + } + ++static int nft_rbtree_gc_elem(const struct nft_set *__set, ++ struct nft_rbtree *priv, ++ struct nft_rbtree_elem *rbe) ++{ ++ struct nft_set *set = (struct nft_set *)__set; ++ struct rb_node *prev = rb_prev(&rbe->node); ++ struct nft_rbtree_elem *rbe_prev; ++ struct nft_set_gc_batch *gcb; ++ ++ gcb = nft_set_gc_batch_check(set, NULL, GFP_ATOMIC); ++ if (!gcb) ++ return -ENOMEM; ++ ++ /* search for expired end interval coming before this element. */ ++ do { ++ rbe_prev = rb_entry(prev, struct nft_rbtree_elem, node); ++ if (nft_rbtree_interval_end(rbe_prev)) ++ break; ++ ++ prev = rb_prev(prev); ++ } while (prev != NULL); ++ ++ rb_erase(&rbe_prev->node, &priv->root); ++ rb_erase(&rbe->node, &priv->root); ++ atomic_sub(2, &set->nelems); ++ ++ nft_set_gc_batch_add(gcb, rbe); ++ nft_set_gc_batch_complete(gcb); ++ ++ return 0; ++} ++ ++static bool nft_rbtree_update_first(const struct nft_set *set, ++ struct nft_rbtree_elem *rbe, ++ struct rb_node *first) ++{ ++ struct nft_rbtree_elem *first_elem; ++ ++ first_elem = rb_entry(first, struct nft_rbtree_elem, node); ++ /* this element is closest to where the new element is to be inserted: ++ * update the first element for the node list path. ++ */ ++ if (nft_rbtree_cmp(set, rbe, first_elem) < 0) ++ return true; ++ ++ return false; ++} ++ + static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set, + struct nft_rbtree_elem *new, + struct nft_set_ext **ext) + { +- bool overlap = false, dup_end_left = false, dup_end_right = false; ++ struct nft_rbtree_elem *rbe, *rbe_le = NULL, *rbe_ge = NULL; ++ struct rb_node *node, *parent, **p, *first = NULL; + struct nft_rbtree *priv = nft_set_priv(set); + u8 genmask = nft_genmask_next(net); +- struct nft_rbtree_elem *rbe; +- struct rb_node *parent, **p; +- int d; ++ int d, err; + +- /* Detect overlaps as we descend the tree. Set the flag in these cases: +- * +- * a1. _ _ __>| ?_ _ __| (insert end before existing end) +- * a2. _ _ ___| ?_ _ _>| (insert end after existing end) +- * a3. _ _ ___? >|_ _ __| (insert start before existing end) +- * +- * and clear it later on, as we eventually reach the points indicated by +- * '?' above, in the cases described below. We'll always meet these +- * later, locally, due to tree ordering, and overlaps for the intervals +- * that are the closest together are always evaluated last. +- * +- * b1. _ _ __>| !_ _ __| (insert end before existing start) +- * b2. _ _ ___| !_ _ _>| (insert end after existing start) +- * b3. _ _ ___! >|_ _ __| (insert start after existing end, as a leaf) +- * '--' no nodes falling in this range +- * b4. >|_ _ ! (insert start before existing start) +- * +- * Case a3. resolves to b3.: +- * - if the inserted start element is the leftmost, because the '0' +- * element in the tree serves as end element +- * - otherwise, if an existing end is found immediately to the left. If +- * there are existing nodes in between, we need to further descend the +- * tree before we can conclude the new start isn't causing an overlap +- * +- * or to b4., which, preceded by a3., means we already traversed one or +- * more existing intervals entirely, from the right. +- * +- * For a new, rightmost pair of elements, we'll hit cases b3. and b2., +- * in that order. +- * +- * The flag is also cleared in two special cases: +- * +- * b5. |__ _ _!|<_ _ _ (insert start right before existing end) +- * b6. |__ _ >|!__ _ _ (insert end right after existing start) +- * +- * which always happen as last step and imply that no further +- * overlapping is possible. +- * +- * Another special case comes from the fact that start elements matching +- * an already existing start element are allowed: insertion is not +- * performed but we return -EEXIST in that case, and the error will be +- * cleared by the caller if NLM_F_EXCL is not present in the request. +- * This way, request for insertion of an exact overlap isn't reported as +- * error to userspace if not desired. +- * +- * However, if the existing start matches a pre-existing start, but the +- * end element doesn't match the corresponding pre-existing end element, +- * we need to report a partial overlap. This is a local condition that +- * can be noticed without need for a tracking flag, by checking for a +- * local duplicated end for a corresponding start, from left and right, +- * separately. ++ /* Descend the tree to search for an existing element greater than the ++ * key value to insert that is greater than the new element. This is the ++ * first element to walk the ordered elements to find possible overlap. + */ +- + parent = NULL; + p = &priv->root.rb_node; + while (*p != NULL) { + parent = *p; + rbe = rb_entry(parent, struct nft_rbtree_elem, node); +- d = memcmp(nft_set_ext_key(&rbe->ext), +- nft_set_ext_key(&new->ext), +- set->klen); ++ d = nft_rbtree_cmp(set, rbe, new); ++ + if (d < 0) { + p = &parent->rb_left; +- +- if (nft_rbtree_interval_start(new)) { +- if (nft_rbtree_interval_end(rbe) && +- nft_set_elem_active(&rbe->ext, genmask) && +- !nft_set_elem_expired(&rbe->ext) && !*p) +- overlap = false; +- } else { +- if (dup_end_left && !*p) +- return -ENOTEMPTY; +- +- overlap = nft_rbtree_interval_end(rbe) && +- nft_set_elem_active(&rbe->ext, +- genmask) && +- !nft_set_elem_expired(&rbe->ext); +- +- if (overlap) { +- dup_end_right = true; +- continue; +- } +- } + } else if (d > 0) { +- p = &parent->rb_right; ++ if (!first || ++ nft_rbtree_update_first(set, rbe, first)) ++ first = &rbe->node; + +- if (nft_rbtree_interval_end(new)) { +- if (dup_end_right && !*p) +- return -ENOTEMPTY; +- +- overlap = nft_rbtree_interval_end(rbe) && +- nft_set_elem_active(&rbe->ext, +- genmask) && +- !nft_set_elem_expired(&rbe->ext); +- +- if (overlap) { +- dup_end_left = true; +- continue; +- } +- } else if (nft_set_elem_active(&rbe->ext, genmask) && +- !nft_set_elem_expired(&rbe->ext)) { +- overlap = nft_rbtree_interval_end(rbe); +- } ++ p = &parent->rb_right; + } else { +- if (nft_rbtree_interval_end(rbe) && +- nft_rbtree_interval_start(new)) { ++ if (nft_rbtree_interval_end(rbe)) + p = &parent->rb_left; +- +- if (nft_set_elem_active(&rbe->ext, genmask) && +- !nft_set_elem_expired(&rbe->ext)) +- overlap = false; +- } else if (nft_rbtree_interval_start(rbe) && +- nft_rbtree_interval_end(new)) { ++ else + p = &parent->rb_right; ++ } ++ } ++ ++ if (!first) ++ first = rb_first(&priv->root); ++ ++ /* Detect overlap by going through the list of valid tree nodes. ++ * Values stored in the tree are in reversed order, starting from ++ * highest to lowest value. ++ */ ++ for (node = first; node != NULL; node = rb_next(node)) { ++ rbe = rb_entry(node, struct nft_rbtree_elem, node); ++ ++ if (!nft_set_elem_active(&rbe->ext, genmask)) ++ continue; + +- if (nft_set_elem_active(&rbe->ext, genmask) && +- !nft_set_elem_expired(&rbe->ext)) +- overlap = false; +- } else if (nft_set_elem_active(&rbe->ext, genmask) && +- !nft_set_elem_expired(&rbe->ext)) { +- *ext = &rbe->ext; +- return -EEXIST; +- } else { +- overlap = false; +- if (nft_rbtree_interval_end(rbe)) +- p = &parent->rb_left; +- else +- p = &parent->rb_right; ++ /* perform garbage collection to avoid bogus overlap reports. */ ++ if (nft_set_elem_expired(&rbe->ext)) { ++ err = nft_rbtree_gc_elem(set, priv, rbe); ++ if (err < 0) ++ return err; ++ ++ continue; ++ } ++ ++ d = nft_rbtree_cmp(set, rbe, new); ++ if (d == 0) { ++ /* Matching end element: no need to look for an ++ * overlapping greater or equal element. ++ */ ++ if (nft_rbtree_interval_end(rbe)) { ++ rbe_le = rbe; ++ break; ++ } ++ ++ /* first element that is greater or equal to key value. */ ++ if (!rbe_ge) { ++ rbe_ge = rbe; ++ continue; ++ } ++ ++ /* this is a closer more or equal element, update it. */ ++ if (nft_rbtree_cmp(set, rbe_ge, new) != 0) { ++ rbe_ge = rbe; ++ continue; + } ++ ++ /* element is equal to key value, make sure flags are ++ * the same, an existing more or equal start element ++ * must not be replaced by more or equal end element. ++ */ ++ if ((nft_rbtree_interval_start(new) && ++ nft_rbtree_interval_start(rbe_ge)) || ++ (nft_rbtree_interval_end(new) && ++ nft_rbtree_interval_end(rbe_ge))) { ++ rbe_ge = rbe; ++ continue; ++ } ++ } else if (d > 0) { ++ /* annotate element greater than the new element. */ ++ rbe_ge = rbe; ++ continue; ++ } else if (d < 0) { ++ /* annotate element less than the new element. */ ++ rbe_le = rbe; ++ break; + } ++ } + +- dup_end_left = dup_end_right = false; ++ /* - new start element matching existing start element: full overlap ++ * reported as -EEXIST, cleared by caller if NLM_F_EXCL is not given. ++ */ ++ if (rbe_ge && !nft_rbtree_cmp(set, new, rbe_ge) && ++ nft_rbtree_interval_start(rbe_ge) == nft_rbtree_interval_start(new)) { ++ *ext = &rbe_ge->ext; ++ return -EEXIST; ++ } ++ ++ /* - new end element matching existing end element: full overlap ++ * reported as -EEXIST, cleared by caller if NLM_F_EXCL is not given. ++ */ ++ if (rbe_le && !nft_rbtree_cmp(set, new, rbe_le) && ++ nft_rbtree_interval_end(rbe_le) == nft_rbtree_interval_end(new)) { ++ *ext = &rbe_le->ext; ++ return -EEXIST; + } + +- if (overlap) ++ /* - new start element with existing closest, less or equal key value ++ * being a start element: partial overlap, reported as -ENOTEMPTY. ++ * Anonymous sets allow for two consecutive start element since they ++ * are constant, skip them to avoid bogus overlap reports. ++ */ ++ if (!nft_set_is_anonymous(set) && rbe_le && ++ nft_rbtree_interval_start(rbe_le) && nft_rbtree_interval_start(new)) ++ return -ENOTEMPTY; ++ ++ /* - new end element with existing closest, less or equal key value ++ * being a end element: partial overlap, reported as -ENOTEMPTY. ++ */ ++ if (rbe_le && ++ nft_rbtree_interval_end(rbe_le) && nft_rbtree_interval_end(new)) + return -ENOTEMPTY; + ++ /* - new end element with existing closest, greater or equal key value ++ * being an end element: partial overlap, reported as -ENOTEMPTY ++ */ ++ if (rbe_ge && ++ nft_rbtree_interval_end(rbe_ge) && nft_rbtree_interval_end(new)) ++ return -ENOTEMPTY; ++ ++ /* Accepted element: pick insertion point depending on key value */ ++ parent = NULL; ++ p = &priv->root.rb_node; ++ while (*p != NULL) { ++ parent = *p; ++ rbe = rb_entry(parent, struct nft_rbtree_elem, node); ++ d = nft_rbtree_cmp(set, rbe, new); ++ ++ if (d < 0) ++ p = &parent->rb_left; ++ else if (d > 0) ++ p = &parent->rb_right; ++ else if (nft_rbtree_interval_end(rbe)) ++ p = &parent->rb_left; ++ else ++ p = &parent->rb_right; ++ } ++ + rb_link_node_rcu(&new->node, parent, p); + rb_insert_color(&new->node, &priv->root); + return 0; +-- +2.39.0 + diff --git a/queue-5.10/netlink-annotate-data-races-around-dst_portid-and-ds.patch b/queue-5.10/netlink-annotate-data-races-around-dst_portid-and-ds.patch new file mode 100644 index 00000000000..3fc9dc1e1e6 --- /dev/null +++ b/queue-5.10/netlink-annotate-data-races-around-dst_portid-and-ds.patch @@ -0,0 +1,87 @@ +From 04210c92c925d17c4fe0468e7d1424674616d73d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Jan 2023 12:59:54 +0000 +Subject: netlink: annotate data races around dst_portid and dst_group + +From: Eric Dumazet + +[ Upstream commit 004db64d185a5f23dfb891d7701e23713b2420ee ] + +netlink_getname(), netlink_sendmsg() and netlink_getsockbyportid() +can read nlk->dst_portid and nlk->dst_group while another +thread is changing them. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Eric Dumazet +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/netlink/af_netlink.c | 23 ++++++++++++++--------- + 1 file changed, 14 insertions(+), 9 deletions(-) + +diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c +index 438f45222ca5..cdecd1977583 100644 +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -1082,8 +1082,9 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr, + + if (addr->sa_family == AF_UNSPEC) { + sk->sk_state = NETLINK_UNCONNECTED; +- nlk->dst_portid = 0; +- nlk->dst_group = 0; ++ /* dst_portid and dst_group can be read locklessly */ ++ WRITE_ONCE(nlk->dst_portid, 0); ++ WRITE_ONCE(nlk->dst_group, 0); + return 0; + } + if (addr->sa_family != AF_NETLINK) +@@ -1105,8 +1106,9 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr, + + if (err == 0) { + sk->sk_state = NETLINK_CONNECTED; +- nlk->dst_portid = nladdr->nl_pid; +- nlk->dst_group = ffs(nladdr->nl_groups); ++ /* dst_portid and dst_group can be read locklessly */ ++ WRITE_ONCE(nlk->dst_portid, nladdr->nl_pid); ++ WRITE_ONCE(nlk->dst_group, ffs(nladdr->nl_groups)); + } + + return err; +@@ -1123,8 +1125,9 @@ static int netlink_getname(struct socket *sock, struct sockaddr *addr, + nladdr->nl_pad = 0; + + if (peer) { +- nladdr->nl_pid = nlk->dst_portid; +- nladdr->nl_groups = netlink_group_mask(nlk->dst_group); ++ /* Paired with WRITE_ONCE() in netlink_connect() */ ++ nladdr->nl_pid = READ_ONCE(nlk->dst_portid); ++ nladdr->nl_groups = netlink_group_mask(READ_ONCE(nlk->dst_group)); + } else { + /* Paired with WRITE_ONCE() in netlink_insert() */ + nladdr->nl_pid = READ_ONCE(nlk->portid); +@@ -1154,8 +1157,9 @@ static struct sock *netlink_getsockbyportid(struct sock *ssk, u32 portid) + + /* Don't bother queuing skb if kernel socket has no input function */ + nlk = nlk_sk(sock); ++ /* dst_portid can be changed in netlink_connect() */ + if (sock->sk_state == NETLINK_CONNECTED && +- nlk->dst_portid != nlk_sk(ssk)->portid) { ++ READ_ONCE(nlk->dst_portid) != nlk_sk(ssk)->portid) { + sock_put(sock); + return ERR_PTR(-ECONNREFUSED); + } +@@ -1891,8 +1895,9 @@ static int netlink_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) + goto out; + netlink_skb_flags |= NETLINK_SKB_DST; + } else { +- dst_portid = nlk->dst_portid; +- dst_group = nlk->dst_group; ++ /* Paired with WRITE_ONCE() in netlink_connect() */ ++ dst_portid = READ_ONCE(nlk->dst_portid); ++ dst_group = READ_ONCE(nlk->dst_group); + } + + /* Paired with WRITE_ONCE() in netlink_insert() */ +-- +2.39.0 + diff --git a/queue-5.10/netlink-annotate-data-races-around-nlk-portid.patch b/queue-5.10/netlink-annotate-data-races-around-nlk-portid.patch new file mode 100644 index 00000000000..847c8f833db --- /dev/null +++ b/queue-5.10/netlink-annotate-data-races-around-nlk-portid.patch @@ -0,0 +1,87 @@ +From 70e82ef3359a08de88260d79cf83ae6280386ade Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Jan 2023 12:59:53 +0000 +Subject: netlink: annotate data races around nlk->portid + +From: Eric Dumazet + +[ Upstream commit c1bb9484e3b05166880da8574504156ccbd0549e ] + +syzbot reminds us netlink_getname() runs locklessly [1] + +This first patch annotates the race against nlk->portid. + +Following patches take care of the remaining races. + +[1] +BUG: KCSAN: data-race in netlink_getname / netlink_insert + +write to 0xffff88814176d310 of 4 bytes by task 2315 on cpu 1: +netlink_insert+0xf1/0x9a0 net/netlink/af_netlink.c:583 +netlink_autobind+0xae/0x180 net/netlink/af_netlink.c:856 +netlink_sendmsg+0x444/0x760 net/netlink/af_netlink.c:1895 +sock_sendmsg_nosec net/socket.c:714 [inline] +sock_sendmsg net/socket.c:734 [inline] +____sys_sendmsg+0x38f/0x500 net/socket.c:2476 +___sys_sendmsg net/socket.c:2530 [inline] +__sys_sendmsg+0x19a/0x230 net/socket.c:2559 +__do_sys_sendmsg net/socket.c:2568 [inline] +__se_sys_sendmsg net/socket.c:2566 [inline] +__x64_sys_sendmsg+0x42/0x50 net/socket.c:2566 +do_syscall_x64 arch/x86/entry/common.c:50 [inline] +do_syscall_64+0x2b/0x70 arch/x86/entry/common.c:80 +entry_SYSCALL_64_after_hwframe+0x63/0xcd + +read to 0xffff88814176d310 of 4 bytes by task 2316 on cpu 0: +netlink_getname+0xcd/0x1a0 net/netlink/af_netlink.c:1144 +__sys_getsockname+0x11d/0x1b0 net/socket.c:2026 +__do_sys_getsockname net/socket.c:2041 [inline] +__se_sys_getsockname net/socket.c:2038 [inline] +__x64_sys_getsockname+0x3e/0x50 net/socket.c:2038 +do_syscall_x64 arch/x86/entry/common.c:50 [inline] +do_syscall_64+0x2b/0x70 arch/x86/entry/common.c:80 +entry_SYSCALL_64_after_hwframe+0x63/0xcd + +value changed: 0x00000000 -> 0xc9a49780 + +Reported by Kernel Concurrency Sanitizer on: +CPU: 0 PID: 2316 Comm: syz-executor.2 Not tainted 6.2.0-rc3-syzkaller-00030-ge8f60cd7db24-dirty #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022 + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Eric Dumazet +Reported-by: syzbot +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/netlink/af_netlink.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c +index d96a610929d9..438f45222ca5 100644 +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -570,7 +570,9 @@ static int netlink_insert(struct sock *sk, u32 portid) + if (nlk_sk(sk)->bound) + goto err; + +- nlk_sk(sk)->portid = portid; ++ /* portid can be read locklessly from netlink_getname(). */ ++ WRITE_ONCE(nlk_sk(sk)->portid, portid); ++ + sock_hold(sk); + + err = __netlink_insert(table, sk); +@@ -1124,7 +1126,8 @@ static int netlink_getname(struct socket *sock, struct sockaddr *addr, + nladdr->nl_pid = nlk->dst_portid; + nladdr->nl_groups = netlink_group_mask(nlk->dst_group); + } else { +- nladdr->nl_pid = nlk->portid; ++ /* Paired with WRITE_ONCE() in netlink_insert() */ ++ nladdr->nl_pid = READ_ONCE(nlk->portid); + netlink_lock_table(); + nladdr->nl_groups = nlk->groups ? nlk->groups[0] : 0; + netlink_unlock_table(); +-- +2.39.0 + diff --git a/queue-5.10/netlink-annotate-data-races-around-sk_state.patch b/queue-5.10/netlink-annotate-data-races-around-sk_state.patch new file mode 100644 index 00000000000..9599aaeb83c --- /dev/null +++ b/queue-5.10/netlink-annotate-data-races-around-sk_state.patch @@ -0,0 +1,58 @@ +From 659d323d8f67b040af645d421de0c684b08d840b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Jan 2023 12:59:55 +0000 +Subject: netlink: annotate data races around sk_state + +From: Eric Dumazet + +[ Upstream commit 9b663b5cbb15b494ef132a3c937641c90646eb73 ] + +netlink_getsockbyportid() reads sk_state while a concurrent +netlink_connect() can change its value. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Eric Dumazet +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/netlink/af_netlink.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c +index cdecd1977583..2104fbdd63d2 100644 +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -1081,7 +1081,8 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr, + return -EINVAL; + + if (addr->sa_family == AF_UNSPEC) { +- sk->sk_state = NETLINK_UNCONNECTED; ++ /* paired with READ_ONCE() in netlink_getsockbyportid() */ ++ WRITE_ONCE(sk->sk_state, NETLINK_UNCONNECTED); + /* dst_portid and dst_group can be read locklessly */ + WRITE_ONCE(nlk->dst_portid, 0); + WRITE_ONCE(nlk->dst_group, 0); +@@ -1105,7 +1106,8 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr, + err = netlink_autobind(sock); + + if (err == 0) { +- sk->sk_state = NETLINK_CONNECTED; ++ /* paired with READ_ONCE() in netlink_getsockbyportid() */ ++ WRITE_ONCE(sk->sk_state, NETLINK_CONNECTED); + /* dst_portid and dst_group can be read locklessly */ + WRITE_ONCE(nlk->dst_portid, nladdr->nl_pid); + WRITE_ONCE(nlk->dst_group, ffs(nladdr->nl_groups)); +@@ -1157,8 +1159,8 @@ static struct sock *netlink_getsockbyportid(struct sock *ssk, u32 portid) + + /* Don't bother queuing skb if kernel socket has no input function */ + nlk = nlk_sk(sock); +- /* dst_portid can be changed in netlink_connect() */ +- if (sock->sk_state == NETLINK_CONNECTED && ++ /* dst_portid and sk_state can be changed in netlink_connect() */ ++ if (READ_ONCE(sock->sk_state) == NETLINK_CONNECTED && + READ_ONCE(nlk->dst_portid) != nlk_sk(ssk)->portid) { + sock_put(sock); + return ERR_PTR(-ECONNREFUSED); +-- +2.39.0 + diff --git a/queue-5.10/netlink-prevent-potential-spectre-v1-gadgets.patch b/queue-5.10/netlink-prevent-potential-spectre-v1-gadgets.patch new file mode 100644 index 00000000000..78b62d1bdd0 --- /dev/null +++ b/queue-5.10/netlink-prevent-potential-spectre-v1-gadgets.patch @@ -0,0 +1,68 @@ +From 853de5fb26264a3fa2df8f39cc80555437a01faa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Jan 2023 11:01:50 +0000 +Subject: netlink: prevent potential spectre v1 gadgets + +From: Eric Dumazet + +[ Upstream commit f0950402e8c76e7dcb08563f1b4e8000fbc62455 ] + +Most netlink attributes are parsed and validated from +__nla_validate_parse() or validate_nla() + + u16 type = nla_type(nla); + + if (type == 0 || type > maxtype) { + /* error or continue */ + } + +@type is then used as an array index and can be used +as a Spectre v1 gadget. + +array_index_nospec() can be used to prevent leaking +content of kernel memory to malicious users. + +This should take care of vast majority of netlink uses, +but an audit is needed to take care of others where +validation is not yet centralized in core netlink functions. + +Fixes: bfa83a9e03cf ("[NETLINK]: Type-safe netlink messages/attributes interface") +Signed-off-by: Eric Dumazet +Link: https://lore.kernel.org/r/20230119110150.2678537-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + lib/nlattr.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/lib/nlattr.c b/lib/nlattr.c +index fe60f9ae9db1..aa8fc4371e93 100644 +--- a/lib/nlattr.c ++++ b/lib/nlattr.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -369,6 +370,7 @@ static int validate_nla(const struct nlattr *nla, int maxtype, + if (type <= 0 || type > maxtype) + return 0; + ++ type = array_index_nospec(type, maxtype + 1); + pt = &policy[type]; + + BUG_ON(pt->type > NLA_TYPE_MAX); +@@ -584,6 +586,7 @@ static int __nla_validate_parse(const struct nlattr *head, int len, int maxtype, + } + continue; + } ++ type = array_index_nospec(type, maxtype + 1); + if (policy) { + int err = validate_nla(nla, maxtype, policy, + validate, extack, depth); +-- +2.39.0 + diff --git a/queue-5.10/netrom-fix-use-after-free-of-a-listening-socket.patch b/queue-5.10/netrom-fix-use-after-free-of-a-listening-socket.patch new file mode 100644 index 00000000000..ab10a246785 --- /dev/null +++ b/queue-5.10/netrom-fix-use-after-free-of-a-listening-socket.patch @@ -0,0 +1,161 @@ +From 63688fc907371a71d964baa9ad3732ee55a50d59 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Jan 2023 15:19:27 -0800 +Subject: netrom: Fix use-after-free of a listening socket. + +From: Kuniyuki Iwashima + +[ Upstream commit 409db27e3a2eb5e8ef7226ca33be33361b3ed1c9 ] + +syzbot reported a use-after-free in do_accept(), precisely nr_accept() +as sk_prot_alloc() allocated the memory and sock_put() frees it. [0] + +The issue could happen if the heartbeat timer is fired and +nr_heartbeat_expiry() calls nr_destroy_socket(), where a socket +has SOCK_DESTROY or a listening socket has SOCK_DEAD. + +In this case, the first condition cannot be true. SOCK_DESTROY is +flagged in nr_release() only when the file descriptor is close()d, +but accept() is being called for the listening socket, so the second +condition must be true. + +Usually, the AF_NETROM listener neither starts timers nor sets +SOCK_DEAD. However, the condition is met if connect() fails before +listen(). connect() starts the t1 timer and heartbeat timer, and +t1timer calls nr_disconnect() when timeout happens. Then, SOCK_DEAD +is set, and if we call listen(), the heartbeat timer calls +nr_destroy_socket(). + + nr_connect + nr_establish_data_link(sk) + nr_start_t1timer(sk) + nr_start_heartbeat(sk) + nr_t1timer_expiry + nr_disconnect(sk, ETIMEDOUT) + nr_sk(sk)->state = NR_STATE_0 + sk->sk_state = TCP_CLOSE + sock_set_flag(sk, SOCK_DEAD) +nr_listen + if (sk->sk_state != TCP_LISTEN) + sk->sk_state = TCP_LISTEN + nr_heartbeat_expiry + switch (nr->state) + case NR_STATE_0 + if (sk->sk_state == TCP_LISTEN && + sock_flag(sk, SOCK_DEAD)) + nr_destroy_socket(sk) + +This path seems expected, and nr_destroy_socket() is called to clean +up resources. Initially, there was sock_hold() before nr_destroy_socket() +so that the socket would not be freed, but the commit 517a16b1a88b +("netrom: Decrease sock refcount when sock timers expire") accidentally +removed it. + +To fix use-after-free, let's add sock_hold(). + +[0]: +BUG: KASAN: use-after-free in do_accept+0x483/0x510 net/socket.c:1848 +Read of size 8 at addr ffff88807978d398 by task syz-executor.3/5315 + +CPU: 0 PID: 5315 Comm: syz-executor.3 Not tainted 6.2.0-rc3-syzkaller-00165-gd9fc1511728c #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022 +Call Trace: + + __dump_stack lib/dump_stack.c:88 [inline] + dump_stack_lvl+0xd1/0x138 lib/dump_stack.c:106 + print_address_description mm/kasan/report.c:306 [inline] + print_report+0x15e/0x461 mm/kasan/report.c:417 + kasan_report+0xbf/0x1f0 mm/kasan/report.c:517 + do_accept+0x483/0x510 net/socket.c:1848 + __sys_accept4_file net/socket.c:1897 [inline] + __sys_accept4+0x9a/0x120 net/socket.c:1927 + __do_sys_accept net/socket.c:1944 [inline] + __se_sys_accept net/socket.c:1941 [inline] + __x64_sys_accept+0x75/0xb0 net/socket.c:1941 + do_syscall_x64 arch/x86/entry/common.c:50 [inline] + do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80 + entry_SYSCALL_64_after_hwframe+0x63/0xcd +RIP: 0033:0x7fa436a8c0c9 +Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 f1 19 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48 +RSP: 002b:00007fa437784168 EFLAGS: 00000246 ORIG_RAX: 000000000000002b +RAX: ffffffffffffffda RBX: 00007fa436bac050 RCX: 00007fa436a8c0c9 +RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000005 +RBP: 00007fa436ae7ae9 R08: 0000000000000000 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 +R13: 00007ffebc6700df R14: 00007fa437784300 R15: 0000000000022000 + + +Allocated by task 5294: + kasan_save_stack+0x22/0x40 mm/kasan/common.c:45 + kasan_set_track+0x25/0x30 mm/kasan/common.c:52 + ____kasan_kmalloc mm/kasan/common.c:371 [inline] + ____kasan_kmalloc mm/kasan/common.c:330 [inline] + __kasan_kmalloc+0xa3/0xb0 mm/kasan/common.c:380 + kasan_kmalloc include/linux/kasan.h:211 [inline] + __do_kmalloc_node mm/slab_common.c:968 [inline] + __kmalloc+0x5a/0xd0 mm/slab_common.c:981 + kmalloc include/linux/slab.h:584 [inline] + sk_prot_alloc+0x140/0x290 net/core/sock.c:2038 + sk_alloc+0x3a/0x7a0 net/core/sock.c:2091 + nr_create+0xb6/0x5f0 net/netrom/af_netrom.c:433 + __sock_create+0x359/0x790 net/socket.c:1515 + sock_create net/socket.c:1566 [inline] + __sys_socket_create net/socket.c:1603 [inline] + __sys_socket_create net/socket.c:1588 [inline] + __sys_socket+0x133/0x250 net/socket.c:1636 + __do_sys_socket net/socket.c:1649 [inline] + __se_sys_socket net/socket.c:1647 [inline] + __x64_sys_socket+0x73/0xb0 net/socket.c:1647 + do_syscall_x64 arch/x86/entry/common.c:50 [inline] + do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80 + entry_SYSCALL_64_after_hwframe+0x63/0xcd + +Freed by task 14: + kasan_save_stack+0x22/0x40 mm/kasan/common.c:45 + kasan_set_track+0x25/0x30 mm/kasan/common.c:52 + kasan_save_free_info+0x2b/0x40 mm/kasan/generic.c:518 + ____kasan_slab_free mm/kasan/common.c:236 [inline] + ____kasan_slab_free+0x13b/0x1a0 mm/kasan/common.c:200 + kasan_slab_free include/linux/kasan.h:177 [inline] + __cache_free mm/slab.c:3394 [inline] + __do_kmem_cache_free mm/slab.c:3580 [inline] + __kmem_cache_free+0xcd/0x3b0 mm/slab.c:3587 + sk_prot_free net/core/sock.c:2074 [inline] + __sk_destruct+0x5df/0x750 net/core/sock.c:2166 + sk_destruct net/core/sock.c:2181 [inline] + __sk_free+0x175/0x460 net/core/sock.c:2192 + sk_free+0x7c/0xa0 net/core/sock.c:2203 + sock_put include/net/sock.h:1991 [inline] + nr_heartbeat_expiry+0x1d7/0x460 net/netrom/nr_timer.c:148 + call_timer_fn+0x1da/0x7c0 kernel/time/timer.c:1700 + expire_timers+0x2c6/0x5c0 kernel/time/timer.c:1751 + __run_timers kernel/time/timer.c:2022 [inline] + __run_timers kernel/time/timer.c:1995 [inline] + run_timer_softirq+0x326/0x910 kernel/time/timer.c:2035 + __do_softirq+0x1fb/0xadc kernel/softirq.c:571 + +Fixes: 517a16b1a88b ("netrom: Decrease sock refcount when sock timers expire") +Reported-by: syzbot+5fafd5cfe1fc91f6b352@syzkaller.appspotmail.com +Signed-off-by: Kuniyuki Iwashima +Link: https://lore.kernel.org/r/20230120231927.51711-1-kuniyu@amazon.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/netrom/nr_timer.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/netrom/nr_timer.c b/net/netrom/nr_timer.c +index a8da88db7893..4e7c968cde2d 100644 +--- a/net/netrom/nr_timer.c ++++ b/net/netrom/nr_timer.c +@@ -121,6 +121,7 @@ static void nr_heartbeat_expiry(struct timer_list *t) + is accepted() it isn't 'dead' so doesn't get removed. */ + if (sock_flag(sk, SOCK_DESTROY) || + (sk->sk_state == TCP_LISTEN && sock_flag(sk, SOCK_DEAD))) { ++ sock_hold(sk); + bh_unlock_sock(sk); + nr_destroy_socket(sk); + goto out; +-- +2.39.0 + diff --git a/queue-5.10/sctp-fail-if-no-bound-addresses-can-be-used-for-a-gi.patch b/queue-5.10/sctp-fail-if-no-bound-addresses-can-be-used-for-a-gi.patch new file mode 100644 index 00000000000..30bc5f20781 --- /dev/null +++ b/queue-5.10/sctp-fail-if-no-bound-addresses-can-be-used-for-a-gi.patch @@ -0,0 +1,68 @@ +From 7a56badcd3299789e740f8679935ba106c944202 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Jan 2023 14:59:33 -0300 +Subject: sctp: fail if no bound addresses can be used for a given scope + +From: Marcelo Ricardo Leitner + +[ Upstream commit 458e279f861d3f61796894cd158b780765a1569f ] + +Currently, if you bind the socket to something like: + servaddr.sin6_family = AF_INET6; + servaddr.sin6_port = htons(0); + servaddr.sin6_scope_id = 0; + inet_pton(AF_INET6, "::1", &servaddr.sin6_addr); + +And then request a connect to: + connaddr.sin6_family = AF_INET6; + connaddr.sin6_port = htons(20000); + connaddr.sin6_scope_id = if_nametoindex("lo"); + inet_pton(AF_INET6, "fe88::1", &connaddr.sin6_addr); + +What the stack does is: + - bind the socket + - create a new asoc + - to handle the connect + - copy the addresses that can be used for the given scope + - try to connect + +But the copy returns 0 addresses, and the effect is that it ends up +trying to connect as if the socket wasn't bound, which is not the +desired behavior. This unexpected behavior also allows KASLR leaks +through SCTP diag interface. + +The fix here then is, if when trying to copy the addresses that can +be used for the scope used in connect() it returns 0 addresses, bail +out. This is what TCP does with a similar reproducer. + +Reported-by: Pietro Borrello +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Marcelo Ricardo Leitner +Reviewed-by: Xin Long +Link: https://lore.kernel.org/r/9fcd182f1099f86c6661f3717f63712ddd1c676c.1674496737.git.marcelo.leitner@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sctp/bind_addr.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c +index 59e653b528b1..6b95d3ba8fe1 100644 +--- a/net/sctp/bind_addr.c ++++ b/net/sctp/bind_addr.c +@@ -73,6 +73,12 @@ int sctp_bind_addr_copy(struct net *net, struct sctp_bind_addr *dest, + } + } + ++ /* If somehow no addresses were found that can be used with this ++ * scope, it's an error. ++ */ ++ if (list_empty(&dest->address_list)) ++ error = -ENETUNREACH; ++ + out: + if (error) + sctp_bind_addr_clean(dest); +-- +2.39.0 + diff --git a/queue-5.10/series b/queue-5.10/series index e8ec3373ae8..6f0d5b7de27 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -109,3 +109,26 @@ thermal-intel-int340x-protect-trip-temperature-from-concurrent-updates.patch arm-9280-1-mm-fix-warning-on-phys_addr_t-to-void-pointer-assignment.patch edac-device-respect-any-driver-supplied-workqueue-polling-value.patch edac-qcom-do-not-pass-llcc_driv_data-as-edac_device_ctl_info-s-pvt_info.patch +units-add-watt-units.patch +units-add-si-metric-prefix-definitions.patch +i2c-designware-use-div_round_closest-macro.patch +i2c-designware-use-casting-of-u64-in-clock-multiplic.patch +netlink-prevent-potential-spectre-v1-gadgets.patch +net-fix-uaf-in-netns-ops-registration-error-path.patch +netfilter-nft_set_rbtree-switch-to-node-list-walk-fo.patch +netfilter-nft_set_rbtree-skip-elements-in-transactio.patch +netlink-annotate-data-races-around-nlk-portid.patch +netlink-annotate-data-races-around-dst_portid-and-ds.patch +netlink-annotate-data-races-around-sk_state.patch +ipv4-prevent-potential-spectre-v1-gadget-in-ip_metri.patch +ipv4-prevent-potential-spectre-v1-gadget-in-fib_metr.patch +netfilter-conntrack-fix-vtag-checks-for-abort-shutdo.patch +netfilter-conntrack-fix-bug-in-for_each_sctp_chunk.patch +netrom-fix-use-after-free-of-a-listening-socket.patch +net-sched-sch_taprio-do-not-schedule-in-taprio_reset.patch +sctp-fail-if-no-bound-addresses-can-be-used-for-a-gi.patch +net-ravb-fix-possible-hang-if-ris2_qff1-happen.patch +thermal-intel-int340x-add-locking-to-int340x_thermal.patch +net-tg3-resolve-deadlock-in-tg3_reset_task-during-ee.patch +net-mdio-mux-meson-g12a-force-internal-phy-off-on-mu.patch +tools-gpio-fix-c-option-of-gpio-event-mon.patch diff --git a/queue-5.10/thermal-intel-int340x-add-locking-to-int340x_thermal.patch b/queue-5.10/thermal-intel-int340x-add-locking-to-int340x_thermal.patch new file mode 100644 index 00000000000..8d0551e5b34 --- /dev/null +++ b/queue-5.10/thermal-intel-int340x-add-locking-to-int340x_thermal.patch @@ -0,0 +1,58 @@ +From 83b0fdb6c4ea46a9fdadb52f4f5dcf2d1b4b00e2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Jan 2023 13:17:42 +0100 +Subject: thermal: intel: int340x: Add locking to + int340x_thermal_get_trip_type() + +From: Rafael J. Wysocki + +[ Upstream commit acd7e9ee57c880b99671dd99680cb707b7b5b0ee ] + +In order to prevent int340x_thermal_get_trip_type() from possibly +racing with int340x_thermal_read_trips() invoked by int3403_notify() +add locking to it in analogy with int340x_thermal_get_trip_temp(). + +Fixes: 6757a7abe47b ("thermal: intel: int340x: Protect trip temperature from concurrent updates") +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + .../intel/int340x_thermal/int340x_thermal_zone.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c +index c9e0050bce17..6952f4e237e1 100644 +--- a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c ++++ b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c +@@ -81,11 +81,13 @@ static int int340x_thermal_get_trip_type(struct thermal_zone_device *zone, + enum thermal_trip_type *type) + { + struct int34x_thermal_zone *d = zone->devdata; +- int i; ++ int i, ret = 0; + + if (d->override_ops && d->override_ops->get_trip_type) + return d->override_ops->get_trip_type(zone, trip, type); + ++ mutex_lock(&d->trip_mutex); ++ + if (trip < d->aux_trip_nr) + *type = THERMAL_TRIP_PASSIVE; + else if (trip == d->crt_trip_id) +@@ -103,10 +105,12 @@ static int int340x_thermal_get_trip_type(struct thermal_zone_device *zone, + } + } + if (i == INT340X_THERMAL_MAX_ACT_TRIP_COUNT) +- return -EINVAL; ++ ret = -EINVAL; + } + +- return 0; ++ mutex_unlock(&d->trip_mutex); ++ ++ return ret; + } + + static int int340x_thermal_set_trip_temp(struct thermal_zone_device *zone, +-- +2.39.0 + diff --git a/queue-5.10/tools-gpio-fix-c-option-of-gpio-event-mon.patch b/queue-5.10/tools-gpio-fix-c-option-of-gpio-event-mon.patch new file mode 100644 index 00000000000..fde1e81baaf --- /dev/null +++ b/queue-5.10/tools-gpio-fix-c-option-of-gpio-event-mon.patch @@ -0,0 +1,58 @@ +From fa5915eaf31f2d2daf132b3b84c5a0eecbcbc4b5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 26 Jan 2023 15:10:33 +0200 +Subject: tools: gpio: fix -c option of gpio-event-mon + +From: Ivo Borisov Shopov + +[ Upstream commit 677d85e1a1ee69fa05ccea83847309484be3781c ] + +Following line should listen for a rising edge and exit after the first +one since '-c 1' is provided. + + # gpio-event-mon -n gpiochip1 -o 0 -r -c 1 + +It works with kernel 4.19 but it doesn't work with 5.10. In 5.10 the +above command doesn't exit after the first rising edge it keep listening +for an event forever. The '-c 1' is not taken into an account. +The problem is in commit 62757c32d5db ("tools: gpio: add multi-line +monitoring to gpio-event-mon"). +Before this commit the iterator 'i' in monitor_device() is used for +counting of the events (loops). In the case of the above command (-c 1) +we should start from 0 and increment 'i' only ones and hit the 'break' +statement and exit the process. But after the above commit counting +doesn't start from 0, it start from 1 when we listen on one line. +It is because 'i' is used from one more purpose, counting of lines +(num_lines) and it isn't restore to 0 after following code + + for (i = 0; i < num_lines; i++) + gpiotools_set_bit(&values.mask, i); + +Restore the initial value of the iterator to 0 in order to allow counting +of loops to work for any cases. + +Fixes: 62757c32d5db ("tools: gpio: add multi-line monitoring to gpio-event-mon") +Signed-off-by: Ivo Borisov Shopov +Reviewed-by: Andy Shevchenko +[Bartosz: tweak the commit message] +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Sasha Levin +--- + tools/gpio/gpio-event-mon.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tools/gpio/gpio-event-mon.c b/tools/gpio/gpio-event-mon.c +index 84ae1039b0a8..367c10636890 100644 +--- a/tools/gpio/gpio-event-mon.c ++++ b/tools/gpio/gpio-event-mon.c +@@ -86,6 +86,7 @@ int monitor_device(const char *device_name, + gpiotools_test_bit(values.bits, i)); + } + ++ i = 0; + while (1) { + struct gpio_v2_line_event event; + +-- +2.39.0 + diff --git a/queue-5.10/units-add-si-metric-prefix-definitions.patch b/queue-5.10/units-add-si-metric-prefix-definitions.patch new file mode 100644 index 00000000000..5d64650d62c --- /dev/null +++ b/queue-5.10/units-add-si-metric-prefix-definitions.patch @@ -0,0 +1,52 @@ +From c07f985884c5f5e2db433a84a8d5f7c766a41078 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 12 Jul 2021 17:20:25 +0300 +Subject: units: Add SI metric prefix definitions + +From: Andy Shevchenko + +[ Upstream commit 26471d4a6cf8d5d0bd0fb55c7169de7d67cc703a ] + +Sometimes it's useful to have well-defined SI metric prefix to be used +to self-describe the formulas or equations. + +List most popular ones in the units.h. + +Signed-off-by: Andy Shevchenko +Signed-off-by: Wolfram Sang +Stable-dep-of: c8c37bc51451 ("i2c: designware: use casting of u64 in clock multiplication to avoid overflow") +Signed-off-by: Sasha Levin +--- + include/linux/units.h | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/include/linux/units.h b/include/linux/units.h +index 92c234e71cab..3457179f7116 100644 +--- a/include/linux/units.h ++++ b/include/linux/units.h +@@ -4,6 +4,22 @@ + + #include + ++/* Metric prefixes in accordance with Système international (d'unités) */ ++#define PETA 1000000000000000ULL ++#define TERA 1000000000000ULL ++#define GIGA 1000000000UL ++#define MEGA 1000000UL ++#define KILO 1000UL ++#define HECTO 100UL ++#define DECA 10UL ++#define DECI 10UL ++#define CENTI 100UL ++#define MILLI 1000UL ++#define MICRO 1000000UL ++#define NANO 1000000000UL ++#define PICO 1000000000000ULL ++#define FEMTO 1000000000000000ULL ++ + #define MILLIWATT_PER_WATT 1000L + #define MICROWATT_PER_MILLIWATT 1000L + #define MICROWATT_PER_WATT 1000000L +-- +2.39.0 + diff --git a/queue-5.10/units-add-watt-units.patch b/queue-5.10/units-add-watt-units.patch new file mode 100644 index 00000000000..130cadca075 --- /dev/null +++ b/queue-5.10/units-add-watt-units.patch @@ -0,0 +1,38 @@ +From 4935d2785810b556a4f85e4bb9daefb30ede1da8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Dec 2020 17:41:42 +0100 +Subject: units: Add Watt units + +From: Daniel Lezcano + +[ Upstream commit 2ee5f8f05949735fa2f4c463a5e13fcb3660c719 ] + +As there are the temperature units, let's add the Watt macros definition. + +Signed-off-by: Daniel Lezcano +Reviewed-by: Lukasz Luba +Signed-off-by: Rafael J. Wysocki +Stable-dep-of: c8c37bc51451 ("i2c: designware: use casting of u64 in clock multiplication to avoid overflow") +Signed-off-by: Sasha Levin +--- + include/linux/units.h | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/include/linux/units.h b/include/linux/units.h +index aaf716364ec3..92c234e71cab 100644 +--- a/include/linux/units.h ++++ b/include/linux/units.h +@@ -4,6 +4,10 @@ + + #include + ++#define MILLIWATT_PER_WATT 1000L ++#define MICROWATT_PER_MILLIWATT 1000L ++#define MICROWATT_PER_WATT 1000000L ++ + #define ABSOLUTE_ZERO_MILLICELSIUS -273150 + + static inline long milli_kelvin_to_millicelsius(long t) +-- +2.39.0 +