From: Sasha Levin Date: Mon, 9 Dec 2024 11:18:32 +0000 (-0500) Subject: Fixes for 5.4 X-Git-Tag: v6.6.65~45 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d6096796bae6769578556430b2d8f23060266b5a;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.4 Signed-off-by: Sasha Levin --- diff --git a/queue-5.4/can-j1939-j1939_session_new-fix-skb-reference-counti.patch b/queue-5.4/can-j1939-j1939_session_new-fix-skb-reference-counti.patch new file mode 100644 index 00000000000..5c4ff0ce082 --- /dev/null +++ b/queue-5.4/can-j1939-j1939_session_new-fix-skb-reference-counti.patch @@ -0,0 +1,43 @@ +From afaea757f8d6771907cf34a9832f3bea0ac79866 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Nov 2024 12:48:23 +0300 +Subject: can: j1939: j1939_session_new(): fix skb reference counting + +From: Dmitry Antipov + +[ Upstream commit a8c695005bfe6569acd73d777ca298ddddd66105 ] + +Since j1939_session_skb_queue() does an extra skb_get() for each new +skb, do the same for the initial one in j1939_session_new() to avoid +refcount underflow. + +Reported-by: syzbot+d4e8dc385d9258220c31@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=d4e8dc385d9258220c31 +Fixes: 9d71dd0c7009 ("can: add support of SAE J1939 protocol") +Signed-off-by: Dmitry Antipov +Tested-by: Oleksij Rempel +Acked-by: Oleksij Rempel +Link: https://patch.msgid.link/20241105094823.2403806-1-dmantipov@yandex.ru +[mkl: clean up commit message] +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + net/can/j1939/transport.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c +index 1d926a0372e61..7cef19287a3ff 100644 +--- a/net/can/j1939/transport.c ++++ b/net/can/j1939/transport.c +@@ -1489,7 +1489,7 @@ static struct j1939_session *j1939_session_new(struct j1939_priv *priv, + session->state = J1939_SESSION_NEW; + + skb_queue_head_init(&session->skb_queue); +- skb_queue_tail(&session->skb_queue, skb); ++ skb_queue_tail(&session->skb_queue, skb_get(skb)); + + skcb = j1939_skb_to_cb(skb); + memcpy(&session->skcb, skcb, sizeof(session->skcb)); +-- +2.43.0 + diff --git a/queue-5.4/can-sun4i_can-sun4i_can_err-call-can_change_state-ev.patch b/queue-5.4/can-sun4i_can-sun4i_can_err-call-can_change_state-ev.patch new file mode 100644 index 00000000000..d16b7f428e3 --- /dev/null +++ b/queue-5.4/can-sun4i_can-sun4i_can_err-call-can_change_state-ev.patch @@ -0,0 +1,47 @@ +From 84b79477eef284a527684ef393b64c13aa95b013 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Nov 2024 23:15:43 +0100 +Subject: can: sun4i_can: sun4i_can_err(): call can_change_state() even if cf + is NULL + +From: Dario Binacchi + +[ Upstream commit ee6bf3677ae03569d833795064e17f605c2163c7 ] + +Call the function can_change_state() if the allocation of the skb +fails, as it handles the cf parameter when it is null. + +Additionally, this ensures that the statistics related to state error +counters (i. e. warning, passive, and bus-off) are updated. + +Fixes: 0738eff14d81 ("can: Allwinner A10/A20 CAN Controller support - Kernel module") +Signed-off-by: Dario Binacchi +Link: https://patch.msgid.link/20241122221650.633981-3-dario.binacchi@amarulasolutions.com +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + drivers/net/can/sun4i_can.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c +index c519b6f63b33a..d627fb2948be8 100644 +--- a/drivers/net/can/sun4i_can.c ++++ b/drivers/net/can/sun4i_can.c +@@ -614,10 +614,10 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status) + tx_state = txerr >= rxerr ? state : 0; + rx_state = txerr <= rxerr ? state : 0; + +- if (likely(skb)) +- can_change_state(dev, cf, tx_state, rx_state); +- else +- priv->can.state = state; ++ /* The skb allocation might fail, but can_change_state() ++ * handles cf == NULL. ++ */ ++ can_change_state(dev, cf, tx_state, rx_state); + if (state == CAN_STATE_BUS_OFF) + can_bus_off(dev); + } +-- +2.43.0 + diff --git a/queue-5.4/can-sun4i_can-sun4i_can_err-fix-rx-tx-_errors-statis.patch b/queue-5.4/can-sun4i_can-sun4i_can_err-fix-rx-tx-_errors-statis.patch new file mode 100644 index 00000000000..ce44586f99c --- /dev/null +++ b/queue-5.4/can-sun4i_can-sun4i_can_err-fix-rx-tx-_errors-statis.patch @@ -0,0 +1,63 @@ +From 93bdb1e6020b1a25a4767d0658900e5f5bdffe2d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Nov 2024 23:15:51 +0100 +Subject: can: sun4i_can: sun4i_can_err(): fix {rx,tx}_errors statistics + +From: Dario Binacchi + +[ Upstream commit 595a81988a6fe06eb5849e972c8b9cb21c4e0d54 ] + +The sun4i_can_err() function only incremented the receive error counter +and never the transmit error counter, even if the STA_ERR_DIR flag +reported that an error had occurred during transmission. + +Increment the receive/transmit error counter based on the value of the +STA_ERR_DIR flag. + +Fixes: 0738eff14d81 ("can: Allwinner A10/A20 CAN Controller support - Kernel module") +Signed-off-by: Dario Binacchi +Link: https://patch.msgid.link/20241122221650.633981-11-dario.binacchi@amarulasolutions.com +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + drivers/net/can/sun4i_can.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c +index d627fb2948be8..0eddd5779e5a2 100644 +--- a/drivers/net/can/sun4i_can.c ++++ b/drivers/net/can/sun4i_can.c +@@ -563,11 +563,9 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status) + /* bus error interrupt */ + netdev_dbg(dev, "bus error interrupt\n"); + priv->can.can_stats.bus_error++; +- stats->rx_errors++; ++ ecc = readl(priv->base + SUN4I_REG_STA_ADDR); + + if (likely(skb)) { +- ecc = readl(priv->base + SUN4I_REG_STA_ADDR); +- + cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; + + switch (ecc & SUN4I_STA_MASK_ERR) { +@@ -585,9 +583,15 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status) + >> 16; + break; + } +- /* error occurred during transmission? */ +- if ((ecc & SUN4I_STA_ERR_DIR) == 0) ++ } ++ ++ /* error occurred during transmission? */ ++ if ((ecc & SUN4I_STA_ERR_DIR) == 0) { ++ if (likely(skb)) + cf->data[2] |= CAN_ERR_PROT_TX; ++ stats->tx_errors++; ++ } else { ++ stats->rx_errors++; + } + } + if (isrc & SUN4I_INT_ERR_PASSIVE) { +-- +2.43.0 + diff --git a/queue-5.4/crypto-x86-aegis128-access-32-bit-arguments-as-32-bi.patch b/queue-5.4/crypto-x86-aegis128-access-32-bit-arguments-as-32-bi.patch new file mode 100644 index 00000000000..e7233c9400f --- /dev/null +++ b/queue-5.4/crypto-x86-aegis128-access-32-bit-arguments-as-32-bi.patch @@ -0,0 +1,136 @@ +From 4d606812eef72a7fb42016e3a6cf2351811021d7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 16 Oct 2024 17:00:42 -0700 +Subject: crypto: x86/aegis128 - access 32-bit arguments as 32-bit + +From: Eric Biggers + +[ Upstream commit 3b2f2d22fb424e9bebda4dbf6676cbfc7f9f62cd ] + +Fix the AEGIS assembly code to access 'unsigned int' arguments as 32-bit +values instead of 64-bit, since the upper bits of the corresponding +64-bit registers are not guaranteed to be zero. + +Note: there haven't been any reports of this bug actually causing +incorrect behavior. Neither gcc nor clang guarantee zero-extension to +64 bits, but zero-extension is likely to happen in practice because most +instructions that operate on 32-bit registers zero-extend to 64 bits. + +Fixes: 1d373d4e8e15 ("crypto: x86 - Add optimized AEGIS implementations") +Cc: stable@vger.kernel.org +Reviewed-by: Ondrej Mosnacek +Signed-off-by: Eric Biggers +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + arch/x86/crypto/aegis128-aesni-asm.S | 29 ++++++++++++++-------------- + 1 file changed, 15 insertions(+), 14 deletions(-) + +diff --git a/arch/x86/crypto/aegis128-aesni-asm.S b/arch/x86/crypto/aegis128-aesni-asm.S +index b7026fdef4ff2..6c5048605a664 100644 +--- a/arch/x86/crypto/aegis128-aesni-asm.S ++++ b/arch/x86/crypto/aegis128-aesni-asm.S +@@ -20,7 +20,7 @@ + #define T1 %xmm7 + + #define STATEP %rdi +-#define LEN %rsi ++#define LEN %esi + #define SRC %rdx + #define DST %rcx + +@@ -75,32 +75,32 @@ SYM_FUNC_START_LOCAL(__load_partial) + xor %r9d, %r9d + pxor MSG, MSG + +- mov LEN, %r8 ++ mov LEN, %r8d + and $0x1, %r8 + jz .Lld_partial_1 + +- mov LEN, %r8 ++ mov LEN, %r8d + and $0x1E, %r8 + add SRC, %r8 + mov (%r8), %r9b + + .Lld_partial_1: +- mov LEN, %r8 ++ mov LEN, %r8d + and $0x2, %r8 + jz .Lld_partial_2 + +- mov LEN, %r8 ++ mov LEN, %r8d + and $0x1C, %r8 + add SRC, %r8 + shl $0x10, %r9 + mov (%r8), %r9w + + .Lld_partial_2: +- mov LEN, %r8 ++ mov LEN, %r8d + and $0x4, %r8 + jz .Lld_partial_4 + +- mov LEN, %r8 ++ mov LEN, %r8d + and $0x18, %r8 + add SRC, %r8 + shl $32, %r9 +@@ -110,11 +110,11 @@ SYM_FUNC_START_LOCAL(__load_partial) + .Lld_partial_4: + movq %r9, MSG + +- mov LEN, %r8 ++ mov LEN, %r8d + and $0x8, %r8 + jz .Lld_partial_8 + +- mov LEN, %r8 ++ mov LEN, %r8d + and $0x10, %r8 + add SRC, %r8 + pslldq $8, MSG +@@ -138,7 +138,7 @@ SYM_FUNC_END(__load_partial) + * %r10 + */ + SYM_FUNC_START_LOCAL(__store_partial) +- mov LEN, %r8 ++ mov LEN, %r8d + mov DST, %r9 + + movq T0, %r10 +@@ -676,7 +676,7 @@ ENTRY(crypto_aegis128_aesni_dec_tail) + call __store_partial + + /* mask with byte count: */ +- movq LEN, T0 ++ movd LEN, T0 + punpcklbw T0, T0 + punpcklbw T0, T0 + punpcklbw T0, T0 +@@ -701,7 +701,8 @@ ENDPROC(crypto_aegis128_aesni_dec_tail) + + /* + * void crypto_aegis128_aesni_final(void *state, void *tag_xor, +- * u64 assoclen, u64 cryptlen); ++ * unsigned int assoclen, ++ * unsigned int cryptlen); + */ + ENTRY(crypto_aegis128_aesni_final) + FRAME_BEGIN +@@ -714,8 +715,8 @@ ENTRY(crypto_aegis128_aesni_final) + movdqu 0x40(STATEP), STATE4 + + /* prepare length block: */ +- movq %rdx, MSG +- movq %rcx, T0 ++ movd %edx, MSG ++ movd %ecx, T0 + pslldq $8, T0 + pxor T0, MSG + psllq $3, MSG /* multiply by 8 (to get bit count) */ +-- +2.43.0 + diff --git a/queue-5.4/dccp-fix-memory-leak-in-dccp_feat_change_recv.patch b/queue-5.4/dccp-fix-memory-leak-in-dccp_feat_change_recv.patch new file mode 100644 index 00000000000..c8f3e134b39 --- /dev/null +++ b/queue-5.4/dccp-fix-memory-leak-in-dccp_feat_change_recv.patch @@ -0,0 +1,78 @@ +From 28a481b7dab9ac180f98a6dfaf604a82c3736add Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Nov 2024 17:39:02 +0300 +Subject: dccp: Fix memory leak in dccp_feat_change_recv + +From: Ivan Solodovnikov + +[ Upstream commit 22be4727a8f898442066bcac34f8a1ad0bc72e14 ] + +If dccp_feat_push_confirm() fails after new value for SP feature was accepted +without reconciliation ('entry == NULL' branch), memory allocated for that value +with dccp_feat_clone_sp_val() is never freed. + +Here is the kmemleak stack for this: + +unreferenced object 0xffff88801d4ab488 (size 8): + comm "syz-executor310", pid 1127, jiffies 4295085598 (age 41.666s) + hex dump (first 8 bytes): + 01 b4 4a 1d 80 88 ff ff ..J..... + backtrace: + [<00000000db7cabfe>] kmemdup+0x23/0x50 mm/util.c:128 + [<0000000019b38405>] kmemdup include/linux/string.h:465 [inline] + [<0000000019b38405>] dccp_feat_clone_sp_val net/dccp/feat.c:371 [inline] + [<0000000019b38405>] dccp_feat_clone_sp_val net/dccp/feat.c:367 [inline] + [<0000000019b38405>] dccp_feat_change_recv net/dccp/feat.c:1145 [inline] + [<0000000019b38405>] dccp_feat_parse_options+0x1196/0x2180 net/dccp/feat.c:1416 + [<00000000b1f6d94a>] dccp_parse_options+0xa2a/0x1260 net/dccp/options.c:125 + [<0000000030d7b621>] dccp_rcv_state_process+0x197/0x13d0 net/dccp/input.c:650 + [<000000001f74c72e>] dccp_v4_do_rcv+0xf9/0x1a0 net/dccp/ipv4.c:688 + [<00000000a6c24128>] sk_backlog_rcv include/net/sock.h:1041 [inline] + [<00000000a6c24128>] __release_sock+0x139/0x3b0 net/core/sock.c:2570 + [<00000000cf1f3a53>] release_sock+0x54/0x1b0 net/core/sock.c:3111 + [<000000008422fa23>] inet_wait_for_connect net/ipv4/af_inet.c:603 [inline] + [<000000008422fa23>] __inet_stream_connect+0x5d0/0xf70 net/ipv4/af_inet.c:696 + [<0000000015b6f64d>] inet_stream_connect+0x53/0xa0 net/ipv4/af_inet.c:735 + [<0000000010122488>] __sys_connect_file+0x15c/0x1a0 net/socket.c:1865 + [<00000000b4b70023>] __sys_connect+0x165/0x1a0 net/socket.c:1882 + [<00000000f4cb3815>] __do_sys_connect net/socket.c:1892 [inline] + [<00000000f4cb3815>] __se_sys_connect net/socket.c:1889 [inline] + [<00000000f4cb3815>] __x64_sys_connect+0x6e/0xb0 net/socket.c:1889 + [<00000000e7b1e839>] do_syscall_64+0x33/0x40 arch/x86/entry/common.c:46 + [<0000000055e91434>] entry_SYSCALL_64_after_hwframe+0x67/0xd1 + +Clean up the allocated memory in case of dccp_feat_push_confirm() failure +and bail out with an error reset code. + +Found by Linux Verification Center (linuxtesting.org) with Syzkaller. + +Fixes: e77b8363b2ea ("dccp: Process incoming Change feature-negotiation options") +Signed-off-by: Ivan Solodovnikov +Link: https://patch.msgid.link/20241126143902.190853-1-solodovnikov.ia@phystech.edu +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/dccp/feat.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/net/dccp/feat.c b/net/dccp/feat.c +index 9c3b5e0562342..7647306802f1e 100644 +--- a/net/dccp/feat.c ++++ b/net/dccp/feat.c +@@ -1156,8 +1156,12 @@ static u8 dccp_feat_change_recv(struct list_head *fn, u8 is_mandatory, u8 opt, + goto not_valid_or_not_known; + } + +- return dccp_feat_push_confirm(fn, feat, local, &fval); ++ if (dccp_feat_push_confirm(fn, feat, local, &fval)) { ++ kfree(fval.sp.vec); ++ return DCCP_RESET_CODE_TOO_BUSY; ++ } + ++ return 0; + } else if (entry->state == FEAT_UNSTABLE) { /* 6.6.2 */ + return 0; + } +-- +2.43.0 + diff --git a/queue-5.4/gpio-grgpio-add-null-check-in-grgpio_probe.patch b/queue-5.4/gpio-grgpio-add-null-check-in-grgpio_probe.patch new file mode 100644 index 00000000000..61a4b2b704c --- /dev/null +++ b/queue-5.4/gpio-grgpio-add-null-check-in-grgpio_probe.patch @@ -0,0 +1,41 @@ +From fa237523c59b25984d1cf67fc195dbb22d20ece7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Nov 2024 17:18:22 +0800 +Subject: gpio: grgpio: Add NULL check in grgpio_probe + +From: Charles Han + +[ Upstream commit 050b23d081da0f29474de043e9538c1f7a351b3b ] + +devm_kasprintf() can return a NULL pointer on failure,but this +returned value in grgpio_probe is not checked. +Add NULL check in grgpio_probe, to handle kernel NULL +pointer dereference error. + +Cc: stable@vger.kernel.org +Fixes: 7eb6ce2f2723 ("gpio: Convert to using %pOF instead of full_name") +Signed-off-by: Charles Han +Link: https://lore.kernel.org/r/20241114091822.78199-1-hanchunchao@inspur.com +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpio-grgpio.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/gpio/gpio-grgpio.c b/drivers/gpio/gpio-grgpio.c +index 62ba651fef658..ccf407f415ab3 100644 +--- a/drivers/gpio/gpio-grgpio.c ++++ b/drivers/gpio/gpio-grgpio.c +@@ -363,6 +363,9 @@ static int grgpio_probe(struct platform_device *ofdev) + gc->owner = THIS_MODULE; + gc->to_irq = grgpio_to_irq; + gc->label = devm_kasprintf(dev, GFP_KERNEL, "%pOF", np); ++ if (!gc->label) ++ return -ENOMEM; ++ + gc->base = -1; + + err = of_property_read_u32(np, "nbits", &prop); +-- +2.43.0 + diff --git a/queue-5.4/gpio-grgpio-use-a-helper-variable-to-store-the-addre.patch b/queue-5.4/gpio-grgpio-use-a-helper-variable-to-store-the-addre.patch new file mode 100644 index 00000000000..4e856f3a12e --- /dev/null +++ b/queue-5.4/gpio-grgpio-use-a-helper-variable-to-store-the-addre.patch @@ -0,0 +1,115 @@ +From 22dff71e78b0fa4cd97b4bca98cc4b9a6262616b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Oct 2024 15:18:31 +0200 +Subject: gpio: grgpio: use a helper variable to store the address of + ofdev->dev + +From: Bartosz Golaszewski + +[ Upstream commit d036ae41cebdfae92666024163c109b8fef516fa ] + +Instead of dereferencing the platform device pointer repeatedly, just +store its address in a helper variable. + +Link: https://lore.kernel.org/r/20241015131832.44678-3-brgl@bgdev.pl +Signed-off-by: Bartosz Golaszewski +Stable-dep-of: 050b23d081da ("gpio: grgpio: Add NULL check in grgpio_probe") +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpio-grgpio.c | 23 ++++++++++++----------- + 1 file changed, 12 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpio/gpio-grgpio.c b/drivers/gpio/gpio-grgpio.c +index 3224933f4c8f4..62ba651fef658 100644 +--- a/drivers/gpio/gpio-grgpio.c ++++ b/drivers/gpio/gpio-grgpio.c +@@ -328,6 +328,7 @@ static const struct irq_domain_ops grgpio_irq_domain_ops = { + static int grgpio_probe(struct platform_device *ofdev) + { + struct device_node *np = ofdev->dev.of_node; ++ struct device *dev = &ofdev->dev; + void __iomem *regs; + struct gpio_chip *gc; + struct grgpio_priv *priv; +@@ -337,7 +338,7 @@ static int grgpio_probe(struct platform_device *ofdev) + int size; + int i; + +- priv = devm_kzalloc(&ofdev->dev, sizeof(*priv), GFP_KERNEL); ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + +@@ -346,29 +347,29 @@ static int grgpio_probe(struct platform_device *ofdev) + return PTR_ERR(regs); + + gc = &priv->gc; +- err = bgpio_init(gc, &ofdev->dev, 4, regs + GRGPIO_DATA, ++ err = bgpio_init(gc, dev, 4, regs + GRGPIO_DATA, + regs + GRGPIO_OUTPUT, NULL, regs + GRGPIO_DIR, NULL, + BGPIOF_BIG_ENDIAN_BYTE_ORDER); + if (err) { +- dev_err(&ofdev->dev, "bgpio_init() failed\n"); ++ dev_err(dev, "bgpio_init() failed\n"); + return err; + } + + priv->regs = regs; + priv->imask = gc->read_reg(regs + GRGPIO_IMASK); +- priv->dev = &ofdev->dev; ++ priv->dev = dev; + + gc->of_node = np; + gc->owner = THIS_MODULE; + gc->to_irq = grgpio_to_irq; +- gc->label = devm_kasprintf(&ofdev->dev, GFP_KERNEL, "%pOF", np); ++ gc->label = devm_kasprintf(dev, GFP_KERNEL, "%pOF", np); + gc->base = -1; + + err = of_property_read_u32(np, "nbits", &prop); + if (err || prop <= 0 || prop > GRGPIO_MAX_NGPIO) { + gc->ngpio = GRGPIO_MAX_NGPIO; +- dev_dbg(&ofdev->dev, +- "No or invalid nbits property: assume %d\n", gc->ngpio); ++ dev_dbg(dev, "No or invalid nbits property: assume %d\n", ++ gc->ngpio); + } else { + gc->ngpio = prop; + } +@@ -380,7 +381,7 @@ static int grgpio_probe(struct platform_device *ofdev) + irqmap = (s32 *)of_get_property(np, "irqmap", &size); + if (irqmap) { + if (size < gc->ngpio) { +- dev_err(&ofdev->dev, ++ dev_err(dev, + "irqmap shorter than ngpio (%d < %d)\n", + size, gc->ngpio); + return -EINVAL; +@@ -390,7 +391,7 @@ static int grgpio_probe(struct platform_device *ofdev) + &grgpio_irq_domain_ops, + priv); + if (!priv->domain) { +- dev_err(&ofdev->dev, "Could not add irq domain\n"); ++ dev_err(dev, "Could not add irq domain\n"); + return -EINVAL; + } + +@@ -420,13 +421,13 @@ static int grgpio_probe(struct platform_device *ofdev) + + err = gpiochip_add_data(gc, priv); + if (err) { +- dev_err(&ofdev->dev, "Could not add gpiochip\n"); ++ dev_err(dev, "Could not add gpiochip\n"); + if (priv->domain) + irq_domain_remove(priv->domain); + return err; + } + +- dev_info(&ofdev->dev, "regs=0x%p, base=%d, ngpio=%d, irqs=%s\n", ++ dev_info(dev, "regs=0x%p, base=%d, ngpio=%d, irqs=%s\n", + priv->regs, gc->base, gc->ngpio, priv->domain ? "on" : "off"); + + return 0; +-- +2.43.0 + diff --git a/queue-5.4/igb-fix-potential-invalid-memory-access-in-igb_init_.patch b/queue-5.4/igb-fix-potential-invalid-memory-access-in-igb_init_.patch new file mode 100644 index 00000000000..3706a55bbec --- /dev/null +++ b/queue-5.4/igb-fix-potential-invalid-memory-access-in-igb_init_.patch @@ -0,0 +1,40 @@ +From 869d278598587b9017297048656e1147b29c1303 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Oct 2024 20:10:48 +0800 +Subject: igb: Fix potential invalid memory access in igb_init_module() + +From: Yuan Can + +[ Upstream commit 0566f83d206c7a864abcd741fe39d6e0ae5eef29 ] + +The pci_register_driver() can fail and when this happened, the dca_notifier +needs to be unregistered, otherwise the dca_notifier can be called when +igb fails to install, resulting to invalid memory access. + +Fixes: bbd98fe48a43 ("igb: Fix DCA errors and do not use context index for 82576") +Signed-off-by: Yuan Can +Tested-by: Pucha Himasekhar Reddy (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/igb/igb_main.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c +index 1e9967657248a..84de6bbace090 100644 +--- a/drivers/net/ethernet/intel/igb/igb_main.c ++++ b/drivers/net/ethernet/intel/igb/igb_main.c +@@ -674,6 +674,10 @@ static int __init igb_init_module(void) + dca_register_notify(&dca_notifier); + #endif + ret = pci_register_driver(&igb_driver); ++#ifdef CONFIG_IGB_DCA ++ if (ret) ++ dca_unregister_notify(&dca_notifier); ++#endif + return ret; + } + +-- +2.43.0 + diff --git a/queue-5.4/ipvs-fix-ub-due-to-uninitialized-stack-access-in-ip_.patch b/queue-5.4/ipvs-fix-ub-due-to-uninitialized-stack-access-in-ip_.patch new file mode 100644 index 00000000000..d4af46a8bc3 --- /dev/null +++ b/queue-5.4/ipvs-fix-ub-due-to-uninitialized-stack-access-in-ip_.patch @@ -0,0 +1,117 @@ +From 8b2a1d14aff584f8ff23a86d6822241ca1d106e2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 23 Nov 2024 03:42:56 -0600 +Subject: ipvs: fix UB due to uninitialized stack access in + ip_vs_protocol_init() + +From: Jinghao Jia + +[ Upstream commit 146b6f1112eb30a19776d6c323c994e9d67790db ] + +Under certain kernel configurations when building with Clang/LLVM, the +compiler does not generate a return or jump as the terminator +instruction for ip_vs_protocol_init(), triggering the following objtool +warning during build time: + + vmlinux.o: warning: objtool: ip_vs_protocol_init() falls through to next function __initstub__kmod_ip_vs_rr__935_123_ip_vs_rr_init6() + +At runtime, this either causes an oops when trying to load the ipvs +module or a boot-time panic if ipvs is built-in. This same issue has +been reported by the Intel kernel test robot previously. + +Digging deeper into both LLVM and the kernel code reveals this to be a +undefined behavior problem. ip_vs_protocol_init() uses a on-stack buffer +of 64 chars to store the registered protocol names and leaves it +uninitialized after definition. The function calls strnlen() when +concatenating protocol names into the buffer. With CONFIG_FORTIFY_SOURCE +strnlen() performs an extra step to check whether the last byte of the +input char buffer is a null character (commit 3009f891bb9f ("fortify: +Allow strlen() and strnlen() to pass compile-time known lengths")). +This, together with possibly other configurations, cause the following +IR to be generated: + + define hidden i32 @ip_vs_protocol_init() local_unnamed_addr #5 section ".init.text" align 16 !kcfi_type !29 { + %1 = alloca [64 x i8], align 16 + ... + + 14: ; preds = %11 + %15 = getelementptr inbounds i8, ptr %1, i64 63 + %16 = load i8, ptr %15, align 1 + %17 = tail call i1 @llvm.is.constant.i8(i8 %16) + %18 = icmp eq i8 %16, 0 + %19 = select i1 %17, i1 %18, i1 false + br i1 %19, label %20, label %23 + + 20: ; preds = %14 + %21 = call i64 @strlen(ptr noundef nonnull dereferenceable(1) %1) #23 + ... + + 23: ; preds = %14, %11, %20 + %24 = call i64 @strnlen(ptr noundef nonnull dereferenceable(1) %1, i64 noundef 64) #24 + ... + } + +The above code calculates the address of the last char in the buffer +(value %15) and then loads from it (value %16). Because the buffer is +never initialized, the LLVM GVN pass marks value %16 as undefined: + + %13 = getelementptr inbounds i8, ptr %1, i64 63 + br i1 undef, label %14, label %17 + +This gives later passes (SCCP, in particular) more DCE opportunities by +propagating the undef value further, and eventually removes everything +after the load on the uninitialized stack location: + + define hidden i32 @ip_vs_protocol_init() local_unnamed_addr #0 section ".init.text" align 16 !kcfi_type !11 { + %1 = alloca [64 x i8], align 16 + ... + + 12: ; preds = %11 + %13 = getelementptr inbounds i8, ptr %1, i64 63 + unreachable + } + +In this way, the generated native code will just fall through to the +next function, as LLVM does not generate any code for the unreachable IR +instruction and leaves the function without a terminator. + +Zero the on-stack buffer to avoid this possible UB. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202402100205.PWXIz1ZK-lkp@intel.com/ +Co-developed-by: Ruowen Qin +Signed-off-by: Ruowen Qin +Signed-off-by: Jinghao Jia +Acked-by: Julian Anastasov +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/ipvs/ip_vs_proto.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/net/netfilter/ipvs/ip_vs_proto.c b/net/netfilter/ipvs/ip_vs_proto.c +index f100da4ba3bc3..a9fd1d3fc2cbf 100644 +--- a/net/netfilter/ipvs/ip_vs_proto.c ++++ b/net/netfilter/ipvs/ip_vs_proto.c +@@ -340,7 +340,7 @@ void __net_exit ip_vs_protocol_net_cleanup(struct netns_ipvs *ipvs) + + int __init ip_vs_protocol_init(void) + { +- char protocols[64]; ++ char protocols[64] = { 0 }; + #define REGISTER_PROTOCOL(p) \ + do { \ + register_ip_vs_protocol(p); \ +@@ -348,8 +348,6 @@ int __init ip_vs_protocol_init(void) + strcat(protocols, (p)->name); \ + } while (0) + +- protocols[0] = '\0'; +- protocols[2] = '\0'; + #ifdef CONFIG_IP_VS_PROTO_TCP + REGISTER_PROTOCOL(&ip_vs_protocol_tcp); + #endif +-- +2.43.0 + diff --git a/queue-5.4/itco_wdt-mask-nmi_now-bit-for-update_no_reboot_bit-c.patch b/queue-5.4/itco_wdt-mask-nmi_now-bit-for-update_no_reboot_bit-c.patch new file mode 100644 index 00000000000..de0a970f880 --- /dev/null +++ b/queue-5.4/itco_wdt-mask-nmi_now-bit-for-update_no_reboot_bit-c.patch @@ -0,0 +1,85 @@ +From f3a8d8bc065850255ca3bf7119e745fddbd9885a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Sep 2024 12:14:03 -0700 +Subject: iTCO_wdt: mask NMI_NOW bit for update_no_reboot_bit() call + +From: Oleksandr Ocheretnyi + +[ Upstream commit daa814d784ac034c62ab3fb0ef83daeafef527e2 ] + +Commit da23b6faa8bf ("watchdog: iTCO: Add support for Cannon Lake +PCH iTCO") does not mask NMI_NOW bit during TCO1_CNT register's +value comparison for update_no_reboot_bit() call causing following +failure: + + ... + iTCO_vendor_support: vendor-support=0 + iTCO_wdt iTCO_wdt: unable to reset NO_REBOOT flag, device + disabled by hardware/BIOS + ... + +and this can lead to unexpected NMIs later during regular +crashkernel's workflow because of watchdog probe call failures. + +This change masks NMI_NOW bit for TCO1_CNT register values to +avoid unexpected NMI_NOW bit inversions. + +Fixes: da23b6faa8bf ("watchdog: iTCO: Add support for Cannon Lake PCH iTCO") +Signed-off-by: Oleksandr Ocheretnyi +Reviewed-by: Guenter Roeck +Reviewed-by: Mika Westerberg +Link: https://lore.kernel.org/r/20240913191403.2560805-1-oocheret@cisco.com +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Sasha Levin +--- + drivers/watchdog/iTCO_wdt.c | 21 +++++++++++++++++++-- + 1 file changed, 19 insertions(+), 2 deletions(-) + +diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c +index 134237d8b8fca..c03df400ffb90 100644 +--- a/drivers/watchdog/iTCO_wdt.c ++++ b/drivers/watchdog/iTCO_wdt.c +@@ -83,6 +83,13 @@ + #define TCO2_CNT(p) (TCOBASE(p) + 0x0a) /* TCO2 Control Register */ + #define TCOv2_TMR(p) (TCOBASE(p) + 0x12) /* TCOv2 Timer Initial Value*/ + ++/* ++ * NMI_NOW is bit 8 of TCO1_CNT register ++ * Read/Write ++ * This bit is implemented as RW but has no effect on HW. ++ */ ++#define NMI_NOW BIT(8) ++ + /* internal variables */ + struct iTCO_wdt_private { + struct watchdog_device wddev; +@@ -221,13 +228,23 @@ static int update_no_reboot_bit_cnt(void *priv, bool set) + struct iTCO_wdt_private *p = priv; + u16 val, newval; + +- val = inw(TCO1_CNT(p)); ++ /* ++ * writing back 1b1 to NMI_NOW of TCO1_CNT register ++ * causes NMI_NOW bit inversion what consequently does ++ * not allow to perform the register's value comparison ++ * properly. ++ * ++ * NMI_NOW bit masking for TCO1_CNT register values ++ * helps to avoid possible NMI_NOW bit inversions on ++ * following write operation. ++ */ ++ val = inw(TCO1_CNT(p)) & ~NMI_NOW; + if (set) + val |= BIT(0); + else + val &= ~BIT(0); + outw(val, TCO1_CNT(p)); +- newval = inw(TCO1_CNT(p)); ++ newval = inw(TCO1_CNT(p)) & ~NMI_NOW; + + /* make sure the update is successful */ + return val != newval ? -EIO : 0; +-- +2.43.0 + diff --git a/queue-5.4/net-ipv6-release-expired-exception-dst-cached-in-soc.patch b/queue-5.4/net-ipv6-release-expired-exception-dst-cached-in-soc.patch new file mode 100644 index 00000000000..9cd2786d744 --- /dev/null +++ b/queue-5.4/net-ipv6-release-expired-exception-dst-cached-in-soc.patch @@ -0,0 +1,85 @@ +From ed9484e1ff6ad7290e7c790f8653203987c9f480 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 28 Nov 2024 09:59:50 +0100 +Subject: net/ipv6: release expired exception dst cached in socket + +From: Jiri Wiesner + +[ Upstream commit 3301ab7d5aeb0fe270f73a3d4810c9d1b6a9f045 ] + +Dst objects get leaked in ip6_negative_advice() when this function is +executed for an expired IPv6 route located in the exception table. There +are several conditions that must be fulfilled for the leak to occur: +* an ICMPv6 packet indicating a change of the MTU for the path is received, + resulting in an exception dst being created +* a TCP connection that uses the exception dst for routing packets must + start timing out so that TCP begins retransmissions +* after the exception dst expires, the FIB6 garbage collector must not run + before TCP executes ip6_negative_advice() for the expired exception dst + +When TCP executes ip6_negative_advice() for an exception dst that has +expired and if no other socket holds a reference to the exception dst, the +refcount of the exception dst is 2, which corresponds to the increment +made by dst_init() and the increment made by the TCP socket for which the +connection is timing out. The refcount made by the socket is never +released. The refcount of the dst is decremented in sk_dst_reset() but +that decrement is counteracted by a dst_hold() intentionally placed just +before the sk_dst_reset() in ip6_negative_advice(). After +ip6_negative_advice() has finished, there is no other object tied to the +dst. The socket lost its reference stored in sk_dst_cache and the dst is +no longer in the exception table. The exception dst becomes a leaked +object. + +As a result of this dst leak, an unbalanced refcount is reported for the +loopback device of a net namespace being destroyed under kernels that do +not contain e5f80fcf869a ("ipv6: give an IPv6 dev to blackhole_netdev"): +unregister_netdevice: waiting for lo to become free. Usage count = 2 + +Fix the dst leak by removing the dst_hold() in ip6_negative_advice(). The +patch that introduced the dst_hold() in ip6_negative_advice() was +92f1655aa2b22 ("net: fix __dst_negative_advice() race"). But 92f1655aa2b22 +merely refactored the code with regards to the dst refcount so the issue +was present even before 92f1655aa2b22. The bug was introduced in +54c1a859efd9f ("ipv6: Don't drop cache route entry unless timer actually +expired.") where the expired cached route is deleted and the sk_dst_cache +member of the socket is set to NULL by calling dst_negative_advice() but +the refcount belonging to the socket is left unbalanced. + +The IPv4 version - ipv4_negative_advice() - is not affected by this bug. +When the TCP connection times out ipv4_negative_advice() merely resets the +sk_dst_cache of the socket while decrementing the refcount of the +exception dst. + +Fixes: 92f1655aa2b22 ("net: fix __dst_negative_advice() race") +Fixes: 54c1a859efd9f ("ipv6: Don't drop cache route entry unless timer actually expired.") +Link: https://lore.kernel.org/netdev/20241113105611.GA6723@incl/T/#u +Signed-off-by: Jiri Wiesner +Reviewed-by: Eric Dumazet +Link: https://patch.msgid.link/20241128085950.GA4505@incl +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv6/route.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index 2e91a563139a8..f1c2ac967e36c 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -2670,10 +2670,10 @@ static void ip6_negative_advice(struct sock *sk, + if (rt->rt6i_flags & RTF_CACHE) { + rcu_read_lock(); + if (rt6_check_expired(rt)) { +- /* counteract the dst_release() in sk_dst_reset() */ +- dst_hold(dst); ++ /* rt/dst can not be destroyed yet, ++ * because of rcu_read_lock() ++ */ + sk_dst_reset(sk); +- + rt6_remove_exception_rt(rt); + } + rcu_read_unlock(); +-- +2.43.0 + diff --git a/queue-5.4/net-qed-allow-old-cards-not-supporting-num_images-to.patch b/queue-5.4/net-qed-allow-old-cards-not-supporting-num_images-to.patch new file mode 100644 index 00000000000..ee7413677cf --- /dev/null +++ b/queue-5.4/net-qed-allow-old-cards-not-supporting-num_images-to.patch @@ -0,0 +1,48 @@ +From c6376df776c740c335583e200d1fa43bac458484 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 28 Nov 2024 09:33:58 +0100 +Subject: net/qed: allow old cards not supporting "num_images" to work + +From: Louis Leseur + +[ Upstream commit 7a0ea70da56ee8c2716d0b79e9959d3c47efab62 ] + +Commit 43645ce03e00 ("qed: Populate nvm image attribute shadow.") +added support for populating flash image attributes, notably +"num_images". However, some cards were not able to return this +information. In such cases, the driver would return EINVAL, causing the +driver to exit. + +Add check to return EOPNOTSUPP instead of EINVAL when the card is not +able to return these information. The caller function already handles +EOPNOTSUPP without error. + +Fixes: 43645ce03e00 ("qed: Populate nvm image attribute shadow.") +Co-developed-by: Florian Forestier +Signed-off-by: Florian Forestier +Signed-off-by: Louis Leseur +Link: https://patch.msgid.link/20241128083633.26431-1-louis.leseur@gmail.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/qlogic/qed/qed_mcp.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.c b/drivers/net/ethernet/qlogic/qed/qed_mcp.c +index 3769b15b04b3b..168dbf11efed8 100644 +--- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c ++++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c +@@ -3059,7 +3059,9 @@ int qed_mcp_bist_nvm_get_num_images(struct qed_hwfn *p_hwfn, + if (rc) + return rc; + +- if (((rsp & FW_MSG_CODE_MASK) != FW_MSG_CODE_OK)) ++ if (((rsp & FW_MSG_CODE_MASK) == FW_MSG_CODE_UNSUPPORTED)) ++ rc = -EOPNOTSUPP; ++ else if (((rsp & FW_MSG_CODE_MASK) != FW_MSG_CODE_OK)) + rc = -EINVAL; + + return rc; +-- +2.43.0 + diff --git a/queue-5.4/net-sched-tbf-correct-backlog-statistic-for-gso-pack.patch b/queue-5.4/net-sched-tbf-correct-backlog-statistic-for-gso-pack.patch new file mode 100644 index 00000000000..775570a51c7 --- /dev/null +++ b/queue-5.4/net-sched-tbf-correct-backlog-statistic-for-gso-pack.patch @@ -0,0 +1,91 @@ +From d5b1723db6ea5c340a96239b76fe451a9793f53f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 25 Nov 2024 18:46:07 +0100 +Subject: net/sched: tbf: correct backlog statistic for GSO packets + +From: Martin Ottens + +[ Upstream commit 1596a135e3180c92e42dd1fbcad321f4fb3e3b17 ] + +When the length of a GSO packet in the tbf qdisc is larger than the burst +size configured the packet will be segmented by the tbf_segment function. +Whenever this function is used to enqueue SKBs, the backlog statistic of +the tbf is not increased correctly. This can lead to underflows of the +'backlog' byte-statistic value when these packets are dequeued from tbf. + +Reproduce the bug: +Ensure that the sender machine has GSO enabled. Configured the tbf on +the outgoing interface of the machine as follows (burstsize = 1 MTU): +$ tc qdisc add dev root handle 1: tbf rate 50Mbit burst 1514 latency 50ms + +Send bulk TCP traffic out via this interface, e.g., by running an iPerf3 +client on this machine. Check the qdisc statistics: +$ tc -s qdisc show dev + +The 'backlog' byte-statistic has incorrect values while traffic is +transferred, e.g., high values due to u32 underflows. When the transfer +is stopped, the value is != 0, which should never happen. + +This patch fixes this bug by updating the statistics correctly, even if +single SKBs of a GSO SKB cannot be enqueued. + +Fixes: e43ac79a4bc6 ("sch_tbf: segment too big GSO packets") +Signed-off-by: Martin Ottens +Reviewed-by: Eric Dumazet +Link: https://patch.msgid.link/20241125174608.1484356-1-martin.ottens@fau.de +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sched/sch_tbf.c | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c +index a7f60bb2dd513..259a39ca99bfb 100644 +--- a/net/sched/sch_tbf.c ++++ b/net/sched/sch_tbf.c +@@ -146,7 +146,7 @@ static int tbf_segment(struct sk_buff *skb, struct Qdisc *sch, + struct tbf_sched_data *q = qdisc_priv(sch); + struct sk_buff *segs, *nskb; + netdev_features_t features = netif_skb_features(skb); +- unsigned int len = 0, prev_len = qdisc_pkt_len(skb); ++ unsigned int len = 0, prev_len = qdisc_pkt_len(skb), seg_len; + int ret, nb; + + segs = skb_gso_segment(skb, features & ~NETIF_F_GSO_MASK); +@@ -158,22 +158,28 @@ static int tbf_segment(struct sk_buff *skb, struct Qdisc *sch, + while (segs) { + nskb = segs->next; + skb_mark_not_on_list(segs); +- qdisc_skb_cb(segs)->pkt_len = segs->len; +- len += segs->len; ++ seg_len = segs->len; ++ qdisc_skb_cb(segs)->pkt_len = seg_len; + ret = qdisc_enqueue(segs, q->qdisc, to_free); + if (ret != NET_XMIT_SUCCESS) { + if (net_xmit_drop_count(ret)) + qdisc_qstats_drop(sch); + } else { + nb++; ++ len += seg_len; + } + segs = nskb; + } + sch->q.qlen += nb; +- if (nb > 1) ++ sch->qstats.backlog += len; ++ if (nb > 0) { + qdisc_tree_reduce_backlog(sch, 1 - nb, prev_len - len); +- consume_skb(skb); +- return nb > 0 ? NET_XMIT_SUCCESS : NET_XMIT_DROP; ++ consume_skb(skb); ++ return NET_XMIT_SUCCESS; ++ } ++ ++ kfree_skb(skb); ++ return NET_XMIT_DROP; + } + + static int tbf_enqueue(struct sk_buff *skb, struct Qdisc *sch, +-- +2.43.0 + diff --git a/queue-5.4/netfilter-ipset-hold-module-reference-while-requesti.patch b/queue-5.4/netfilter-ipset-hold-module-reference-while-requesti.patch new file mode 100644 index 00000000000..5829267ecbc --- /dev/null +++ b/queue-5.4/netfilter-ipset-hold-module-reference-while-requesti.patch @@ -0,0 +1,49 @@ +From a51c30bf991ead1673fc672b432feb7638a62031 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Nov 2024 16:30:38 +0100 +Subject: netfilter: ipset: Hold module reference while requesting a module + +From: Phil Sutter + +[ Upstream commit 456f010bfaefde84d3390c755eedb1b0a5857c3c ] + +User space may unload ip_set.ko while it is itself requesting a set type +backend module, leading to a kernel crash. The race condition may be +provoked by inserting an mdelay() right after the nfnl_unlock() call. + +Fixes: a7b4f989a629 ("netfilter: ipset: IP set core support") +Signed-off-by: Phil Sutter +Acked-by: Jozsef Kadlecsik +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/ipset/ip_set_core.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c +index 83fa95ecaad47..1ce19162ebf79 100644 +--- a/net/netfilter/ipset/ip_set_core.c ++++ b/net/netfilter/ipset/ip_set_core.c +@@ -103,14 +103,19 @@ find_set_type(const char *name, u8 family, u8 revision) + static bool + load_settype(const char *name) + { ++ if (!try_module_get(THIS_MODULE)) ++ return false; ++ + nfnl_unlock(NFNL_SUBSYS_IPSET); + pr_debug("try to load ip_set_%s\n", name); + if (request_module("ip_set_%s", name) < 0) { + pr_warn("Can't find ip_set type %s\n", name); + nfnl_lock(NFNL_SUBSYS_IPSET); ++ module_put(THIS_MODULE); + return false; + } + nfnl_lock(NFNL_SUBSYS_IPSET); ++ module_put(THIS_MODULE); + return true; + } + +-- +2.43.0 + diff --git a/queue-5.4/netfilter-nft_set_hash-skip-duplicated-elements-pend.patch b/queue-5.4/netfilter-nft_set_hash-skip-duplicated-elements-pend.patch new file mode 100644 index 00000000000..d71696804f0 --- /dev/null +++ b/queue-5.4/netfilter-nft_set_hash-skip-duplicated-elements-pend.patch @@ -0,0 +1,97 @@ +From 3b8048da92d50cd6f81901f89bf5c58405171e95 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Dec 2024 00:04:49 +0100 +Subject: netfilter: nft_set_hash: skip duplicated elements pending gc run + +From: Pablo Neira Ayuso + +[ Upstream commit 7ffc7481153bbabf3332c6a19b289730c7e1edf5 ] + +rhashtable does not provide stable walk, duplicated elements are +possible in case of resizing. I considered that checking for errors when +calling rhashtable_walk_next() was sufficient to detect the resizing. +However, rhashtable_walk_next() returns -EAGAIN only at the end of the +iteration, which is too late, because a gc work containing duplicated +elements could have been already scheduled for removal to the worker. + +Add a u32 gc worker sequence number per set, bump it on every workqueue +run. Annotate gc worker sequence number on the expired element. Use it +to skip those already seen in this gc workqueue run. + +Note that this new field is never reset in case gc transaction fails, so +next gc worker run on the expired element overrides it. Wraparound of gc +worker sequence number should not be an issue with stale gc worker +sequence number in the element, that would just postpone the element +removal in one gc run. + +Note that it is not possible to use flags to annotate that element is +pending gc run to detect duplicates, given that gc transaction can be +invalidated in case of update from the control plane, therefore, not +allowing to clear such flag. + +On x86_64, pahole reports no changes in the size of nft_rhash_elem. + +Fixes: f6c383b8c31a ("netfilter: nf_tables: adapt set backend to use GC transaction API") +Reported-by: Laurent Fasnacht +Tested-by: Laurent Fasnacht +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nft_set_hash.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/net/netfilter/nft_set_hash.c b/net/netfilter/nft_set_hash.c +index ec03d4c77b3df..200f837372adf 100644 +--- a/net/netfilter/nft_set_hash.c ++++ b/net/netfilter/nft_set_hash.c +@@ -27,10 +27,12 @@ extern unsigned int nf_tables_net_id; + struct nft_rhash { + struct rhashtable ht; + struct delayed_work gc_work; ++ u32 wq_gc_seq; + }; + + struct nft_rhash_elem { + struct rhash_head node; ++ u32 wq_gc_seq; + struct nft_set_ext ext; + }; + +@@ -325,6 +327,10 @@ static void nft_rhash_gc(struct work_struct *work) + if (!gc) + goto done; + ++ /* Elements never collected use a zero gc worker sequence number. */ ++ if (unlikely(++priv->wq_gc_seq == 0)) ++ priv->wq_gc_seq++; ++ + rhashtable_walk_enter(&priv->ht, &hti); + rhashtable_walk_start(&hti); + +@@ -342,6 +348,14 @@ static void nft_rhash_gc(struct work_struct *work) + goto try_later; + } + ++ /* rhashtable walk is unstable, already seen in this gc run? ++ * Then, skip this element. In case of (unlikely) sequence ++ * wraparound and stale element wq_gc_seq, next gc run will ++ * just find this expired element. ++ */ ++ if (he->wq_gc_seq == priv->wq_gc_seq) ++ continue; ++ + if (nft_set_elem_is_dead(&he->ext)) + goto dead_elem; + +@@ -362,6 +376,8 @@ static void nft_rhash_gc(struct work_struct *work) + if (!gc) + goto try_later; + ++ /* annotate gc sequence for this attempt. */ ++ he->wq_gc_seq = priv->wq_gc_seq; + nft_trans_gc_elem_add(gc, he); + } + +-- +2.43.0 + diff --git a/queue-5.4/netfilter-x_tables-fix-led-id-check-in-led_tg_check.patch b/queue-5.4/netfilter-x_tables-fix-led-id-check-in-led_tg_check.patch new file mode 100644 index 00000000000..88a22379391 --- /dev/null +++ b/queue-5.4/netfilter-x_tables-fix-led-id-check-in-led_tg_check.patch @@ -0,0 +1,109 @@ +From c97bfaf8682b099278ae7a40357b9a35f581aa12 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Nov 2024 09:55:42 +0300 +Subject: netfilter: x_tables: fix LED ID check in led_tg_check() + +From: Dmitry Antipov + +[ Upstream commit 04317f4eb2aad312ad85c1a17ad81fe75f1f9bc7 ] + +Syzbot has reported the following BUG detected by KASAN: + +BUG: KASAN: slab-out-of-bounds in strlen+0x58/0x70 +Read of size 1 at addr ffff8881022da0c8 by task repro/5879 +... +Call Trace: + + dump_stack_lvl+0x241/0x360 + ? __pfx_dump_stack_lvl+0x10/0x10 + ? __pfx__printk+0x10/0x10 + ? _printk+0xd5/0x120 + ? __virt_addr_valid+0x183/0x530 + ? __virt_addr_valid+0x183/0x530 + print_report+0x169/0x550 + ? __virt_addr_valid+0x183/0x530 + ? __virt_addr_valid+0x183/0x530 + ? __virt_addr_valid+0x45f/0x530 + ? __phys_addr+0xba/0x170 + ? strlen+0x58/0x70 + kasan_report+0x143/0x180 + ? strlen+0x58/0x70 + strlen+0x58/0x70 + kstrdup+0x20/0x80 + led_tg_check+0x18b/0x3c0 + xt_check_target+0x3bb/0xa40 + ? __pfx_xt_check_target+0x10/0x10 + ? stack_depot_save_flags+0x6e4/0x830 + ? nft_target_init+0x174/0xc30 + nft_target_init+0x82d/0xc30 + ? __pfx_nft_target_init+0x10/0x10 + ? nf_tables_newrule+0x1609/0x2980 + ? nf_tables_newrule+0x1609/0x2980 + ? rcu_is_watching+0x15/0xb0 + ? nf_tables_newrule+0x1609/0x2980 + ? nf_tables_newrule+0x1609/0x2980 + ? __kmalloc_noprof+0x21a/0x400 + nf_tables_newrule+0x1860/0x2980 + ? __pfx_nf_tables_newrule+0x10/0x10 + ? __nla_parse+0x40/0x60 + nfnetlink_rcv+0x14e5/0x2ab0 + ? __pfx_validate_chain+0x10/0x10 + ? __pfx_nfnetlink_rcv+0x10/0x10 + ? __lock_acquire+0x1384/0x2050 + ? netlink_deliver_tap+0x2e/0x1b0 + ? __pfx_lock_release+0x10/0x10 + ? netlink_deliver_tap+0x2e/0x1b0 + netlink_unicast+0x7f8/0x990 + ? __pfx_netlink_unicast+0x10/0x10 + ? __virt_addr_valid+0x183/0x530 + ? __check_object_size+0x48e/0x900 + netlink_sendmsg+0x8e4/0xcb0 + ? __pfx_netlink_sendmsg+0x10/0x10 + ? aa_sock_msg_perm+0x91/0x160 + ? __pfx_netlink_sendmsg+0x10/0x10 + __sock_sendmsg+0x223/0x270 + ____sys_sendmsg+0x52a/0x7e0 + ? __pfx_____sys_sendmsg+0x10/0x10 + __sys_sendmsg+0x292/0x380 + ? __pfx___sys_sendmsg+0x10/0x10 + ? lockdep_hardirqs_on_prepare+0x43d/0x780 + ? __pfx_lockdep_hardirqs_on_prepare+0x10/0x10 + ? exc_page_fault+0x590/0x8c0 + ? do_syscall_64+0xb6/0x230 + do_syscall_64+0xf3/0x230 + entry_SYSCALL_64_after_hwframe+0x77/0x7f +... + + +Since an invalid (without '\0' byte at all) byte sequence may be passed +from userspace, add an extra check to ensure that such a sequence is +rejected as possible ID and so never passed to 'kstrdup()' and further. + +Reported-by: syzbot+6c8215822f35fdb35667@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=6c8215822f35fdb35667 +Fixes: 268cb38e1802 ("netfilter: x_tables: add LED trigger target") +Signed-off-by: Dmitry Antipov +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/xt_LED.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/net/netfilter/xt_LED.c b/net/netfilter/xt_LED.c +index 0371c387b0d1f..13a2b5820b34b 100644 +--- a/net/netfilter/xt_LED.c ++++ b/net/netfilter/xt_LED.c +@@ -97,7 +97,9 @@ static int led_tg_check(const struct xt_tgchk_param *par) + struct xt_led_info_internal *ledinternal; + int err; + +- if (ledinfo->id[0] == '\0') ++ /* Bail out if empty string or not a string at all. */ ++ if (ledinfo->id[0] == '\0' || ++ !memchr(ledinfo->id, '\0', sizeof(ledinfo->id))) + return -EINVAL; + + mutex_lock(&xt_led_mutex); +-- +2.43.0 + diff --git a/queue-5.4/series b/queue-5.4/series index fecc5c70227..c1ef19a6f07 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -218,3 +218,31 @@ dm-thin-add-missing-destroy_work_on_stack.patch nfsd-make-sure-exp-active-before-svc_export_show.patch nfsd-fix-nfs4_openowner-leak-when-concurrent-nfsd4_open-occur.patch drm-etnaviv-flush-shader-l1-cache-after-user-commandstream.patch +itco_wdt-mask-nmi_now-bit-for-update_no_reboot_bit-c.patch +watchdog-mediatek-make-sure-system-reset-gets-assert.patch +can-sun4i_can-sun4i_can_err-call-can_change_state-ev.patch +can-sun4i_can-sun4i_can_err-fix-rx-tx-_errors-statis.patch +ipvs-fix-ub-due-to-uninitialized-stack-access-in-ip_.patch +netfilter-x_tables-fix-led-id-check-in-led_tg_check.patch +net-sched-tbf-correct-backlog-statistic-for-gso-pack.patch +can-j1939-j1939_session_new-fix-skb-reference-counti.patch +net-ipv6-release-expired-exception-dst-cached-in-soc.patch +dccp-fix-memory-leak-in-dccp_feat_change_recv.patch +tipc-add-reference-counter-to-bearer.patch +tipc-enable-creating-a-preliminary-node.patch +tipc-add-new-aead-key-structure-for-user-api.patch +tipc-fix-use-after-free-of-kernel-socket-in-cleanup_.patch +net-qed-allow-old-cards-not-supporting-num_images-to.patch +igb-fix-potential-invalid-memory-access-in-igb_init_.patch +netfilter-ipset-hold-module-reference-while-requesti.patch +netfilter-nft_set_hash-skip-duplicated-elements-pend.patch +xen-xenbus-reference-count-registered-modules.patch +xenbus-backend-add-memory-pressure-handler-callback.patch +xenbus-backend-protect-xenbus-callback-with-lock.patch +xen-xenbus-fix-locking.patch +xen-fix-the-issue-of-resource-not-being-properly-rel.patch +x86-asm-reorder-early-variables.patch +x86-asm-crypto-annotate-local-functions.patch +crypto-x86-aegis128-access-32-bit-arguments-as-32-bi.patch +gpio-grgpio-use-a-helper-variable-to-store-the-addre.patch +gpio-grgpio-add-null-check-in-grgpio_probe.patch diff --git a/queue-5.4/tipc-add-new-aead-key-structure-for-user-api.patch b/queue-5.4/tipc-add-new-aead-key-structure-for-user-api.patch new file mode 100644 index 00000000000..d288c72dcda --- /dev/null +++ b/queue-5.4/tipc-add-new-aead-key-structure-for-user-api.patch @@ -0,0 +1,58 @@ +From 092b2eb7e9298c5ed31276a0977ae9c46e01c94b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 8 Nov 2019 12:05:10 +0700 +Subject: tipc: add new AEAD key structure for user API + +From: Tuong Lien + +[ Upstream commit 134bdac397661a5841d9f27f508190c68b26232b ] + +The new structure 'tipc_aead_key' is added to the 'tipc.h' for user to +be able to transfer a key to TIPC in kernel. Netlink will be used for +this purpose in the later commits. + +Acked-by: Ying Xue +Acked-by: Jon Maloy +Signed-off-by: Tuong Lien +Signed-off-by: David S. Miller +Stable-dep-of: 6a2fa13312e5 ("tipc: Fix use-after-free of kernel socket in cleanup_bearer().") +Signed-off-by: Sasha Levin +--- + include/uapi/linux/tipc.h | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +diff --git a/include/uapi/linux/tipc.h b/include/uapi/linux/tipc.h +index 7df026ea6affa..a1b64a9167970 100644 +--- a/include/uapi/linux/tipc.h ++++ b/include/uapi/linux/tipc.h +@@ -232,6 +232,27 @@ struct tipc_sioc_nodeid_req { + char node_id[TIPC_NODEID_LEN]; + }; + ++/* ++ * TIPC Crypto, AEAD ++ */ ++#define TIPC_AEAD_ALG_NAME (32) ++ ++struct tipc_aead_key { ++ char alg_name[TIPC_AEAD_ALG_NAME]; ++ unsigned int keylen; /* in bytes */ ++ char key[]; ++}; ++ ++#define TIPC_AEAD_KEYLEN_MIN (16 + 4) ++#define TIPC_AEAD_KEYLEN_MAX (32 + 4) ++#define TIPC_AEAD_KEY_SIZE_MAX (sizeof(struct tipc_aead_key) + \ ++ TIPC_AEAD_KEYLEN_MAX) ++ ++static inline int tipc_aead_key_size(struct tipc_aead_key *key) ++{ ++ return sizeof(*key) + key->keylen; ++} ++ + /* The macros and functions below are deprecated: + */ + +-- +2.43.0 + diff --git a/queue-5.4/tipc-add-reference-counter-to-bearer.patch b/queue-5.4/tipc-add-reference-counter-to-bearer.patch new file mode 100644 index 00000000000..bf0c0e1ea82 --- /dev/null +++ b/queue-5.4/tipc-add-reference-counter-to-bearer.patch @@ -0,0 +1,92 @@ +From d824d7e2a6eacc64760b7c548d4c680e37adb2c3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 8 Nov 2019 12:05:08 +0700 +Subject: tipc: add reference counter to bearer + +From: Tuong Lien + +[ Upstream commit 2a7ee696f7b000a970dcce0cb06fdcd0a9e6ee76 ] + +As a need to support the crypto asynchronous operations in the later +commits, apart from the current RCU mechanism for bearer pointer, we +add a 'refcnt' to the bearer object as well. + +So, a bearer can be hold via 'tipc_bearer_hold()' without being freed +even though the bearer or interface can be disabled in the meanwhile. +If that happens, the bearer will be released then when the crypto +operation is completed and 'tipc_bearer_put()' is called. + +Acked-by: Ying Xue +Acked-by: Jon Maloy +Signed-off-by: Tuong Lien +Signed-off-by: David S. Miller +Stable-dep-of: 6a2fa13312e5 ("tipc: Fix use-after-free of kernel socket in cleanup_bearer().") +Signed-off-by: Sasha Levin +--- + net/tipc/bearer.c | 14 +++++++++++++- + net/tipc/bearer.h | 3 +++ + 2 files changed, 16 insertions(+), 1 deletion(-) + +diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c +index dc5c6b1e97910..fc0b787fb9286 100644 +--- a/net/tipc/bearer.c ++++ b/net/tipc/bearer.c +@@ -334,6 +334,7 @@ static int tipc_enable_bearer(struct net *net, const char *name, + b->net_plane = bearer_id + 'A'; + b->priority = prio; + test_and_set_bit_lock(0, &b->up); ++ refcount_set(&b->refcnt, 1); + + res = tipc_disc_create(net, b, &b->bcast_addr, &skb); + if (res) { +@@ -371,6 +372,17 @@ static int tipc_reset_bearer(struct net *net, struct tipc_bearer *b) + return 0; + } + ++bool tipc_bearer_hold(struct tipc_bearer *b) ++{ ++ return (b && refcount_inc_not_zero(&b->refcnt)); ++} ++ ++void tipc_bearer_put(struct tipc_bearer *b) ++{ ++ if (b && refcount_dec_and_test(&b->refcnt)) ++ kfree_rcu(b, rcu); ++} ++ + /** + * bearer_disable + * +@@ -389,7 +401,7 @@ static void bearer_disable(struct net *net, struct tipc_bearer *b) + if (b->disc) + tipc_disc_delete(b->disc); + RCU_INIT_POINTER(tn->bearer_list[bearer_id], NULL); +- kfree_rcu(b, rcu); ++ tipc_bearer_put(b); + tipc_mon_delete(net, bearer_id); + } + +diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h +index ea0f3c49cbedb..faca696d422ff 100644 +--- a/net/tipc/bearer.h ++++ b/net/tipc/bearer.h +@@ -165,6 +165,7 @@ struct tipc_bearer { + struct tipc_discoverer *disc; + char net_plane; + unsigned long up; ++ refcount_t refcnt; + }; + + struct tipc_bearer_names { +@@ -210,6 +211,8 @@ int tipc_media_set_window(const char *name, u32 new_value); + int tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a); + int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b, + struct nlattr *attrs[]); ++bool tipc_bearer_hold(struct tipc_bearer *b); ++void tipc_bearer_put(struct tipc_bearer *b); + void tipc_disable_l2_media(struct tipc_bearer *b); + int tipc_l2_send_msg(struct net *net, struct sk_buff *buf, + struct tipc_bearer *b, struct tipc_media_addr *dest); +-- +2.43.0 + diff --git a/queue-5.4/tipc-enable-creating-a-preliminary-node.patch b/queue-5.4/tipc-enable-creating-a-preliminary-node.patch new file mode 100644 index 00000000000..265d8c6eb1e --- /dev/null +++ b/queue-5.4/tipc-enable-creating-a-preliminary-node.patch @@ -0,0 +1,274 @@ +From a8a6606f4b66250898f08e92063b0f7c90cab33e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 8 Nov 2019 12:05:09 +0700 +Subject: tipc: enable creating a "preliminary" node +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Tuong Lien + +[ Upstream commit 4cbf8ac2fe5a0846508fe02b95a5de1a90fa73f4 ] + +When user sets RX key for a peer not existing on the own node, a new +node entry is needed to which the RX key will be attached. However, +since the peer node address (& capabilities) is unknown at that moment, +only the node-ID is provided, this commit allows the creation of a node +with only the data that we call as “preliminary”. + +A preliminary node is not the object of the “tipc_node_find()” but the +“tipc_node_find_by_id()”. Once the first message i.e. LINK_CONFIG comes +from that peer, and is successfully decrypted by the own node, the +actual peer node data will be properly updated and the node will +function as usual. + +In addition, the node timer always starts when a node object is created +so if a preliminary node is not used, it will be cleaned up. + +The later encryption functions will also use the node timer and be able +to create a preliminary node automatically when needed. + +Acked-by: Ying Xue +Acked-by: Jon Maloy +Signed-off-by: Tuong Lien +Signed-off-by: David S. Miller +Stable-dep-of: 6a2fa13312e5 ("tipc: Fix use-after-free of kernel socket in cleanup_bearer().") +Signed-off-by: Sasha Levin +--- + net/tipc/node.c | 99 +++++++++++++++++++++++++++++++++++-------------- + net/tipc/node.h | 1 + + 2 files changed, 73 insertions(+), 27 deletions(-) + +diff --git a/net/tipc/node.c b/net/tipc/node.c +index 535a4a778640a..16de7a1b3b01f 100644 +--- a/net/tipc/node.c ++++ b/net/tipc/node.c +@@ -89,6 +89,7 @@ struct tipc_bclink_entry { + * @links: array containing references to all links to node + * @action_flags: bit mask of different types of node actions + * @state: connectivity state vs peer node ++ * @preliminary: a preliminary node or not + * @sync_point: sequence number where synch/failover is finished + * @list: links to adjacent nodes in sorted list of cluster's nodes + * @working_links: number of working links to node (both active and standby) +@@ -112,6 +113,7 @@ struct tipc_node { + int action_flags; + struct list_head list; + int state; ++ bool preliminary; + bool failover_sent; + u16 sync_point; + int link_cnt; +@@ -120,6 +122,7 @@ struct tipc_node { + u32 signature; + u32 link_id; + u8 peer_id[16]; ++ char peer_id_string[NODE_ID_STR_LEN]; + struct list_head publ_list; + struct list_head conn_sks; + unsigned long keepalive_intv; +@@ -245,6 +248,16 @@ u16 tipc_node_get_capabilities(struct net *net, u32 addr) + return caps; + } + ++u32 tipc_node_get_addr(struct tipc_node *node) ++{ ++ return (node) ? node->addr : 0; ++} ++ ++char *tipc_node_get_id_str(struct tipc_node *node) ++{ ++ return node->peer_id_string; ++} ++ + static void tipc_node_kref_release(struct kref *kref) + { + struct tipc_node *n = container_of(kref, struct tipc_node, kref); +@@ -274,7 +287,7 @@ static struct tipc_node *tipc_node_find(struct net *net, u32 addr) + + rcu_read_lock(); + hlist_for_each_entry_rcu(node, &tn->node_htable[thash], hash) { +- if (node->addr != addr) ++ if (node->addr != addr || node->preliminary) + continue; + if (!kref_get_unless_zero(&node->kref)) + node = NULL; +@@ -400,17 +413,39 @@ static void tipc_node_assign_peer_net(struct tipc_node *n, u32 hash_mixes) + + static struct tipc_node *tipc_node_create(struct net *net, u32 addr, + u8 *peer_id, u16 capabilities, +- u32 signature, u32 hash_mixes) ++ u32 hash_mixes, bool preliminary) + { + struct tipc_net *tn = net_generic(net, tipc_net_id); + struct tipc_node *n, *temp_node; + struct tipc_link *l; ++ unsigned long intv; + int bearer_id; + int i; + + spin_lock_bh(&tn->node_list_lock); +- n = tipc_node_find(net, addr); ++ n = tipc_node_find(net, addr) ?: ++ tipc_node_find_by_id(net, peer_id); + if (n) { ++ if (!n->preliminary) ++ goto update; ++ if (preliminary) ++ goto exit; ++ /* A preliminary node becomes "real" now, refresh its data */ ++ tipc_node_write_lock(n); ++ n->preliminary = false; ++ n->addr = addr; ++ hlist_del_rcu(&n->hash); ++ hlist_add_head_rcu(&n->hash, ++ &tn->node_htable[tipc_hashfn(addr)]); ++ list_del_rcu(&n->list); ++ list_for_each_entry_rcu(temp_node, &tn->node_list, list) { ++ if (n->addr < temp_node->addr) ++ break; ++ } ++ list_add_tail_rcu(&n->list, &temp_node->list); ++ tipc_node_write_unlock_fast(n); ++ ++update: + if (n->peer_hash_mix ^ hash_mixes) + tipc_node_assign_peer_net(n, hash_mixes); + if (n->capabilities == capabilities) +@@ -438,7 +473,9 @@ static struct tipc_node *tipc_node_create(struct net *net, u32 addr, + pr_warn("Node creation failed, no memory\n"); + goto exit; + } ++ tipc_nodeid2string(n->peer_id_string, peer_id); + n->addr = addr; ++ n->preliminary = preliminary; + memcpy(&n->peer_id, peer_id, 16); + n->net = net; + n->peer_net = NULL; +@@ -463,22 +500,14 @@ static struct tipc_node *tipc_node_create(struct net *net, u32 addr, + n->signature = INVALID_NODE_SIG; + n->active_links[0] = INVALID_BEARER_ID; + n->active_links[1] = INVALID_BEARER_ID; +- if (!tipc_link_bc_create(net, tipc_own_addr(net), +- addr, U16_MAX, +- tipc_link_window(tipc_bc_sndlink(net)), +- n->capabilities, +- &n->bc_entry.inputq1, +- &n->bc_entry.namedq, +- tipc_bc_sndlink(net), +- &n->bc_entry.link)) { +- pr_warn("Broadcast rcv link creation failed, no memory\n"); +- kfree(n); +- n = NULL; +- goto exit; +- } ++ n->bc_entry.link = NULL; + tipc_node_get(n); + timer_setup(&n->timer, tipc_node_timeout, 0); +- n->keepalive_intv = U32_MAX; ++ /* Start a slow timer anyway, crypto needs it */ ++ n->keepalive_intv = 10000; ++ intv = jiffies + msecs_to_jiffies(n->keepalive_intv); ++ if (!mod_timer(&n->timer, intv)) ++ tipc_node_get(n); + hlist_add_head_rcu(&n->hash, &tn->node_htable[tipc_hashfn(addr)]); + list_for_each_entry_rcu(temp_node, &tn->node_list, list) { + if (n->addr < temp_node->addr) +@@ -996,6 +1025,8 @@ u32 tipc_node_try_addr(struct net *net, u8 *id, u32 addr) + { + struct tipc_net *tn = tipc_net(net); + struct tipc_node *n; ++ bool preliminary; ++ u32 sugg_addr; + + /* Suggest new address if some other peer is using this one */ + n = tipc_node_find(net, addr); +@@ -1011,9 +1042,11 @@ u32 tipc_node_try_addr(struct net *net, u8 *id, u32 addr) + /* Suggest previously used address if peer is known */ + n = tipc_node_find_by_id(net, id); + if (n) { +- addr = n->addr; ++ sugg_addr = n->addr; ++ preliminary = n->preliminary; + tipc_node_put(n); +- return addr; ++ if (!preliminary) ++ return sugg_addr; + } + + /* Even this node may be in conflict */ +@@ -1030,7 +1063,7 @@ void tipc_node_check_dest(struct net *net, u32 addr, + bool *respond, bool *dupl_addr) + { + struct tipc_node *n; +- struct tipc_link *l; ++ struct tipc_link *l, *snd_l; + struct tipc_link_entry *le; + bool addr_match = false; + bool sign_match = false; +@@ -1045,12 +1078,27 @@ void tipc_node_check_dest(struct net *net, u32 addr, + *dupl_addr = false; + *respond = false; + +- n = tipc_node_create(net, addr, peer_id, capabilities, signature, +- hash_mixes); ++ n = tipc_node_create(net, addr, peer_id, capabilities, hash_mixes, ++ false); + if (!n) + return; + + tipc_node_write_lock(n); ++ if (unlikely(!n->bc_entry.link)) { ++ snd_l = tipc_bc_sndlink(net); ++ if (!tipc_link_bc_create(net, tipc_own_addr(net), ++ addr, U16_MAX, ++ tipc_link_window(snd_l), ++ n->capabilities, ++ &n->bc_entry.inputq1, ++ &n->bc_entry.namedq, snd_l, ++ &n->bc_entry.link)) { ++ pr_warn("Broadcast rcv link creation failed, no mem\n"); ++ tipc_node_write_unlock_fast(n); ++ tipc_node_put(n); ++ return; ++ } ++ } + + le = &n->links[b->identity]; + +@@ -2135,6 +2183,8 @@ int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb) + } + + list_for_each_entry_rcu(node, &tn->node_list, list) { ++ if (node->preliminary) ++ continue; + if (last_addr) { + if (node->addr == last_addr) + last_addr = 0; +@@ -2654,11 +2704,6 @@ int tipc_nl_node_dump_monitor_peer(struct sk_buff *skb, + return skb->len; + } + +-u32 tipc_node_get_addr(struct tipc_node *node) +-{ +- return (node) ? node->addr : 0; +-} +- + /** + * tipc_node_dump - dump TIPC node data + * @n: tipc node to be dumped +diff --git a/net/tipc/node.h b/net/tipc/node.h +index 30563c4f35d5c..1d4345ef49b44 100644 +--- a/net/tipc/node.h ++++ b/net/tipc/node.h +@@ -72,6 +72,7 @@ enum { + void tipc_node_stop(struct net *net); + bool tipc_node_get_id(struct net *net, u32 addr, u8 *id); + u32 tipc_node_get_addr(struct tipc_node *node); ++char *tipc_node_get_id_str(struct tipc_node *node); + u32 tipc_node_try_addr(struct net *net, u8 *id, u32 addr); + void tipc_node_check_dest(struct net *net, u32 onode, u8 *peer_id128, + struct tipc_bearer *bearer, +-- +2.43.0 + diff --git a/queue-5.4/tipc-fix-use-after-free-of-kernel-socket-in-cleanup_.patch b/queue-5.4/tipc-fix-use-after-free-of-kernel-socket-in-cleanup_.patch new file mode 100644 index 00000000000..80217f6ee1a --- /dev/null +++ b/queue-5.4/tipc-fix-use-after-free-of-kernel-socket-in-cleanup_.patch @@ -0,0 +1,107 @@ +From 23a6a81bcd8d55695a82a8ae273064c4071d6981 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Nov 2024 14:05:12 +0900 +Subject: tipc: Fix use-after-free of kernel socket in cleanup_bearer(). + +From: Kuniyuki Iwashima + +[ Upstream commit 6a2fa13312e51a621f652d522d7e2df7066330b6 ] + +syzkaller reported a use-after-free of UDP kernel socket +in cleanup_bearer() without repro. [0][1] + +When bearer_disable() calls tipc_udp_disable(), cleanup +of the UDP kernel socket is deferred by work calling +cleanup_bearer(). + +tipc_net_stop() waits for such works to finish by checking +tipc_net(net)->wq_count. However, the work decrements the +count too early before releasing the kernel socket, +unblocking cleanup_net() and resulting in use-after-free. + +Let's move the decrement after releasing the socket in +cleanup_bearer(). + +[0]: +ref_tracker: net notrefcnt@000000009b3d1faf has 1/1 users at + sk_alloc+0x438/0x608 + inet_create+0x4c8/0xcb0 + __sock_create+0x350/0x6b8 + sock_create_kern+0x58/0x78 + udp_sock_create4+0x68/0x398 + udp_sock_create+0x88/0xc8 + tipc_udp_enable+0x5e8/0x848 + __tipc_nl_bearer_enable+0x84c/0xed8 + tipc_nl_bearer_enable+0x38/0x60 + genl_family_rcv_msg_doit+0x170/0x248 + genl_rcv_msg+0x400/0x5b0 + netlink_rcv_skb+0x1dc/0x398 + genl_rcv+0x44/0x68 + netlink_unicast+0x678/0x8b0 + netlink_sendmsg+0x5e4/0x898 + ____sys_sendmsg+0x500/0x830 + +[1]: +BUG: KMSAN: use-after-free in udp_hashslot include/net/udp.h:85 [inline] +BUG: KMSAN: use-after-free in udp_lib_unhash+0x3b8/0x930 net/ipv4/udp.c:1979 + udp_hashslot include/net/udp.h:85 [inline] + udp_lib_unhash+0x3b8/0x930 net/ipv4/udp.c:1979 + sk_common_release+0xaf/0x3f0 net/core/sock.c:3820 + inet_release+0x1e0/0x260 net/ipv4/af_inet.c:437 + inet6_release+0x6f/0xd0 net/ipv6/af_inet6.c:489 + __sock_release net/socket.c:658 [inline] + sock_release+0xa0/0x210 net/socket.c:686 + cleanup_bearer+0x42d/0x4c0 net/tipc/udp_media.c:819 + process_one_work kernel/workqueue.c:3229 [inline] + process_scheduled_works+0xcaf/0x1c90 kernel/workqueue.c:3310 + worker_thread+0xf6c/0x1510 kernel/workqueue.c:3391 + kthread+0x531/0x6b0 kernel/kthread.c:389 + ret_from_fork+0x60/0x80 arch/x86/kernel/process.c:147 + ret_from_fork_asm+0x11/0x20 arch/x86/entry/entry_64.S:244 + +Uninit was created at: + slab_free_hook mm/slub.c:2269 [inline] + slab_free mm/slub.c:4580 [inline] + kmem_cache_free+0x207/0xc40 mm/slub.c:4682 + net_free net/core/net_namespace.c:454 [inline] + cleanup_net+0x16f2/0x19d0 net/core/net_namespace.c:647 + process_one_work kernel/workqueue.c:3229 [inline] + process_scheduled_works+0xcaf/0x1c90 kernel/workqueue.c:3310 + worker_thread+0xf6c/0x1510 kernel/workqueue.c:3391 + kthread+0x531/0x6b0 kernel/kthread.c:389 + ret_from_fork+0x60/0x80 arch/x86/kernel/process.c:147 + ret_from_fork_asm+0x11/0x20 arch/x86/entry/entry_64.S:244 + +CPU: 0 UID: 0 PID: 54 Comm: kworker/0:2 Not tainted 6.12.0-rc1-00131-gf66ebf37d69c #7 91723d6f74857f70725e1583cba3cf4adc716cfa +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014 +Workqueue: events cleanup_bearer + +Fixes: 26abe14379f8 ("net: Modify sk_alloc to not reference count the netns of kernel sockets.") +Reported-by: syzkaller +Signed-off-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20241127050512.28438-1-kuniyu@amazon.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/tipc/udp_media.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c +index 4db2185a32aec..696a21208b24b 100644 +--- a/net/tipc/udp_media.c ++++ b/net/tipc/udp_media.c +@@ -805,10 +805,10 @@ static void cleanup_bearer(struct work_struct *work) + kfree_rcu(rcast, rcu); + } + +- atomic_dec(&tipc_net(sock_net(ub->ubsock->sk))->wq_count); + dst_cache_destroy(&ub->rcast.dst_cache); + udp_tunnel_sock_release(ub->ubsock); + synchronize_net(); ++ atomic_dec(&tipc_net(sock_net(ub->ubsock->sk))->wq_count); + kfree(ub); + } + +-- +2.43.0 + diff --git a/queue-5.4/watchdog-mediatek-make-sure-system-reset-gets-assert.patch b/queue-5.4/watchdog-mediatek-make-sure-system-reset-gets-assert.patch new file mode 100644 index 00000000000..f48c040b39f --- /dev/null +++ b/queue-5.4/watchdog-mediatek-make-sure-system-reset-gets-assert.patch @@ -0,0 +1,48 @@ +From 79b7eeda6d32a1f139db5134640549cd8f51f20d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Nov 2024 10:47:51 +0000 +Subject: watchdog: mediatek: Make sure system reset gets asserted in + mtk_wdt_restart() + +From: Yassine Oudjana + +[ Upstream commit a1495a21e0b8aad92132dfcf9c6fffc1bde9d5b2 ] + +Clear the IRQ enable bit of WDT_MODE before asserting software reset +in order to make TOPRGU issue a system reset signal instead of an IRQ. + +Fixes: a44a45536f7b ("watchdog: Add driver for Mediatek watchdog") +Signed-off-by: Yassine Oudjana +Reviewed-by: AngeloGioacchino Del Regno +Reviewed-by: Guenter Roeck +Link: https://lore.kernel.org/r/20241106104738.195968-2-y.oudjana@protonmail.com +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Sasha Levin +--- + drivers/watchdog/mtk_wdt.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c +index 9c3d0033260d9..a2845c9ad3a7c 100644 +--- a/drivers/watchdog/mtk_wdt.c ++++ b/drivers/watchdog/mtk_wdt.c +@@ -60,9 +60,15 @@ static int mtk_wdt_restart(struct watchdog_device *wdt_dev, + { + struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev); + void __iomem *wdt_base; ++ u32 reg; + + wdt_base = mtk_wdt->wdt_base; + ++ /* Enable reset in order to issue a system reset instead of an IRQ */ ++ reg = readl(wdt_base + WDT_MODE); ++ reg &= ~WDT_MODE_IRQ_EN; ++ writel(reg | WDT_MODE_KEY, wdt_base + WDT_MODE); ++ + while (1) { + writel(WDT_SWRST_KEY, wdt_base + WDT_SWRST); + mdelay(5); +-- +2.43.0 + diff --git a/queue-5.4/x86-asm-crypto-annotate-local-functions.patch b/queue-5.4/x86-asm-crypto-annotate-local-functions.patch new file mode 100644 index 00000000000..5079d6fbc04 --- /dev/null +++ b/queue-5.4/x86-asm-crypto-annotate-local-functions.patch @@ -0,0 +1,640 @@ +From 3f15cd401498be0e0a99c0af6f4c9e5622dcc3bf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 11 Oct 2019 13:50:46 +0200 +Subject: x86/asm/crypto: Annotate local functions + +From: Jiri Slaby + +[ Upstream commit 74d8b90a889022e306b543ff2147a6941c99b354 ] + +Use the newly added SYM_FUNC_START_LOCAL to annotate beginnings of all +functions which do not have ".globl" annotation, but their endings are +annotated by ENDPROC. This is needed to balance ENDPROC for tools that +generate debuginfo. + +These function names are not prepended with ".L" as they might appear in +call traces and they wouldn't be visible after such change. + +To be symmetric, the functions' ENDPROCs are converted to the new +SYM_FUNC_END. + +Signed-off-by: Jiri Slaby +Signed-off-by: Borislav Petkov +Cc: "David S. Miller" +Cc: Herbert Xu +Cc: "H. Peter Anvin" +Cc: Ingo Molnar +Cc: linux-arch@vger.kernel.org +Cc: linux-crypto@vger.kernel.org +Cc: Thomas Gleixner +Cc: x86-ml +Link: https://lkml.kernel.org/r/20191011115108.12392-7-jslaby@suse.cz +Stable-dep-of: 3b2f2d22fb42 ("crypto: x86/aegis128 - access 32-bit arguments as 32-bit") +Signed-off-by: Sasha Levin +--- + arch/x86/crypto/aegis128-aesni-asm.S | 8 ++-- + arch/x86/crypto/aesni-intel_asm.S | 49 ++++++++------------ + arch/x86/crypto/camellia-aesni-avx-asm_64.S | 20 ++++---- + arch/x86/crypto/camellia-aesni-avx2-asm_64.S | 20 ++++---- + arch/x86/crypto/cast5-avx-x86_64-asm_64.S | 8 ++-- + arch/x86/crypto/cast6-avx-x86_64-asm_64.S | 8 ++-- + arch/x86/crypto/chacha-ssse3-x86_64.S | 4 +- + arch/x86/crypto/ghash-clmulni-intel_asm.S | 4 +- + arch/x86/crypto/serpent-avx-x86_64-asm_64.S | 8 ++-- + arch/x86/crypto/serpent-avx2-asm_64.S | 8 ++-- + arch/x86/crypto/twofish-avx-x86_64-asm_64.S | 8 ++-- + 11 files changed, 68 insertions(+), 77 deletions(-) + +diff --git a/arch/x86/crypto/aegis128-aesni-asm.S b/arch/x86/crypto/aegis128-aesni-asm.S +index 4434607e366dc..b7026fdef4ff2 100644 +--- a/arch/x86/crypto/aegis128-aesni-asm.S ++++ b/arch/x86/crypto/aegis128-aesni-asm.S +@@ -71,7 +71,7 @@ + * %r8 + * %r9 + */ +-__load_partial: ++SYM_FUNC_START_LOCAL(__load_partial) + xor %r9d, %r9d + pxor MSG, MSG + +@@ -123,7 +123,7 @@ __load_partial: + + .Lld_partial_8: + ret +-ENDPROC(__load_partial) ++SYM_FUNC_END(__load_partial) + + /* + * __store_partial: internal ABI +@@ -137,7 +137,7 @@ ENDPROC(__load_partial) + * %r9 + * %r10 + */ +-__store_partial: ++SYM_FUNC_START_LOCAL(__store_partial) + mov LEN, %r8 + mov DST, %r9 + +@@ -181,7 +181,7 @@ __store_partial: + + .Lst_partial_1: + ret +-ENDPROC(__store_partial) ++SYM_FUNC_END(__store_partial) + + /* + * void crypto_aegis128_aesni_init(void *state, const void *key, const void *iv); +diff --git a/arch/x86/crypto/aesni-intel_asm.S b/arch/x86/crypto/aesni-intel_asm.S +index dd954d8db629b..ef62383c6bd8f 100644 +--- a/arch/x86/crypto/aesni-intel_asm.S ++++ b/arch/x86/crypto/aesni-intel_asm.S +@@ -1759,7 +1759,7 @@ ENDPROC(aesni_gcm_finalize) + + .align 4 + _key_expansion_128: +-_key_expansion_256a: ++SYM_FUNC_START_LOCAL(_key_expansion_256a) + pshufd $0b11111111, %xmm1, %xmm1 + shufps $0b00010000, %xmm0, %xmm4 + pxor %xmm4, %xmm0 +@@ -1770,10 +1770,9 @@ _key_expansion_256a: + add $0x10, TKEYP + ret + ENDPROC(_key_expansion_128) +-ENDPROC(_key_expansion_256a) ++SYM_FUNC_END(_key_expansion_256a) + +-.align 4 +-_key_expansion_192a: ++SYM_FUNC_START_LOCAL(_key_expansion_192a) + pshufd $0b01010101, %xmm1, %xmm1 + shufps $0b00010000, %xmm0, %xmm4 + pxor %xmm4, %xmm0 +@@ -1795,10 +1794,9 @@ _key_expansion_192a: + movaps %xmm1, 0x10(TKEYP) + add $0x20, TKEYP + ret +-ENDPROC(_key_expansion_192a) ++SYM_FUNC_END(_key_expansion_192a) + +-.align 4 +-_key_expansion_192b: ++SYM_FUNC_START_LOCAL(_key_expansion_192b) + pshufd $0b01010101, %xmm1, %xmm1 + shufps $0b00010000, %xmm0, %xmm4 + pxor %xmm4, %xmm0 +@@ -1815,10 +1813,9 @@ _key_expansion_192b: + movaps %xmm0, (TKEYP) + add $0x10, TKEYP + ret +-ENDPROC(_key_expansion_192b) ++SYM_FUNC_END(_key_expansion_192b) + +-.align 4 +-_key_expansion_256b: ++SYM_FUNC_START_LOCAL(_key_expansion_256b) + pshufd $0b10101010, %xmm1, %xmm1 + shufps $0b00010000, %xmm2, %xmm4 + pxor %xmm4, %xmm2 +@@ -1828,7 +1825,7 @@ _key_expansion_256b: + movaps %xmm2, (TKEYP) + add $0x10, TKEYP + ret +-ENDPROC(_key_expansion_256b) ++SYM_FUNC_END(_key_expansion_256b) + + /* + * int aesni_set_key(struct crypto_aes_ctx *ctx, const u8 *in_key, +@@ -1981,8 +1978,7 @@ ENDPROC(aesni_enc) + * KEY + * TKEYP (T1) + */ +-.align 4 +-_aesni_enc1: ++SYM_FUNC_START_LOCAL(_aesni_enc1) + movaps (KEYP), KEY # key + mov KEYP, TKEYP + pxor KEY, STATE # round 0 +@@ -2025,7 +2021,7 @@ _aesni_enc1: + movaps 0x70(TKEYP), KEY + AESENCLAST KEY STATE + ret +-ENDPROC(_aesni_enc1) ++SYM_FUNC_END(_aesni_enc1) + + /* + * _aesni_enc4: internal ABI +@@ -2045,8 +2041,7 @@ ENDPROC(_aesni_enc1) + * KEY + * TKEYP (T1) + */ +-.align 4 +-_aesni_enc4: ++SYM_FUNC_START_LOCAL(_aesni_enc4) + movaps (KEYP), KEY # key + mov KEYP, TKEYP + pxor KEY, STATE1 # round 0 +@@ -2134,7 +2129,7 @@ _aesni_enc4: + AESENCLAST KEY STATE3 + AESENCLAST KEY STATE4 + ret +-ENDPROC(_aesni_enc4) ++SYM_FUNC_END(_aesni_enc4) + + /* + * void aesni_dec (const void *ctx, u8 *dst, const u8 *src) +@@ -2173,8 +2168,7 @@ ENDPROC(aesni_dec) + * KEY + * TKEYP (T1) + */ +-.align 4 +-_aesni_dec1: ++SYM_FUNC_START_LOCAL(_aesni_dec1) + movaps (KEYP), KEY # key + mov KEYP, TKEYP + pxor KEY, STATE # round 0 +@@ -2217,7 +2211,7 @@ _aesni_dec1: + movaps 0x70(TKEYP), KEY + AESDECLAST KEY STATE + ret +-ENDPROC(_aesni_dec1) ++SYM_FUNC_END(_aesni_dec1) + + /* + * _aesni_dec4: internal ABI +@@ -2237,8 +2231,7 @@ ENDPROC(_aesni_dec1) + * KEY + * TKEYP (T1) + */ +-.align 4 +-_aesni_dec4: ++SYM_FUNC_START_LOCAL(_aesni_dec4) + movaps (KEYP), KEY # key + mov KEYP, TKEYP + pxor KEY, STATE1 # round 0 +@@ -2326,7 +2319,7 @@ _aesni_dec4: + AESDECLAST KEY STATE3 + AESDECLAST KEY STATE4 + ret +-ENDPROC(_aesni_dec4) ++SYM_FUNC_END(_aesni_dec4) + + /* + * void aesni_ecb_enc(struct crypto_aes_ctx *ctx, const u8 *dst, u8 *src, +@@ -2604,8 +2597,7 @@ ENDPROC(aesni_cbc_dec) + * INC: == 1, in little endian + * BSWAP_MASK == endian swapping mask + */ +-.align 4 +-_aesni_inc_init: ++SYM_FUNC_START_LOCAL(_aesni_inc_init) + movaps .Lbswap_mask, BSWAP_MASK + movaps IV, CTR + PSHUFB_XMM BSWAP_MASK CTR +@@ -2613,7 +2605,7 @@ _aesni_inc_init: + MOVQ_R64_XMM TCTR_LOW INC + MOVQ_R64_XMM CTR TCTR_LOW + ret +-ENDPROC(_aesni_inc_init) ++SYM_FUNC_END(_aesni_inc_init) + + /* + * _aesni_inc: internal ABI +@@ -2630,8 +2622,7 @@ ENDPROC(_aesni_inc_init) + * CTR: == output IV, in little endian + * TCTR_LOW: == lower qword of CTR + */ +-.align 4 +-_aesni_inc: ++SYM_FUNC_START_LOCAL(_aesni_inc) + paddq INC, CTR + add $1, TCTR_LOW + jnc .Linc_low +@@ -2642,7 +2633,7 @@ _aesni_inc: + movaps CTR, IV + PSHUFB_XMM BSWAP_MASK IV + ret +-ENDPROC(_aesni_inc) ++SYM_FUNC_END(_aesni_inc) + + /* + * void aesni_ctr_enc(struct crypto_aes_ctx *ctx, const u8 *dst, u8 *src, +diff --git a/arch/x86/crypto/camellia-aesni-avx-asm_64.S b/arch/x86/crypto/camellia-aesni-avx-asm_64.S +index a14af6eb09cb0..f4408ca55fdb3 100644 +--- a/arch/x86/crypto/camellia-aesni-avx-asm_64.S ++++ b/arch/x86/crypto/camellia-aesni-avx-asm_64.S +@@ -189,20 +189,20 @@ + * larger and would only be 0.5% faster (on sandy-bridge). + */ + .align 8 +-roundsm16_x0_x1_x2_x3_x4_x5_x6_x7_y0_y1_y2_y3_y4_y5_y6_y7_cd: ++SYM_FUNC_START_LOCAL(roundsm16_x0_x1_x2_x3_x4_x5_x6_x7_y0_y1_y2_y3_y4_y5_y6_y7_cd) + roundsm16(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, + %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, + %rcx, (%r9)); + ret; +-ENDPROC(roundsm16_x0_x1_x2_x3_x4_x5_x6_x7_y0_y1_y2_y3_y4_y5_y6_y7_cd) ++SYM_FUNC_END(roundsm16_x0_x1_x2_x3_x4_x5_x6_x7_y0_y1_y2_y3_y4_y5_y6_y7_cd) + + .align 8 +-roundsm16_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab: ++SYM_FUNC_START_LOCAL(roundsm16_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab) + roundsm16(%xmm4, %xmm5, %xmm6, %xmm7, %xmm0, %xmm1, %xmm2, %xmm3, + %xmm12, %xmm13, %xmm14, %xmm15, %xmm8, %xmm9, %xmm10, %xmm11, + %rax, (%r9)); + ret; +-ENDPROC(roundsm16_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab) ++SYM_FUNC_END(roundsm16_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab) + + /* + * IN/OUT: +@@ -722,7 +722,7 @@ ENDPROC(roundsm16_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab) + .text + + .align 8 +-__camellia_enc_blk16: ++SYM_FUNC_START_LOCAL(__camellia_enc_blk16) + /* input: + * %rdi: ctx, CTX + * %rax: temporary storage, 256 bytes +@@ -806,10 +806,10 @@ __camellia_enc_blk16: + %xmm15, %rax, %rcx, 24); + + jmp .Lenc_done; +-ENDPROC(__camellia_enc_blk16) ++SYM_FUNC_END(__camellia_enc_blk16) + + .align 8 +-__camellia_dec_blk16: ++SYM_FUNC_START_LOCAL(__camellia_dec_blk16) + /* input: + * %rdi: ctx, CTX + * %rax: temporary storage, 256 bytes +@@ -891,7 +891,7 @@ __camellia_dec_blk16: + ((key_table + (24) * 8) + 4)(CTX)); + + jmp .Ldec_max24; +-ENDPROC(__camellia_dec_blk16) ++SYM_FUNC_END(__camellia_dec_blk16) + + ENTRY(camellia_ecb_enc_16way) + /* input: +@@ -1120,7 +1120,7 @@ ENDPROC(camellia_ctr_16way) + vpxor tmp, iv, iv; + + .align 8 +-camellia_xts_crypt_16way: ++SYM_FUNC_START_LOCAL(camellia_xts_crypt_16way) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (16 blocks) +@@ -1254,7 +1254,7 @@ camellia_xts_crypt_16way: + + FRAME_END + ret; +-ENDPROC(camellia_xts_crypt_16way) ++SYM_FUNC_END(camellia_xts_crypt_16way) + + ENTRY(camellia_xts_enc_16way) + /* input: +diff --git a/arch/x86/crypto/camellia-aesni-avx2-asm_64.S b/arch/x86/crypto/camellia-aesni-avx2-asm_64.S +index 4be4c7c3ba273..72ae3edd09979 100644 +--- a/arch/x86/crypto/camellia-aesni-avx2-asm_64.S ++++ b/arch/x86/crypto/camellia-aesni-avx2-asm_64.S +@@ -223,20 +223,20 @@ + * larger and would only marginally faster. + */ + .align 8 +-roundsm32_x0_x1_x2_x3_x4_x5_x6_x7_y0_y1_y2_y3_y4_y5_y6_y7_cd: ++SYM_FUNC_START_LOCAL(roundsm32_x0_x1_x2_x3_x4_x5_x6_x7_y0_y1_y2_y3_y4_y5_y6_y7_cd) + roundsm32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7, + %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, %ymm15, + %rcx, (%r9)); + ret; +-ENDPROC(roundsm32_x0_x1_x2_x3_x4_x5_x6_x7_y0_y1_y2_y3_y4_y5_y6_y7_cd) ++SYM_FUNC_END(roundsm32_x0_x1_x2_x3_x4_x5_x6_x7_y0_y1_y2_y3_y4_y5_y6_y7_cd) + + .align 8 +-roundsm32_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab: ++SYM_FUNC_START_LOCAL(roundsm32_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab) + roundsm32(%ymm4, %ymm5, %ymm6, %ymm7, %ymm0, %ymm1, %ymm2, %ymm3, + %ymm12, %ymm13, %ymm14, %ymm15, %ymm8, %ymm9, %ymm10, %ymm11, + %rax, (%r9)); + ret; +-ENDPROC(roundsm32_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab) ++SYM_FUNC_END(roundsm32_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab) + + /* + * IN/OUT: +@@ -760,7 +760,7 @@ ENDPROC(roundsm32_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab) + .text + + .align 8 +-__camellia_enc_blk32: ++SYM_FUNC_START_LOCAL(__camellia_enc_blk32) + /* input: + * %rdi: ctx, CTX + * %rax: temporary storage, 512 bytes +@@ -844,10 +844,10 @@ __camellia_enc_blk32: + %ymm15, %rax, %rcx, 24); + + jmp .Lenc_done; +-ENDPROC(__camellia_enc_blk32) ++SYM_FUNC_END(__camellia_enc_blk32) + + .align 8 +-__camellia_dec_blk32: ++SYM_FUNC_START_LOCAL(__camellia_dec_blk32) + /* input: + * %rdi: ctx, CTX + * %rax: temporary storage, 512 bytes +@@ -929,7 +929,7 @@ __camellia_dec_blk32: + ((key_table + (24) * 8) + 4)(CTX)); + + jmp .Ldec_max24; +-ENDPROC(__camellia_dec_blk32) ++SYM_FUNC_END(__camellia_dec_blk32) + + ENTRY(camellia_ecb_enc_32way) + /* input: +@@ -1222,7 +1222,7 @@ ENDPROC(camellia_ctr_32way) + vpxor tmp1, iv, iv; + + .align 8 +-camellia_xts_crypt_32way: ++SYM_FUNC_START_LOCAL(camellia_xts_crypt_32way) + /* input: + * %rdi: ctx, CTX + * %rsi: dst (32 blocks) +@@ -1367,7 +1367,7 @@ camellia_xts_crypt_32way: + + FRAME_END + ret; +-ENDPROC(camellia_xts_crypt_32way) ++SYM_FUNC_END(camellia_xts_crypt_32way) + + ENTRY(camellia_xts_enc_32way) + /* input: +diff --git a/arch/x86/crypto/cast5-avx-x86_64-asm_64.S b/arch/x86/crypto/cast5-avx-x86_64-asm_64.S +index dc55c3332fcc4..ef86c6a966de1 100644 +--- a/arch/x86/crypto/cast5-avx-x86_64-asm_64.S ++++ b/arch/x86/crypto/cast5-avx-x86_64-asm_64.S +@@ -209,7 +209,7 @@ + .text + + .align 16 +-__cast5_enc_blk16: ++SYM_FUNC_START_LOCAL(__cast5_enc_blk16) + /* input: + * %rdi: ctx + * RL1: blocks 1 and 2 +@@ -280,10 +280,10 @@ __cast5_enc_blk16: + outunpack_blocks(RR4, RL4, RTMP, RX, RKM); + + ret; +-ENDPROC(__cast5_enc_blk16) ++SYM_FUNC_END(__cast5_enc_blk16) + + .align 16 +-__cast5_dec_blk16: ++SYM_FUNC_START_LOCAL(__cast5_dec_blk16) + /* input: + * %rdi: ctx + * RL1: encrypted blocks 1 and 2 +@@ -357,7 +357,7 @@ __cast5_dec_blk16: + .L__skip_dec: + vpsrldq $4, RKR, RKR; + jmp .L__dec_tail; +-ENDPROC(__cast5_dec_blk16) ++SYM_FUNC_END(__cast5_dec_blk16) + + ENTRY(cast5_ecb_enc_16way) + /* input: +diff --git a/arch/x86/crypto/cast6-avx-x86_64-asm_64.S b/arch/x86/crypto/cast6-avx-x86_64-asm_64.S +index 4f0a7cdb94d9d..b080a7454e70e 100644 +--- a/arch/x86/crypto/cast6-avx-x86_64-asm_64.S ++++ b/arch/x86/crypto/cast6-avx-x86_64-asm_64.S +@@ -247,7 +247,7 @@ + .text + + .align 8 +-__cast6_enc_blk8: ++SYM_FUNC_START_LOCAL(__cast6_enc_blk8) + /* input: + * %rdi: ctx + * RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2: blocks +@@ -292,10 +292,10 @@ __cast6_enc_blk8: + outunpack_blocks(RA2, RB2, RC2, RD2, RTMP, RX, RKRF, RKM); + + ret; +-ENDPROC(__cast6_enc_blk8) ++SYM_FUNC_END(__cast6_enc_blk8) + + .align 8 +-__cast6_dec_blk8: ++SYM_FUNC_START_LOCAL(__cast6_dec_blk8) + /* input: + * %rdi: ctx + * RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2: encrypted blocks +@@ -339,7 +339,7 @@ __cast6_dec_blk8: + outunpack_blocks(RA2, RB2, RC2, RD2, RTMP, RX, RKRF, RKM); + + ret; +-ENDPROC(__cast6_dec_blk8) ++SYM_FUNC_END(__cast6_dec_blk8) + + ENTRY(cast6_ecb_enc_8way) + /* input: +diff --git a/arch/x86/crypto/chacha-ssse3-x86_64.S b/arch/x86/crypto/chacha-ssse3-x86_64.S +index 2d86c7d6dc88c..361d2bfc253cb 100644 +--- a/arch/x86/crypto/chacha-ssse3-x86_64.S ++++ b/arch/x86/crypto/chacha-ssse3-x86_64.S +@@ -33,7 +33,7 @@ CTRINC: .octa 0x00000003000000020000000100000000 + * + * Clobbers: %r8d, %xmm4-%xmm7 + */ +-chacha_permute: ++SYM_FUNC_START_LOCAL(chacha_permute) + + movdqa ROT8(%rip),%xmm4 + movdqa ROT16(%rip),%xmm5 +@@ -109,7 +109,7 @@ chacha_permute: + jnz .Ldoubleround + + ret +-ENDPROC(chacha_permute) ++SYM_FUNC_END(chacha_permute) + + ENTRY(chacha_block_xor_ssse3) + # %rdi: Input state matrix, s +diff --git a/arch/x86/crypto/ghash-clmulni-intel_asm.S b/arch/x86/crypto/ghash-clmulni-intel_asm.S +index 5d53effe8abee..e81da25a33caf 100644 +--- a/arch/x86/crypto/ghash-clmulni-intel_asm.S ++++ b/arch/x86/crypto/ghash-clmulni-intel_asm.S +@@ -44,7 +44,7 @@ + * T2 + * T3 + */ +-__clmul_gf128mul_ble: ++SYM_FUNC_START_LOCAL(__clmul_gf128mul_ble) + movaps DATA, T1 + pshufd $0b01001110, DATA, T2 + pshufd $0b01001110, SHASH, T3 +@@ -87,7 +87,7 @@ __clmul_gf128mul_ble: + pxor T2, T1 + pxor T1, DATA + ret +-ENDPROC(__clmul_gf128mul_ble) ++SYM_FUNC_END(__clmul_gf128mul_ble) + + /* void clmul_ghash_mul(char *dst, const u128 *shash) */ + ENTRY(clmul_ghash_mul) +diff --git a/arch/x86/crypto/serpent-avx-x86_64-asm_64.S b/arch/x86/crypto/serpent-avx-x86_64-asm_64.S +index ddc51dbba3af9..a098aa0157840 100644 +--- a/arch/x86/crypto/serpent-avx-x86_64-asm_64.S ++++ b/arch/x86/crypto/serpent-avx-x86_64-asm_64.S +@@ -555,7 +555,7 @@ + transpose_4x4(x0, x1, x2, x3, t0, t1, t2) + + .align 8 +-__serpent_enc_blk8_avx: ++SYM_FUNC_START_LOCAL(__serpent_enc_blk8_avx) + /* input: + * %rdi: ctx, CTX + * RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2: blocks +@@ -606,10 +606,10 @@ __serpent_enc_blk8_avx: + write_blocks(RA2, RB2, RC2, RD2, RK0, RK1, RK2); + + ret; +-ENDPROC(__serpent_enc_blk8_avx) ++SYM_FUNC_END(__serpent_enc_blk8_avx) + + .align 8 +-__serpent_dec_blk8_avx: ++SYM_FUNC_START_LOCAL(__serpent_dec_blk8_avx) + /* input: + * %rdi: ctx, CTX + * RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2: encrypted blocks +@@ -660,7 +660,7 @@ __serpent_dec_blk8_avx: + write_blocks(RC2, RD2, RB2, RE2, RK0, RK1, RK2); + + ret; +-ENDPROC(__serpent_dec_blk8_avx) ++SYM_FUNC_END(__serpent_dec_blk8_avx) + + ENTRY(serpent_ecb_enc_8way_avx) + /* input: +diff --git a/arch/x86/crypto/serpent-avx2-asm_64.S b/arch/x86/crypto/serpent-avx2-asm_64.S +index 37bc1d48106c4..6149ba80b4d16 100644 +--- a/arch/x86/crypto/serpent-avx2-asm_64.S ++++ b/arch/x86/crypto/serpent-avx2-asm_64.S +@@ -561,7 +561,7 @@ + transpose_4x4(x0, x1, x2, x3, t0, t1, t2) + + .align 8 +-__serpent_enc_blk16: ++SYM_FUNC_START_LOCAL(__serpent_enc_blk16) + /* input: + * %rdi: ctx, CTX + * RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2: plaintext +@@ -612,10 +612,10 @@ __serpent_enc_blk16: + write_blocks(RA2, RB2, RC2, RD2, RK0, RK1, RK2); + + ret; +-ENDPROC(__serpent_enc_blk16) ++SYM_FUNC_END(__serpent_enc_blk16) + + .align 8 +-__serpent_dec_blk16: ++SYM_FUNC_START_LOCAL(__serpent_dec_blk16) + /* input: + * %rdi: ctx, CTX + * RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2: ciphertext +@@ -666,7 +666,7 @@ __serpent_dec_blk16: + write_blocks(RC2, RD2, RB2, RE2, RK0, RK1, RK2); + + ret; +-ENDPROC(__serpent_dec_blk16) ++SYM_FUNC_END(__serpent_dec_blk16) + + ENTRY(serpent_ecb_enc_16way) + /* input: +diff --git a/arch/x86/crypto/twofish-avx-x86_64-asm_64.S b/arch/x86/crypto/twofish-avx-x86_64-asm_64.S +index 698b8f2a56e28..588f0a2f63ab2 100644 +--- a/arch/x86/crypto/twofish-avx-x86_64-asm_64.S ++++ b/arch/x86/crypto/twofish-avx-x86_64-asm_64.S +@@ -234,7 +234,7 @@ + vpxor x3, wkey, x3; + + .align 8 +-__twofish_enc_blk8: ++SYM_FUNC_START_LOCAL(__twofish_enc_blk8) + /* input: + * %rdi: ctx, CTX + * RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2: blocks +@@ -273,10 +273,10 @@ __twofish_enc_blk8: + outunpack_blocks(RC2, RD2, RA2, RB2, RK1, RX0, RY0, RK2); + + ret; +-ENDPROC(__twofish_enc_blk8) ++SYM_FUNC_END(__twofish_enc_blk8) + + .align 8 +-__twofish_dec_blk8: ++SYM_FUNC_START_LOCAL(__twofish_dec_blk8) + /* input: + * %rdi: ctx, CTX + * RC1, RD1, RA1, RB1, RC2, RD2, RA2, RB2: encrypted blocks +@@ -313,7 +313,7 @@ __twofish_dec_blk8: + outunpack_blocks(RA2, RB2, RC2, RD2, RK1, RX0, RY0, RK2); + + ret; +-ENDPROC(__twofish_dec_blk8) ++SYM_FUNC_END(__twofish_dec_blk8) + + ENTRY(twofish_ecb_enc_8way) + /* input: +-- +2.43.0 + diff --git a/queue-5.4/x86-asm-reorder-early-variables.patch b/queue-5.4/x86-asm-reorder-early-variables.patch new file mode 100644 index 00000000000..d48dd6a70a0 --- /dev/null +++ b/queue-5.4/x86-asm-reorder-early-variables.patch @@ -0,0 +1,109 @@ +From 412ac67de3c22418683b90fb02c0926a1789278c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 3 Oct 2019 11:52:37 +0200 +Subject: x86/asm: Reorder early variables + +From: Jiri Slaby + +[ Upstream commit 1a8770b746bd05ef68217989cd723b2c24d2208d ] + +Moving early_recursion_flag (4 bytes) after early_level4_pgt (4k) and +early_dynamic_pgts (256k) saves 4k which are used for alignment of +early_level4_pgt after early_recursion_flag. + +The real improvement is merely on the source code side. Previously it +was: +* __INITDATA + .balign +* early_recursion_flag variable +* a ton of CPP MACROS +* __INITDATA (again) +* early_top_pgt and early_recursion_flag variables +* .data + +Now, it is a bit simpler: +* a ton of CPP MACROS +* __INITDATA + .balign +* early_top_pgt and early_recursion_flag variables +* early_recursion_flag variable +* .data + +On the binary level the change looks like this: +Before: + (sections) + 12 .init.data 00042000 0000000000000000 0000000000000000 00008000 2**12 + (symbols) + 000000 4 OBJECT GLOBAL DEFAULT 22 early_recursion_flag + 001000 4096 OBJECT GLOBAL DEFAULT 22 early_top_pgt + 002000 0x40000 OBJECT GLOBAL DEFAULT 22 early_dynamic_pgts + +After: + (sections) + 12 .init.data 00041004 0000000000000000 0000000000000000 00008000 2**12 + (symbols) + 000000 4096 OBJECT GLOBAL DEFAULT 22 early_top_pgt + 001000 0x40000 OBJECT GLOBAL DEFAULT 22 early_dynamic_pgts + 041000 4 OBJECT GLOBAL DEFAULT 22 early_recursion_flag + +So the resulting vmlinux is smaller by 4k with my toolchain as many +other variables can be placed after early_recursion_flag to fill the +rest of the page. Note that this is only .init data, so it is freed +right after being booted anyway. Savings on-disk are none -- compression +of zeros is easy, so the size of bzImage is the same pre and post the +change. + +Signed-off-by: Jiri Slaby +Signed-off-by: Borislav Petkov +Cc: Andy Lutomirski +Cc: "H. Peter Anvin" +Cc: Ingo Molnar +Cc: Josh Poimboeuf +Cc: Juergen Gross +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Cc: x86-ml +Link: https://lkml.kernel.org/r/20191003095238.29831-1-jslaby@suse.cz +Stable-dep-of: 3b2f2d22fb42 ("crypto: x86/aegis128 - access 32-bit arguments as 32-bit") +Signed-off-by: Sasha Levin +--- + arch/x86/kernel/head_64.S | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S +index f3d3e9646a99b..f00d7c0c1c86b 100644 +--- a/arch/x86/kernel/head_64.S ++++ b/arch/x86/kernel/head_64.S +@@ -335,12 +335,6 @@ early_idt_handler_common: + jmp restore_regs_and_return_to_kernel + END(early_idt_handler_common) + +- __INITDATA +- +- .balign 4 +-GLOBAL(early_recursion_flag) +- .long 0 +- + #define NEXT_PAGE(name) \ + .balign PAGE_SIZE; \ + GLOBAL(name) +@@ -375,6 +369,8 @@ GLOBAL(name) + .endr + + __INITDATA ++ .balign 4 ++ + NEXT_PGD_PAGE(early_top_pgt) + .fill 512,8,0 + .fill PTI_USER_PGD_FILL,8,0 +@@ -382,6 +378,9 @@ NEXT_PGD_PAGE(early_top_pgt) + NEXT_PAGE(early_dynamic_pgts) + .fill 512*EARLY_DYNAMIC_PAGE_TABLES,8,0 + ++GLOBAL(early_recursion_flag) ++ .long 0 ++ + .data + + #if defined(CONFIG_XEN_PV) || defined(CONFIG_PVH) +-- +2.43.0 + diff --git a/queue-5.4/xen-fix-the-issue-of-resource-not-being-properly-rel.patch b/queue-5.4/xen-fix-the-issue-of-resource-not-being-properly-rel.patch new file mode 100644 index 00000000000..97dcab4f720 --- /dev/null +++ b/queue-5.4/xen-fix-the-issue-of-resource-not-being-properly-rel.patch @@ -0,0 +1,68 @@ +From 82db2647beb7e011a6c9b0e99e0ae665142e1ea6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Nov 2024 21:09:19 +0800 +Subject: xen: Fix the issue of resource not being properly released in + xenbus_dev_probe() + +From: Qiu-ji Chen + +[ Upstream commit afc545da381ba0c651b2658966ac737032676f01 ] + +This patch fixes an issue in the function xenbus_dev_probe(). In the +xenbus_dev_probe() function, within the if (err) branch at line 313, the +program incorrectly returns err directly without releasing the resources +allocated by err = drv->probe(dev, id). As the return value is non-zero, +the upper layers assume the processing logic has failed. However, the probe +operation was performed earlier without a corresponding remove operation. +Since the probe actually allocates resources, failing to perform the remove +operation could lead to problems. + +To fix this issue, we followed the resource release logic of the +xenbus_dev_remove() function by adding a new block fail_remove before the +fail_put block. After entering the branch if (err) at line 313, the +function will use a goto statement to jump to the fail_remove block, +ensuring that the previously acquired resources are correctly released, +thus preventing the reference count leak. + +This bug was identified by an experimental static analysis tool developed +by our team. The tool specializes in analyzing reference count operations +and detecting potential issues where resources are not properly managed. +In this case, the tool flagged the missing release operation as a +potential problem, which led to the development of this patch. + +Fixes: 4bac07c993d0 ("xen: add the Xenbus sysfs and virtual device hotplug driver") +Cc: stable@vger.kernel.org +Signed-off-by: Qiu-ji Chen +Reviewed-by: Juergen Gross +Message-ID: <20241105130919.4621-1-chenqiuji666@gmail.com> +Signed-off-by: Juergen Gross +Signed-off-by: Sasha Levin +--- + drivers/xen/xenbus/xenbus_probe.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c +index b88512d92ef52..fd686b962727a 100644 +--- a/drivers/xen/xenbus/xenbus_probe.c ++++ b/drivers/xen/xenbus/xenbus_probe.c +@@ -250,10 +250,16 @@ int xenbus_dev_probe(struct device *_dev) + if (err) { + dev_warn(&dev->dev, "watch_otherend on %s failed.\n", + dev->nodename); +- return err; ++ goto fail_remove; + } + + return 0; ++fail_remove: ++ if (drv->remove) { ++ down(&dev->reclaim_sem); ++ drv->remove(dev); ++ up(&dev->reclaim_sem); ++ } + fail_put: + module_put(drv->driver.owner); + fail: +-- +2.43.0 + diff --git a/queue-5.4/xen-xenbus-fix-locking.patch b/queue-5.4/xen-xenbus-fix-locking.patch new file mode 100644 index 00000000000..0f77cc7b837 --- /dev/null +++ b/queue-5.4/xen-xenbus-fix-locking.patch @@ -0,0 +1,114 @@ +From c510ecc5f36c32b69584a25abf78ffeec09ed101 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Mar 2020 11:03:23 +0100 +Subject: xen/xenbus: fix locking + +From: Juergen Gross + +[ Upstream commit 2f69a110e7bba3ec6bc089a2f736ca0941d887ed ] + +Commit 060eabe8fbe726 ("xenbus/backend: Protect xenbus callback with +lock") introduced a bug by holding a lock while calling a function +which might schedule. + +Fix that by using a semaphore instead. + +Fixes: 060eabe8fbe726 ("xenbus/backend: Protect xenbus callback with lock") +Signed-off-by: Juergen Gross +Link: https://lore.kernel.org/r/20200305100323.16736-1-jgross@suse.com +Reviewed-by: Boris Ostrovsky +Signed-off-by: Boris Ostrovsky +Stable-dep-of: afc545da381b ("xen: Fix the issue of resource not being properly released in xenbus_dev_probe()") +Signed-off-by: Sasha Levin +--- + drivers/xen/xenbus/xenbus_probe.c | 10 +++++----- + drivers/xen/xenbus/xenbus_probe_backend.c | 5 +++-- + include/xen/xenbus.h | 3 ++- + 3 files changed, 10 insertions(+), 8 deletions(-) + +diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c +index 1ad5bc9dd6cc4..b88512d92ef52 100644 +--- a/drivers/xen/xenbus/xenbus_probe.c ++++ b/drivers/xen/xenbus/xenbus_probe.c +@@ -240,9 +240,9 @@ int xenbus_dev_probe(struct device *_dev) + goto fail; + } + +- spin_lock(&dev->reclaim_lock); ++ down(&dev->reclaim_sem); + err = drv->probe(dev, id); +- spin_unlock(&dev->reclaim_lock); ++ up(&dev->reclaim_sem); + if (err) + goto fail_put; + +@@ -273,9 +273,9 @@ int xenbus_dev_remove(struct device *_dev) + free_otherend_watch(dev); + + if (drv->remove) { +- spin_lock(&dev->reclaim_lock); ++ down(&dev->reclaim_sem); + drv->remove(dev); +- spin_unlock(&dev->reclaim_lock); ++ up(&dev->reclaim_sem); + } + + module_put(drv->driver.owner); +@@ -489,7 +489,7 @@ int xenbus_probe_node(struct xen_bus_type *bus, + goto fail; + + dev_set_name(&xendev->dev, "%s", devname); +- spin_lock_init(&xendev->reclaim_lock); ++ sema_init(&xendev->reclaim_sem, 1); + + /* Register with generic device framework. */ + err = device_register(&xendev->dev); +diff --git a/drivers/xen/xenbus/xenbus_probe_backend.c b/drivers/xen/xenbus/xenbus_probe_backend.c +index 54aefbbbbff9e..8c76b94f0512d 100644 +--- a/drivers/xen/xenbus/xenbus_probe_backend.c ++++ b/drivers/xen/xenbus/xenbus_probe_backend.c +@@ -45,6 +45,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -265,10 +266,10 @@ static int backend_reclaim_memory(struct device *dev, void *data) + drv = to_xenbus_driver(dev->driver); + if (drv && drv->reclaim_memory) { + xdev = to_xenbus_device(dev); +- if (!spin_trylock(&xdev->reclaim_lock)) ++ if (down_trylock(&xdev->reclaim_sem)) + return 0; + drv->reclaim_memory(xdev); +- spin_unlock(&xdev->reclaim_lock); ++ up(&xdev->reclaim_sem); + } + return 0; + } +diff --git a/include/xen/xenbus.h b/include/xen/xenbus.h +index 0d166dfe48334..372c7c69cdf6e 100644 +--- a/include/xen/xenbus.h ++++ b/include/xen/xenbus.h +@@ -42,6 +42,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -85,7 +86,7 @@ struct xenbus_device { + enum xenbus_state state; + struct completion down; + struct work_struct work; +- spinlock_t reclaim_lock; ++ struct semaphore reclaim_sem; + }; + + static inline struct xenbus_device *to_xenbus_device(struct device *dev) +-- +2.43.0 + diff --git a/queue-5.4/xen-xenbus-reference-count-registered-modules.patch b/queue-5.4/xen-xenbus-reference-count-registered-modules.patch new file mode 100644 index 00000000000..8420fbb943a --- /dev/null +++ b/queue-5.4/xen-xenbus-reference-count-registered-modules.patch @@ -0,0 +1,69 @@ +From 7bd8b2a692c2f6799ae7a98e0ccbb48eaf433922 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Dec 2019 11:41:16 +0000 +Subject: xen/xenbus: reference count registered modules + +From: Paul Durrant + +[ Upstream commit 196748a276b4dee01177e6b7abcda27cd759de83 ] + +To prevent a PV driver module being removed whilst attached to its other +end, and hence xenbus calling into potentially invalid text, take a +reference on the module before calling the probe() method (dropping it if +unsuccessful) and drop the reference after returning from the remove() +method. + +Suggested-by: Jan Beulich +Signed-off-by: Paul Durrant +Reviewed-by: Jan Beulich +Reviewed-by: Juergen Gross +Signed-off-by: Juergen Gross +Stable-dep-of: afc545da381b ("xen: Fix the issue of resource not being properly released in xenbus_dev_probe()") +Signed-off-by: Sasha Levin +--- + drivers/xen/xenbus/xenbus_probe.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c +index b911a91bce6b7..9215099caad61 100644 +--- a/drivers/xen/xenbus/xenbus_probe.c ++++ b/drivers/xen/xenbus/xenbus_probe.c +@@ -233,9 +233,16 @@ int xenbus_dev_probe(struct device *_dev) + return err; + } + ++ if (!try_module_get(drv->driver.owner)) { ++ dev_warn(&dev->dev, "failed to acquire module reference on '%s'\n", ++ drv->driver.name); ++ err = -ESRCH; ++ goto fail; ++ } ++ + err = drv->probe(dev, id); + if (err) +- goto fail; ++ goto fail_put; + + err = watch_otherend(dev); + if (err) { +@@ -245,6 +252,8 @@ int xenbus_dev_probe(struct device *_dev) + } + + return 0; ++fail_put: ++ module_put(drv->driver.owner); + fail: + xenbus_dev_error(dev, err, "xenbus_dev_probe on %s", dev->nodename); + xenbus_switch_state(dev, XenbusStateClosed); +@@ -264,6 +273,8 @@ int xenbus_dev_remove(struct device *_dev) + if (drv->remove) + drv->remove(dev); + ++ module_put(drv->driver.owner); ++ + free_otherend_details(dev); + + xenbus_switch_state(dev, XenbusStateClosed); +-- +2.43.0 + diff --git a/queue-5.4/xenbus-backend-add-memory-pressure-handler-callback.patch b/queue-5.4/xenbus-backend-add-memory-pressure-handler-callback.patch new file mode 100644 index 00000000000..587f18f2bc5 --- /dev/null +++ b/queue-5.4/xenbus-backend-add-memory-pressure-handler-callback.patch @@ -0,0 +1,107 @@ +From 235178db56f95bc80686936a50f1b0ae99cd9e55 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Jan 2020 09:18:08 +0100 +Subject: xenbus/backend: Add memory pressure handler callback +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: SeongJae Park + +[ Upstream commit 8a105678fb3ec4763352db84745968bf2cb4aa65 ] + +Granting pages consumes backend system memory. In systems configured +with insufficient spare memory for those pages, it can cause a memory +pressure situation. However, finding the optimal amount of the spare +memory is challenging for large systems having dynamic resource +utilization patterns. Also, such a static configuration might lack +flexibility. + +To mitigate such problems, this commit adds a memory reclaim callback to +'xenbus_driver'. If a memory pressure is detected, 'xenbus' requests +every backend driver to volunarily release its memory. + +Note that it would be able to improve the callback facility for more +sophisticated handlings of general pressures. For example, it would be +possible to monitor the memory consumption of each device and issue the +release requests to only devices which causing the pressure. Also, the +callback could be extended to handle not only memory, but general +resources. Nevertheless, this version of the implementation defers such +sophisticated goals as a future work. + +Reviewed-by: Juergen Gross +Reviewed-by: Roger Pau Monné +Signed-off-by: SeongJae Park +Signed-off-by: Boris Ostrovsky +Stable-dep-of: afc545da381b ("xen: Fix the issue of resource not being properly released in xenbus_dev_probe()") +Signed-off-by: Sasha Levin +--- + drivers/xen/xenbus/xenbus_probe_backend.c | 32 +++++++++++++++++++++++ + include/xen/xenbus.h | 1 + + 2 files changed, 33 insertions(+) + +diff --git a/drivers/xen/xenbus/xenbus_probe_backend.c b/drivers/xen/xenbus/xenbus_probe_backend.c +index 4bb603051d5b6..386a1348694a7 100644 +--- a/drivers/xen/xenbus/xenbus_probe_backend.c ++++ b/drivers/xen/xenbus/xenbus_probe_backend.c +@@ -255,6 +255,35 @@ static int backend_probe_and_watch(struct notifier_block *notifier, + return NOTIFY_DONE; + } + ++static int backend_reclaim_memory(struct device *dev, void *data) ++{ ++ const struct xenbus_driver *drv; ++ ++ if (!dev->driver) ++ return 0; ++ drv = to_xenbus_driver(dev->driver); ++ if (drv && drv->reclaim_memory) ++ drv->reclaim_memory(to_xenbus_device(dev)); ++ return 0; ++} ++ ++/* ++ * Returns 0 always because we are using shrinker to only detect memory ++ * pressure. ++ */ ++static unsigned long backend_shrink_memory_count(struct shrinker *shrinker, ++ struct shrink_control *sc) ++{ ++ bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, ++ backend_reclaim_memory); ++ return 0; ++} ++ ++static struct shrinker backend_memory_shrinker = { ++ .count_objects = backend_shrink_memory_count, ++ .seeks = DEFAULT_SEEKS, ++}; ++ + static int __init xenbus_probe_backend_init(void) + { + static struct notifier_block xenstore_notifier = { +@@ -271,6 +300,9 @@ static int __init xenbus_probe_backend_init(void) + + register_xenstore_notifier(&xenstore_notifier); + ++ if (register_shrinker(&backend_memory_shrinker)) ++ pr_warn("shrinker registration failed\n"); ++ + return 0; + } + subsys_initcall(xenbus_probe_backend_init); +diff --git a/include/xen/xenbus.h b/include/xen/xenbus.h +index 14d47ed4114fd..cf37b2d93560f 100644 +--- a/include/xen/xenbus.h ++++ b/include/xen/xenbus.h +@@ -113,6 +113,7 @@ struct xenbus_driver { + struct device_driver driver; + int (*read_otherend_details)(struct xenbus_device *dev); + int (*is_ready)(struct xenbus_device *dev); ++ void (*reclaim_memory)(struct xenbus_device *dev); + }; + + static inline struct xenbus_driver *to_xenbus_driver(struct device_driver *drv) +-- +2.43.0 + diff --git a/queue-5.4/xenbus-backend-protect-xenbus-callback-with-lock.patch b/queue-5.4/xenbus-backend-protect-xenbus-callback-with-lock.patch new file mode 100644 index 00000000000..bd7b956d4b2 --- /dev/null +++ b/queue-5.4/xenbus-backend-protect-xenbus-callback-with-lock.patch @@ -0,0 +1,101 @@ +From 687767a63056cbd1cadbd9daba0952e79bc78612 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Jan 2020 09:18:09 +0100 +Subject: xenbus/backend: Protect xenbus callback with lock + +From: SeongJae Park + +[ Upstream commit 060eabe8fbe726aca341b518366da4d79e338100 ] + +A driver's 'reclaim_memory' callback can race with 'probe' or 'remove' +because it will be called whenever memory pressure is detected. To +avoid such race, this commit embeds a spinlock in each 'xenbus_device' +and make 'xenbus' to hold the lock while the corresponded callbacks are +running. + +Reviewed-by: Juergen Gross +Signed-off-by: SeongJae Park +Signed-off-by: Boris Ostrovsky +Stable-dep-of: afc545da381b ("xen: Fix the issue of resource not being properly released in xenbus_dev_probe()") +Signed-off-by: Sasha Levin +--- + drivers/xen/xenbus/xenbus_probe.c | 8 +++++++- + drivers/xen/xenbus/xenbus_probe_backend.c | 10 ++++++++-- + include/xen/xenbus.h | 1 + + 3 files changed, 16 insertions(+), 3 deletions(-) + +diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c +index 9215099caad61..1ad5bc9dd6cc4 100644 +--- a/drivers/xen/xenbus/xenbus_probe.c ++++ b/drivers/xen/xenbus/xenbus_probe.c +@@ -240,7 +240,9 @@ int xenbus_dev_probe(struct device *_dev) + goto fail; + } + ++ spin_lock(&dev->reclaim_lock); + err = drv->probe(dev, id); ++ spin_unlock(&dev->reclaim_lock); + if (err) + goto fail_put; + +@@ -270,8 +272,11 @@ int xenbus_dev_remove(struct device *_dev) + + free_otherend_watch(dev); + +- if (drv->remove) ++ if (drv->remove) { ++ spin_lock(&dev->reclaim_lock); + drv->remove(dev); ++ spin_unlock(&dev->reclaim_lock); ++ } + + module_put(drv->driver.owner); + +@@ -484,6 +489,7 @@ int xenbus_probe_node(struct xen_bus_type *bus, + goto fail; + + dev_set_name(&xendev->dev, "%s", devname); ++ spin_lock_init(&xendev->reclaim_lock); + + /* Register with generic device framework. */ + err = device_register(&xendev->dev); +diff --git a/drivers/xen/xenbus/xenbus_probe_backend.c b/drivers/xen/xenbus/xenbus_probe_backend.c +index 386a1348694a7..54aefbbbbff9e 100644 +--- a/drivers/xen/xenbus/xenbus_probe_backend.c ++++ b/drivers/xen/xenbus/xenbus_probe_backend.c +@@ -258,12 +258,18 @@ static int backend_probe_and_watch(struct notifier_block *notifier, + static int backend_reclaim_memory(struct device *dev, void *data) + { + const struct xenbus_driver *drv; ++ struct xenbus_device *xdev; + + if (!dev->driver) + return 0; + drv = to_xenbus_driver(dev->driver); +- if (drv && drv->reclaim_memory) +- drv->reclaim_memory(to_xenbus_device(dev)); ++ if (drv && drv->reclaim_memory) { ++ xdev = to_xenbus_device(dev); ++ if (!spin_trylock(&xdev->reclaim_lock)) ++ return 0; ++ drv->reclaim_memory(xdev); ++ spin_unlock(&xdev->reclaim_lock); ++ } + return 0; + } + +diff --git a/include/xen/xenbus.h b/include/xen/xenbus.h +index cf37b2d93560f..0d166dfe48334 100644 +--- a/include/xen/xenbus.h ++++ b/include/xen/xenbus.h +@@ -85,6 +85,7 @@ struct xenbus_device { + enum xenbus_state state; + struct completion down; + struct work_struct work; ++ spinlock_t reclaim_lock; + }; + + static inline struct xenbus_device *to_xenbus_device(struct device *dev) +-- +2.43.0 +