From ad9878bb983496896813f6c53c0db03c8ae3f4d9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 20 Nov 2025 17:18:14 +0100 Subject: [PATCH] 5.4-stable patches added patches: ipv4-route-prevent-rt_bind_exception-from-rebinding-stale-fnhe.patch spi-try-to-get-acpi-gpio-irq-earlier.patch --- ..._exception-from-rebinding-stale-fnhe.patch | 83 +++++++++++++++++++ queue-5.4/series | 2 + ...spi-try-to-get-acpi-gpio-irq-earlier.patch | 55 ++++++++++++ 3 files changed, 140 insertions(+) create mode 100644 queue-5.4/ipv4-route-prevent-rt_bind_exception-from-rebinding-stale-fnhe.patch create mode 100644 queue-5.4/spi-try-to-get-acpi-gpio-irq-earlier.patch diff --git a/queue-5.4/ipv4-route-prevent-rt_bind_exception-from-rebinding-stale-fnhe.patch b/queue-5.4/ipv4-route-prevent-rt_bind_exception-from-rebinding-stale-fnhe.patch new file mode 100644 index 0000000000..6422ca53fa --- /dev/null +++ b/queue-5.4/ipv4-route-prevent-rt_bind_exception-from-rebinding-stale-fnhe.patch @@ -0,0 +1,83 @@ +From ac1499fcd40fe06479e9b933347b837ccabc2a40 Mon Sep 17 00:00:00 2001 +From: Chuang Wang +Date: Tue, 11 Nov 2025 14:43:24 +0800 +Subject: ipv4: route: Prevent rt_bind_exception() from rebinding stale fnhe + +From: Chuang Wang + +commit ac1499fcd40fe06479e9b933347b837ccabc2a40 upstream. + +The sit driver's packet transmission path calls: sit_tunnel_xmit() -> +update_or_create_fnhe(), which lead to fnhe_remove_oldest() being called +to delete entries exceeding FNHE_RECLAIM_DEPTH+random. + +The race window is between fnhe_remove_oldest() selecting fnheX for +deletion and the subsequent kfree_rcu(). During this time, the +concurrent path's __mkroute_output() -> find_exception() can fetch the +soon-to-be-deleted fnheX, and rt_bind_exception() then binds it with a +new dst using a dst_hold(). When the original fnheX is freed via RCU, +the dst reference remains permanently leaked. + +CPU 0 CPU 1 +__mkroute_output() + find_exception() [fnheX] + update_or_create_fnhe() + fnhe_remove_oldest() [fnheX] + rt_bind_exception() [bind dst] + RCU callback [fnheX freed, dst leak] + +This issue manifests as a device reference count leak and a warning in +dmesg when unregistering the net device: + + unregister_netdevice: waiting for sitX to become free. Usage count = N + +Ido Schimmel provided the simple test validation method [1]. + +The fix clears 'oldest->fnhe_daddr' before calling fnhe_flush_routes(). +Since rt_bind_exception() checks this field, setting it to zero prevents +the stale fnhe from being reused and bound to a new dst just before it +is freed. + +[1] +ip netns add ns1 +ip -n ns1 link set dev lo up +ip -n ns1 address add 192.0.2.1/32 dev lo +ip -n ns1 link add name dummy1 up type dummy +ip -n ns1 route add 192.0.2.2/32 dev dummy1 +ip -n ns1 link add name gretap1 up arp off type gretap \ + local 192.0.2.1 remote 192.0.2.2 +ip -n ns1 route add 198.51.0.0/16 dev gretap1 +taskset -c 0 ip netns exec ns1 mausezahn gretap1 \ + -A 198.51.100.1 -B 198.51.0.0/16 -t udp -p 1000 -c 0 -q & +taskset -c 2 ip netns exec ns1 mausezahn gretap1 \ + -A 198.51.100.1 -B 198.51.0.0/16 -t udp -p 1000 -c 0 -q & +sleep 10 +ip netns pids ns1 | xargs kill +ip netns del ns1 + +Cc: stable@vger.kernel.org +Fixes: 67d6d681e15b ("ipv4: make exception cache less predictible") +Signed-off-by: Chuang Wang +Reviewed-by: Ido Schimmel +Reviewed-by: Eric Dumazet +Link: https://patch.msgid.link/20251111064328.24440-1-nashuiliang@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/route.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -637,6 +637,11 @@ static void fnhe_remove_oldest(struct fn + oldest_p = fnhe_p; + } + } ++ ++ /* Clear oldest->fnhe_daddr to prevent this fnhe from being ++ * rebound with new dsts in rt_bind_exception(). ++ */ ++ oldest->fnhe_daddr = 0; + fnhe_flush_routes(oldest); + *oldest_p = oldest->fnhe_next; + kfree_rcu(oldest, rcu); diff --git a/queue-5.4/series b/queue-5.4/series index 4a8d1cdcfc..3bcf35e15a 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -151,3 +151,5 @@ alsa-usb-audio-fix-null-pointer-dereference-in-snd_u.patch mm-ksm-fix-flag-dropping-behavior-in-ksm_madvise.patch gcov-add-support-for-gcc-15.patch strparser-fix-signed-unsigned-mismatch-bug.patch +ipv4-route-prevent-rt_bind_exception-from-rebinding-stale-fnhe.patch +spi-try-to-get-acpi-gpio-irq-earlier.patch diff --git a/queue-5.4/spi-try-to-get-acpi-gpio-irq-earlier.patch b/queue-5.4/spi-try-to-get-acpi-gpio-irq-earlier.patch new file mode 100644 index 0000000000..6143294df0 --- /dev/null +++ b/queue-5.4/spi-try-to-get-acpi-gpio-irq-earlier.patch @@ -0,0 +1,55 @@ +From 3cd2018e15b3d66d2187d92867e265f45ad79e6f Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Sun, 2 Nov 2025 20:09:21 +0100 +Subject: spi: Try to get ACPI GPIO IRQ earlier + +From: Hans de Goede + +commit 3cd2018e15b3d66d2187d92867e265f45ad79e6f upstream. + +Since commit d24cfee7f63d ("spi: Fix acpi deferred irq probe"), the +acpi_dev_gpio_irq_get() call gets delayed till spi_probe() is called +on the SPI device. + +If there is no driver for the SPI device then the move to spi_probe() +results in acpi_dev_gpio_irq_get() never getting called. This may +cause problems by leaving the GPIO pin floating because this call is +responsible for setting up the GPIO pin direction and/or bias according +to the values from the ACPI tables. + +Re-add the removed acpi_dev_gpio_irq_get() in acpi_register_spi_device() +to ensure the GPIO pin is always correctly setup, while keeping the +acpi_dev_gpio_irq_get() call added to spi_probe() to deal with +-EPROBE_DEFER returns caused by the GPIO controller not having a driver +yet. + +Link: https://bbs.archlinux.org/viewtopic.php?id=302348 +Fixes: d24cfee7f63d ("spi: Fix acpi deferred irq probe") +Cc: stable@vger.kernel.org +Signed-off-by: Hans de Goede +Link: https://patch.msgid.link/20251102190921.30068-1-hansg@kernel.org +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman +--- + drivers/spi/spi.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/drivers/spi/spi.c ++++ b/drivers/spi/spi.c +@@ -2055,6 +2055,16 @@ static acpi_status acpi_register_spi_dev + acpi_set_modalias(adev, acpi_device_hid(adev), spi->modalias, + sizeof(spi->modalias)); + ++ /* ++ * This gets re-tried in spi_probe() for -EPROBE_DEFER handling in case ++ * the GPIO controller does not have a driver yet. This needs to be done ++ * here too, because this call sets the GPIO direction and/or bias. ++ * Setting these needs to be done even if there is no driver, in which ++ * case spi_probe() will never get called. ++ */ ++ if (spi->irq < 0) ++ spi->irq = acpi_dev_gpio_irq_get(adev, 0); ++ + acpi_device_set_enumerated(adev); + + adev->power.flags.ignore_parent = true; -- 2.47.3