From: Greg Kroah-Hartman Date: Tue, 22 Apr 2025 07:27:53 +0000 (+0200) Subject: 5.4-stable patches X-Git-Tag: v6.1.135~97 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1d75af67f0e7532b81fcfd3834501965c9ce389b;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: powerpc-prom_init-use-ffreestanding-to-avoid-a-reference-to-bcmp.patch tcp-dccp-don-t-use-timer_pending-in-reqsk_queue_unlink.patch --- diff --git a/queue-5.4/powerpc-prom_init-use-ffreestanding-to-avoid-a-reference-to-bcmp.patch b/queue-5.4/powerpc-prom_init-use-ffreestanding-to-avoid-a-reference-to-bcmp.patch new file mode 100644 index 0000000000..793b42406b --- /dev/null +++ b/queue-5.4/powerpc-prom_init-use-ffreestanding-to-avoid-a-reference-to-bcmp.patch @@ -0,0 +1,48 @@ +From 8dcd71b45df34d9b903450fab147ee8c1e6c16b5 Mon Sep 17 00:00:00 2001 +From: Nathan Chancellor +Date: Mon, 18 Nov 2019 21:57:12 -0700 +Subject: powerpc/prom_init: Use -ffreestanding to avoid a reference to bcmp + +From: Nathan Chancellor + +commit 8dcd71b45df34d9b903450fab147ee8c1e6c16b5 upstream. + +LLVM revision r374662 gives LLVM the ability to convert certain loops +into a reference to bcmp as an optimization; this breaks +prom_init_check.sh: + + CALL arch/powerpc/kernel/prom_init_check.sh + Error: External symbol 'bcmp' referenced from prom_init.c + make[2]: *** [arch/powerpc/kernel/Makefile:196: prom_init_check] Error 1 + +bcmp is defined in lib/string.c as a wrapper for memcmp so this could +be added to the whitelist. However, commit +450e7dd4001f ("powerpc/prom_init: don't use string functions from +lib/") copied memcmp as prom_memcmp to avoid KASAN instrumentation so +having bcmp be resolved to regular memcmp would break that assumption. +Furthermore, because the compiler is the one that inserted bcmp, we +cannot provide something like prom_bcmp. + +To prevent LLVM from being clever with optimizations like this, use +-ffreestanding to tell LLVM we are not hosted so it is not free to +make transformations like this. + +Reviewed-by: Nick Desaulneris +Signed-off-by: Nathan Chancellor +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/20191119045712.39633-4-natechancellor@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + arch/powerpc/kernel/Makefile | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/powerpc/kernel/Makefile ++++ b/arch/powerpc/kernel/Makefile +@@ -21,6 +21,7 @@ CFLAGS_prom.o += $(DISABLE_LATENT_ENTROP + + CFLAGS_prom_init.o += $(call cc-option, -fno-stack-protector) + CFLAGS_prom_init.o += -DDISABLE_BRANCH_PROFILING ++CFLAGS_prom_init.o += -ffreestanding + + ifdef CONFIG_FUNCTION_TRACER + # Do not trace early boot code diff --git a/queue-5.4/series b/queue-5.4/series index d570df499f..eb3e7be2e8 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -109,3 +109,5 @@ drm-nouveau-prime-fix-ttm_bo_delayed_delete-oops.patch drm-sti-remove-duplicate-object-names.patch cpufreq-reference-count-policy-in-cpufreq_update_limits.patch kbuild-add-fno-builtin-wcslen.patch +powerpc-prom_init-use-ffreestanding-to-avoid-a-reference-to-bcmp.patch +tcp-dccp-don-t-use-timer_pending-in-reqsk_queue_unlink.patch diff --git a/queue-5.4/tcp-dccp-don-t-use-timer_pending-in-reqsk_queue_unlink.patch b/queue-5.4/tcp-dccp-don-t-use-timer_pending-in-reqsk_queue_unlink.patch new file mode 100644 index 0000000000..8529c9082c --- /dev/null +++ b/queue-5.4/tcp-dccp-don-t-use-timer_pending-in-reqsk_queue_unlink.patch @@ -0,0 +1,168 @@ +From e8c526f2bdf1845bedaf6a478816a3d06fa78b8f Mon Sep 17 00:00:00 2001 +From: Kuniyuki Iwashima +Date: Mon, 14 Oct 2024 15:33:12 -0700 +Subject: tcp/dccp: Don't use timer_pending() in reqsk_queue_unlink(). + +From: Kuniyuki Iwashima + +commit e8c526f2bdf1845bedaf6a478816a3d06fa78b8f upstream. + +Martin KaFai Lau reported use-after-free [0] in reqsk_timer_handler(). + + """ + We are seeing a use-after-free from a bpf prog attached to + trace_tcp_retransmit_synack. The program passes the req->sk to the + bpf_sk_storage_get_tracing kernel helper which does check for null + before using it. + """ + +The commit 83fccfc3940c ("inet: fix potential deadlock in +reqsk_queue_unlink()") added timer_pending() in reqsk_queue_unlink() not +to call del_timer_sync() from reqsk_timer_handler(), but it introduced a +small race window. + +Before the timer is called, expire_timers() calls detach_timer(timer, true) +to clear timer->entry.pprev and marks it as not pending. + +If reqsk_queue_unlink() checks timer_pending() just after expire_timers() +calls detach_timer(), TCP will miss del_timer_sync(); the reqsk timer will +continue running and send multiple SYN+ACKs until it expires. + +The reported UAF could happen if req->sk is close()d earlier than the timer +expiration, which is 63s by default. + +The scenario would be + + 1. inet_csk_complete_hashdance() calls inet_csk_reqsk_queue_drop(), + but del_timer_sync() is missed + + 2. reqsk timer is executed and scheduled again + + 3. req->sk is accept()ed and reqsk_put() decrements rsk_refcnt, but + reqsk timer still has another one, and inet_csk_accept() does not + clear req->sk for non-TFO sockets + + 4. sk is close()d + + 5. reqsk timer is executed again, and BPF touches req->sk + +Let's not use timer_pending() by passing the caller context to +__inet_csk_reqsk_queue_drop(). + +Note that reqsk timer is pinned, so the issue does not happen in most +use cases. [1] + +[0] +BUG: KFENCE: use-after-free read in bpf_sk_storage_get_tracing+0x2e/0x1b0 + +Use-after-free read at 0x00000000a891fb3a (in kfence-#1): +bpf_sk_storage_get_tracing+0x2e/0x1b0 +bpf_prog_5ea3e95db6da0438_tcp_retransmit_synack+0x1d20/0x1dda +bpf_trace_run2+0x4c/0xc0 +tcp_rtx_synack+0xf9/0x100 +reqsk_timer_handler+0xda/0x3d0 +run_timer_softirq+0x292/0x8a0 +irq_exit_rcu+0xf5/0x320 +sysvec_apic_timer_interrupt+0x6d/0x80 +asm_sysvec_apic_timer_interrupt+0x16/0x20 +intel_idle_irq+0x5a/0xa0 +cpuidle_enter_state+0x94/0x273 +cpu_startup_entry+0x15e/0x260 +start_secondary+0x8a/0x90 +secondary_startup_64_no_verify+0xfa/0xfb + +kfence-#1: 0x00000000a72cc7b6-0x00000000d97616d9, size=2376, cache=TCPv6 + +allocated by task 0 on cpu 9 at 260507.901592s: +sk_prot_alloc+0x35/0x140 +sk_clone_lock+0x1f/0x3f0 +inet_csk_clone_lock+0x15/0x160 +tcp_create_openreq_child+0x1f/0x410 +tcp_v6_syn_recv_sock+0x1da/0x700 +tcp_check_req+0x1fb/0x510 +tcp_v6_rcv+0x98b/0x1420 +ipv6_list_rcv+0x2258/0x26e0 +napi_complete_done+0x5b1/0x2990 +mlx5e_napi_poll+0x2ae/0x8d0 +net_rx_action+0x13e/0x590 +irq_exit_rcu+0xf5/0x320 +common_interrupt+0x80/0x90 +asm_common_interrupt+0x22/0x40 +cpuidle_enter_state+0xfb/0x273 +cpu_startup_entry+0x15e/0x260 +start_secondary+0x8a/0x90 +secondary_startup_64_no_verify+0xfa/0xfb + +freed by task 0 on cpu 9 at 260507.927527s: +rcu_core_si+0x4ff/0xf10 +irq_exit_rcu+0xf5/0x320 +sysvec_apic_timer_interrupt+0x6d/0x80 +asm_sysvec_apic_timer_interrupt+0x16/0x20 +cpuidle_enter_state+0xfb/0x273 +cpu_startup_entry+0x15e/0x260 +start_secondary+0x8a/0x90 +secondary_startup_64_no_verify+0xfa/0xfb + +Fixes: 83fccfc3940c ("inet: fix potential deadlock in reqsk_queue_unlink()") +Reported-by: Martin KaFai Lau +Closes: https://lore.kernel.org/netdev/eb6684d0-ffd9-4bdc-9196-33f690c25824@linux.dev/ +Link: https://lore.kernel.org/netdev/b55e2ca0-42f2-4b7c-b445-6ffd87ca74a0@linux.dev/ [1] +Signed-off-by: Kuniyuki Iwashima +Reviewed-by: Eric Dumazet +Reviewed-by: Martin KaFai Lau +Link: https://patch.msgid.link/20241014223312.4254-1-kuniyu@amazon.com +Signed-off-by: Jakub Kicinski +[Resolved conflicts due to context difference] +Signed-off-by: Nathan Gao +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/inet_connection_sock.c | 19 +++++++++++++++---- + 1 file changed, 15 insertions(+), 4 deletions(-) + +--- a/net/ipv4/inet_connection_sock.c ++++ b/net/ipv4/inet_connection_sock.c +@@ -709,21 +709,31 @@ static bool reqsk_queue_unlink(struct re + found = __sk_nulls_del_node_init_rcu(req_to_sk(req)); + spin_unlock(lock); + } +- if (timer_pending(&req->rsk_timer) && del_timer_sync(&req->rsk_timer)) +- reqsk_put(req); ++ + return found; + } + +-bool inet_csk_reqsk_queue_drop(struct sock *sk, struct request_sock *req) ++static bool __inet_csk_reqsk_queue_drop(struct sock *sk, ++ struct request_sock *req, ++ bool from_timer) + { + bool unlinked = reqsk_queue_unlink(req); + ++ if (!from_timer && timer_delete_sync(&req->rsk_timer)) ++ reqsk_put(req); ++ + if (unlinked) { + reqsk_queue_removed(&inet_csk(sk)->icsk_accept_queue, req); + reqsk_put(req); + } ++ + return unlinked; + } ++ ++bool inet_csk_reqsk_queue_drop(struct sock *sk, struct request_sock *req) ++{ ++ return __inet_csk_reqsk_queue_drop(sk, req, false); ++} + EXPORT_SYMBOL(inet_csk_reqsk_queue_drop); + + void inet_csk_reqsk_queue_drop_and_put(struct sock *sk, struct request_sock *req) +@@ -796,7 +806,8 @@ static void reqsk_timer_handler(struct t + return; + } + drop: +- inet_csk_reqsk_queue_drop_and_put(sk_listener, req); ++ __inet_csk_reqsk_queue_drop(sk_listener, req, true); ++ reqsk_put(req); + } + + static void reqsk_queue_hash_req(struct request_sock *req,