diff options
9 files changed, 825 insertions, 0 deletions
diff --git a/queue-6.12/bpf-fix-l4-csum-update-on-ipv6-in-checksum_complete.patch b/queue-6.12/bpf-fix-l4-csum-update-on-ipv6-in-checksum_complete.patch new file mode 100644 index 00000000000..38492cd3858 --- /dev/null +++ b/queue-6.12/bpf-fix-l4-csum-update-on-ipv6-in-checksum_complete.patch @@ -0,0 +1,129 @@ +From ead7f9b8de65632ef8060b84b0c55049a33cfea1 Mon Sep 17 00:00:00 2001 +From: Paul Chaignon <paul.chaignon@gmail.com> +Date: Thu, 29 May 2025 12:28:35 +0200 +Subject: bpf: Fix L4 csum update on IPv6 in CHECKSUM_COMPLETE + +From: Paul Chaignon <paul.chaignon@gmail.com> + +commit ead7f9b8de65632ef8060b84b0c55049a33cfea1 upstream. + +In Cilium, we use bpf_csum_diff + bpf_l4_csum_replace to, among other +things, update the L4 checksum after reverse SNATing IPv6 packets. That +use case is however not currently supported and leads to invalid +skb->csum values in some cases. This patch adds support for IPv6 address +changes in bpf_l4_csum_update via a new flag. + +When calling bpf_l4_csum_replace in Cilium, it ends up calling +inet_proto_csum_replace_by_diff: + + 1: void inet_proto_csum_replace_by_diff(__sum16 *sum, struct sk_buff *skb, + 2: __wsum diff, bool pseudohdr) + 3: { + 4: if (skb->ip_summed != CHECKSUM_PARTIAL) { + 5: csum_replace_by_diff(sum, diff); + 6: if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr) + 7: skb->csum = ~csum_sub(diff, skb->csum); + 8: } else if (pseudohdr) { + 9: *sum = ~csum_fold(csum_add(diff, csum_unfold(*sum))); + 10: } + 11: } + +The bug happens when we're in the CHECKSUM_COMPLETE state. We've just +updated one of the IPv6 addresses. The helper now updates the L4 header +checksum on line 5. Next, it updates skb->csum on line 7. It shouldn't. + +For an IPv6 packet, the updates of the IPv6 address and of the L4 +checksum will cancel each other. The checksums are set such that +computing a checksum over the packet including its checksum will result +in a sum of 0. So the same is true here when we update the L4 checksum +on line 5. We'll update it as to cancel the previous IPv6 address +update. Hence skb->csum should remain untouched in this case. + +The same bug doesn't affect IPv4 packets because, in that case, three +fields are updated: the IPv4 address, the IP checksum, and the L4 +checksum. The change to the IPv4 address and one of the checksums still +cancel each other in skb->csum, but we're left with one checksum update +and should therefore update skb->csum accordingly. That's exactly what +inet_proto_csum_replace_by_diff does. + +This special case for IPv6 L4 checksums is also described atop +inet_proto_csum_replace16, the function we should be using in this case. + +This patch introduces a new bpf_l4_csum_replace flag, BPF_F_IPV6, +to indicate that we're updating the L4 checksum of an IPv6 packet. When +the flag is set, inet_proto_csum_replace_by_diff will skip the +skb->csum update. + +Fixes: 7d672345ed295 ("bpf: add generic bpf_csum_diff helper") +Signed-off-by: Paul Chaignon <paul.chaignon@gmail.com> +Acked-by: Daniel Borkmann <daniel@iogearbox.net> +Link: https://patch.msgid.link/96a6bc3a443e6f0b21ff7b7834000e17fb549e05.1748509484.git.paul.chaignon@gmail.com +Signed-off-by: Jakub Kicinski <kuba@kernel.org> +Signed-off-by: Paul Chaignon <paul.chaignon@gmail.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + include/uapi/linux/bpf.h | 2 ++ + net/core/filter.c | 5 +++-- + tools/include/uapi/linux/bpf.h | 2 ++ + 3 files changed, 7 insertions(+), 2 deletions(-) + +--- a/include/uapi/linux/bpf.h ++++ b/include/uapi/linux/bpf.h +@@ -2035,6 +2035,7 @@ union bpf_attr { + * for updates resulting in a null checksum the value is set to + * **CSUM_MANGLED_0** instead. Flag **BPF_F_PSEUDO_HDR** indicates + * the checksum is to be computed against a pseudo-header. ++ * Flag **BPF_F_IPV6** should be set for IPv6 packets. + * + * This helper works in combination with **bpf_csum_diff**\ (), + * which does not update the checksum in-place, but offers more +@@ -6049,6 +6050,7 @@ enum { + BPF_F_PSEUDO_HDR = (1ULL << 4), + BPF_F_MARK_MANGLED_0 = (1ULL << 5), + BPF_F_MARK_ENFORCE = (1ULL << 6), ++ BPF_F_IPV6 = (1ULL << 7), + }; + + /* BPF_FUNC_skb_set_tunnel_key and BPF_FUNC_skb_get_tunnel_key flags. */ +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -1980,10 +1980,11 @@ BPF_CALL_5(bpf_l4_csum_replace, struct s + bool is_pseudo = flags & BPF_F_PSEUDO_HDR; + bool is_mmzero = flags & BPF_F_MARK_MANGLED_0; + bool do_mforce = flags & BPF_F_MARK_ENFORCE; ++ bool is_ipv6 = flags & BPF_F_IPV6; + __sum16 *ptr; + + if (unlikely(flags & ~(BPF_F_MARK_MANGLED_0 | BPF_F_MARK_ENFORCE | +- BPF_F_PSEUDO_HDR | BPF_F_HDR_FIELD_MASK))) ++ BPF_F_PSEUDO_HDR | BPF_F_HDR_FIELD_MASK | BPF_F_IPV6))) + return -EINVAL; + if (unlikely(offset > 0xffff || offset & 1)) + return -EFAULT; +@@ -1999,7 +2000,7 @@ BPF_CALL_5(bpf_l4_csum_replace, struct s + if (unlikely(from != 0)) + return -EINVAL; + +- inet_proto_csum_replace_by_diff(ptr, skb, to, is_pseudo, false); ++ inet_proto_csum_replace_by_diff(ptr, skb, to, is_pseudo, is_ipv6); + break; + case 2: + inet_proto_csum_replace2(ptr, skb, from, to, is_pseudo); +--- a/tools/include/uapi/linux/bpf.h ++++ b/tools/include/uapi/linux/bpf.h +@@ -2035,6 +2035,7 @@ union bpf_attr { + * for updates resulting in a null checksum the value is set to + * **CSUM_MANGLED_0** instead. Flag **BPF_F_PSEUDO_HDR** indicates + * the checksum is to be computed against a pseudo-header. ++ * Flag **BPF_F_IPV6** should be set for IPv6 packets. + * + * This helper works in combination with **bpf_csum_diff**\ (), + * which does not update the checksum in-place, but offers more +@@ -6049,6 +6050,7 @@ enum { + BPF_F_PSEUDO_HDR = (1ULL << 4), + BPF_F_MARK_MANGLED_0 = (1ULL << 5), + BPF_F_MARK_ENFORCE = (1ULL << 6), ++ BPF_F_IPV6 = (1ULL << 7), + }; + + /* BPF_FUNC_skb_set_tunnel_key and BPF_FUNC_skb_get_tunnel_key flags. */ diff --git a/queue-6.12/drm-v3d-avoid-null-pointer-dereference-in-v3d_job_update_stats.patch b/queue-6.12/drm-v3d-avoid-null-pointer-dereference-in-v3d_job_update_stats.patch new file mode 100644 index 00000000000..4f8e42a88fa --- /dev/null +++ b/queue-6.12/drm-v3d-avoid-null-pointer-dereference-in-v3d_job_update_stats.patch @@ -0,0 +1,111 @@ +From e1bc3a13bd775791cca0bb144d977b00f3598042 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ma=C3=ADra=20Canal?= <mcanal@igalia.com> +Date: Mon, 2 Jun 2025 12:14:02 -0300 +Subject: drm/v3d: Avoid NULL pointer dereference in `v3d_job_update_stats()` +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Maíra Canal <mcanal@igalia.com> + +commit e1bc3a13bd775791cca0bb144d977b00f3598042 upstream. + +The following kernel Oops was recently reported by Mesa CI: + +[ 800.139824] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000588 +[ 800.148619] Mem abort info: +[ 800.151402] ESR = 0x0000000096000005 +[ 800.155141] EC = 0x25: DABT (current EL), IL = 32 bits +[ 800.160444] SET = 0, FnV = 0 +[ 800.163488] EA = 0, S1PTW = 0 +[ 800.166619] FSC = 0x05: level 1 translation fault +[ 800.171487] Data abort info: +[ 800.174357] ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000 +[ 800.179832] CM = 0, WnR = 0, TnD = 0, TagAccess = 0 +[ 800.184873] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 +[ 800.190176] user pgtable: 4k pages, 39-bit VAs, pgdp=00000001014c2000 +[ 800.196607] [0000000000000588] pgd=0000000000000000, p4d=0000000000000000, pud=0000000000000000 +[ 800.205305] Internal error: Oops: 0000000096000005 [#1] PREEMPT SMP +[ 800.211564] Modules linked in: vc4 snd_soc_hdmi_codec drm_display_helper v3d cec gpu_sched drm_dma_helper drm_shmem_helper drm_kms_helper drm drm_panel_orientation_quirks snd_soc_core snd_compress snd_pcm_dmaengine snd_pcm i2c_brcmstb snd_timer snd backlight +[ 800.234448] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.12.25+rpt-rpi-v8 #1 Debian 1:6.12.25-1+rpt1 +[ 800.244182] Hardware name: Raspberry Pi 4 Model B Rev 1.4 (DT) +[ 800.250005] pstate: 600000c5 (nZCv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--) +[ 800.256959] pc : v3d_job_update_stats+0x60/0x130 [v3d] +[ 800.262112] lr : v3d_job_update_stats+0x48/0x130 [v3d] +[ 800.267251] sp : ffffffc080003e60 +[ 800.270555] x29: ffffffc080003e60 x28: ffffffd842784980 x27: 0224012000000000 +[ 800.277687] x26: ffffffd84277f630 x25: ffffff81012fd800 x24: 0000000000000020 +[ 800.284818] x23: ffffff8040238b08 x22: 0000000000000570 x21: 0000000000000158 +[ 800.291948] x20: 0000000000000000 x19: ffffff8040238000 x18: 0000000000000000 +[ 800.299078] x17: ffffffa8c1bd2000 x16: ffffffc080000000 x15: 0000000000000000 +[ 800.306208] x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000000 +[ 800.313338] x11: 0000000000000040 x10: 0000000000001a40 x9 : ffffffd83b39757c +[ 800.320468] x8 : ffffffd842786420 x7 : 7fffffffffffffff x6 : 0000000000ef32b0 +[ 800.327598] x5 : 00ffffffffffffff x4 : 0000000000000015 x3 : ffffffd842784980 +[ 800.334728] x2 : 0000000000000004 x1 : 0000000000010002 x0 : 000000ba4c0ca382 +[ 800.341859] Call trace: +[ 800.344294] v3d_job_update_stats+0x60/0x130 [v3d] +[ 800.349086] v3d_irq+0x124/0x2e0 [v3d] +[ 800.352835] __handle_irq_event_percpu+0x58/0x218 +[ 800.357539] handle_irq_event+0x54/0xb8 +[ 800.361369] handle_fasteoi_irq+0xac/0x240 +[ 800.365458] handle_irq_desc+0x48/0x68 +[ 800.369200] generic_handle_domain_irq+0x24/0x38 +[ 800.373810] gic_handle_irq+0x48/0xd8 +[ 800.377464] call_on_irq_stack+0x24/0x58 +[ 800.381379] do_interrupt_handler+0x88/0x98 +[ 800.385554] el1_interrupt+0x34/0x68 +[ 800.389123] el1h_64_irq_handler+0x18/0x28 +[ 800.393211] el1h_64_irq+0x64/0x68 +[ 800.396603] default_idle_call+0x3c/0x168 +[ 800.400606] do_idle+0x1fc/0x230 +[ 800.403827] cpu_startup_entry+0x40/0x50 +[ 800.407742] rest_init+0xe4/0xf0 +[ 800.410962] start_kernel+0x5e8/0x790 +[ 800.414616] __primary_switched+0x80/0x90 +[ 800.418622] Code: 8b170277 8b160296 11000421 b9000861 (b9401ac1) +[ 800.424707] ---[ end trace 0000000000000000 ]--- +[ 800.457313] ---[ end Kernel panic - not syncing: Oops: Fatal exception in interrupt ]--- + +This issue happens when the file descriptor is closed before the jobs +submitted by it are completed. When the job completes, we update the +global GPU stats and the per-fd GPU stats, which are exposed through +fdinfo. If the file descriptor was closed, then the struct `v3d_file_priv` +and its stats were already freed and we can't update the per-fd stats. + +Therefore, if the file descriptor was already closed, don't update the +per-fd GPU stats, only update the global ones. + +Cc: stable@vger.kernel.org # v6.12+ +Reviewed-by: Jose Maria Casanova Crespo <jmcasanova@igalia.com> +Link: https://lore.kernel.org/r/20250602151451.10161-1-mcanal@igalia.com +Signed-off-by: Maíra Canal <mcanal@igalia.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + drivers/gpu/drm/v3d/v3d_sched.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/v3d/v3d_sched.c ++++ b/drivers/gpu/drm/v3d/v3d_sched.c +@@ -191,7 +191,6 @@ v3d_job_update_stats(struct v3d_job *job + struct v3d_dev *v3d = job->v3d; + struct v3d_file_priv *file = job->file->driver_priv; + struct v3d_stats *global_stats = &v3d->queue[queue].stats; +- struct v3d_stats *local_stats = &file->stats[queue]; + u64 now = local_clock(); + unsigned long flags; + +@@ -201,7 +200,12 @@ v3d_job_update_stats(struct v3d_job *job + else + preempt_disable(); + +- v3d_stats_update(local_stats, now); ++ /* Don't update the local stats if the file context has already closed */ ++ if (file) ++ v3d_stats_update(&file->stats[queue], now); ++ else ++ drm_dbg(&v3d->drm, "The file descriptor was closed before job completion\n"); ++ + v3d_stats_update(global_stats, now); + + if (IS_ENABLED(CONFIG_LOCKDEP)) diff --git a/queue-6.12/erofs-remove-unused-trace-event-erofs_destroy_inode.patch b/queue-6.12/erofs-remove-unused-trace-event-erofs_destroy_inode.patch new file mode 100644 index 00000000000..cab2e51c1c1 --- /dev/null +++ b/queue-6.12/erofs-remove-unused-trace-event-erofs_destroy_inode.patch @@ -0,0 +1,51 @@ +From 30b58444807c93bffeaba7d776110f2a909d2f9a Mon Sep 17 00:00:00 2001 +From: Gao Xiang <hsiangkao@linux.alibaba.com> +Date: Tue, 17 Jun 2025 13:40:56 +0800 +Subject: erofs: remove unused trace event erofs_destroy_inode + +From: Gao Xiang <hsiangkao@linux.alibaba.com> + +commit 30b58444807c93bffeaba7d776110f2a909d2f9a upstream. + +The trace event `erofs_destroy_inode` was added but remains unused. This +unused event contributes approximately 5KB to the kernel module size. + +Reported-by: Steven Rostedt <rostedt@goodmis.org> +Closes: https://lore.kernel.org/r/20250612224906.15000244@batman.local.home +Fixes: 13f06f48f7bf ("staging: erofs: support tracepoint") +Cc: stable@vger.kernel.org +Reviewed-by: Hongbo Li <lihongbo22@huawei.com> +Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com> +Link: https://lore.kernel.org/r/20250617054056.3232365-1-hsiangkao@linux.alibaba.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + include/trace/events/erofs.h | 18 ------------------ + 1 file changed, 18 deletions(-) + +--- a/include/trace/events/erofs.h ++++ b/include/trace/events/erofs.h +@@ -211,24 +211,6 @@ TRACE_EVENT(erofs_map_blocks_exit, + show_mflags(__entry->mflags), __entry->ret) + ); + +-TRACE_EVENT(erofs_destroy_inode, +- TP_PROTO(struct inode *inode), +- +- TP_ARGS(inode), +- +- TP_STRUCT__entry( +- __field( dev_t, dev ) +- __field( erofs_nid_t, nid ) +- ), +- +- TP_fast_assign( +- __entry->dev = inode->i_sb->s_dev; +- __entry->nid = EROFS_I(inode)->nid; +- ), +- +- TP_printk("dev = (%d,%d), nid = %llu", show_dev_nid(__entry)) +-); +- + #endif /* _TRACE_EROFS_H */ + + /* This part must be outside protection */ diff --git a/queue-6.12/kbuild-rust-add-rustc-min-version-support-function.patch b/queue-6.12/kbuild-rust-add-rustc-min-version-support-function.patch new file mode 100644 index 00000000000..83bb39994ed --- /dev/null +++ b/queue-6.12/kbuild-rust-add-rustc-min-version-support-function.patch @@ -0,0 +1,75 @@ +From ac954145e1ee3f72033161cbe4ac0b16b5354ae7 Mon Sep 17 00:00:00 2001 +From: Miguel Ojeda <ojeda@kernel.org> +Date: Mon, 10 Feb 2025 17:42:45 +0100 +Subject: kbuild: rust: add rustc-min-version support function + +From: Miguel Ojeda <ojeda@kernel.org> + +commit ac954145e1ee3f72033161cbe4ac0b16b5354ae7 upstream. + +Introduce `rustc-min-version` support function that mimics +`{gcc,clang}-min-version` ones, following commit 88b61e3bff93 +("Makefile.compiler: replace cc-ifversion with compiler-specific macros"). + +In addition, use it in the first use case we have in the kernel (which +was done independently to minimize the changes needed for the fix). + +Signed-off-by: Miguel Ojeda <ojeda@kernel.org> +Reviewed-by: Fiona Behrens <me@Kloenk.dev> +Reviewed-by: Nicolas Schier <n.schier@avm.de> +Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> +Signed-off-by: Miguel Ojeda <ojeda@kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + Documentation/kbuild/makefiles.rst | 14 ++++++++++++++ + arch/arm64/Makefile | 2 +- + scripts/Makefile.compiler | 4 ++++ + 3 files changed, 19 insertions(+), 1 deletion(-) + +--- a/Documentation/kbuild/makefiles.rst ++++ b/Documentation/kbuild/makefiles.rst +@@ -656,6 +656,20 @@ cc-cross-prefix + endif + endif + ++$(RUSTC) support functions ++-------------------------- ++ ++rustc-min-version ++ rustc-min-version tests if the value of $(CONFIG_RUSTC_VERSION) is greater ++ than or equal to the provided value and evaluates to y if so. ++ ++ Example:: ++ ++ rustflags-$(call rustc-min-version, 108500) := -Cfoo ++ ++ In this example, rustflags-y will be assigned the value -Cfoo if ++ $(CONFIG_RUSTC_VERSION) is >= 1.85.0. ++ + $(LD) support functions + ----------------------- + +--- a/arch/arm64/Makefile ++++ b/arch/arm64/Makefile +@@ -48,7 +48,7 @@ KBUILD_CFLAGS += $(CC_FLAGS_NO_FPU) \ + KBUILD_CFLAGS += $(call cc-disable-warning, psabi) + KBUILD_AFLAGS += $(compat_vdso) + +-ifeq ($(call test-ge, $(CONFIG_RUSTC_VERSION), 108500),y) ++ifeq ($(call rustc-min-version, 108500),y) + KBUILD_RUSTFLAGS += --target=aarch64-unknown-none-softfloat + else + KBUILD_RUSTFLAGS += --target=aarch64-unknown-none -Ctarget-feature="-neon" +--- a/scripts/Makefile.compiler ++++ b/scripts/Makefile.compiler +@@ -67,6 +67,10 @@ gcc-min-version = $(call test-ge, $(CONF + # Usage: cflags-$(call clang-min-version, 110000) += -foo + clang-min-version = $(call test-ge, $(CONFIG_CLANG_VERSION), $1) + ++# rustc-min-version ++# Usage: rustc-$(call rustc-min-version, 108500) += -Cfoo ++rustc-min-version = $(call test-ge, $(CONFIG_RUSTC_VERSION), $1) ++ + # ld-option + # Usage: KBUILD_LDFLAGS += $(call ld-option, -X, -Y) + ld-option = $(call try-run, $(LD) $(KBUILD_LDFLAGS) $(1) -v,$(1),$(2),$(3)) diff --git a/queue-6.12/net-fix-checksum-update-for-ila-adj-transport.patch b/queue-6.12/net-fix-checksum-update-for-ila-adj-transport.patch new file mode 100644 index 00000000000..d3c2270889d --- /dev/null +++ b/queue-6.12/net-fix-checksum-update-for-ila-adj-transport.patch @@ -0,0 +1,157 @@ +From 6043b794c7668c19dabc4a93c75b924a19474d59 Mon Sep 17 00:00:00 2001 +From: Paul Chaignon <paul.chaignon@gmail.com> +Date: Thu, 29 May 2025 12:28:05 +0200 +Subject: net: Fix checksum update for ILA adj-transport + +From: Paul Chaignon <paul.chaignon@gmail.com> + +commit 6043b794c7668c19dabc4a93c75b924a19474d59 upstream. + +During ILA address translations, the L4 checksums can be handled in +different ways. One of them, adj-transport, consist in parsing the +transport layer and updating any found checksum. This logic relies on +inet_proto_csum_replace_by_diff and produces an incorrect skb->csum when +in state CHECKSUM_COMPLETE. + +This bug can be reproduced with a simple ILA to SIR mapping, assuming +packets are received with CHECKSUM_COMPLETE: + + $ ip a show dev eth0 + 14: eth0@if15: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 + link/ether 62:ae:35:9e:0f:8d brd ff:ff:ff:ff:ff:ff link-netnsid 0 + inet6 3333:0:0:1::c078/64 scope global + valid_lft forever preferred_lft forever + inet6 fd00:10:244:1::c078/128 scope global nodad + valid_lft forever preferred_lft forever + inet6 fe80::60ae:35ff:fe9e:f8d/64 scope link proto kernel_ll + valid_lft forever preferred_lft forever + $ ip ila add loc_match fd00:10:244:1 loc 3333:0:0:1 \ + csum-mode adj-transport ident-type luid dev eth0 + +Then I hit [fd00:10:244:1::c078]:8000 with a server listening only on +[3333:0:0:1::c078]:8000. With the bug, the SYN packet is dropped with +SKB_DROP_REASON_TCP_CSUM after inet_proto_csum_replace_by_diff changed +skb->csum. The translation and drop are visible on pwru [1] traces: + + IFACE TUPLE FUNC + eth0:9 [fd00:10:244:3::3d8]:51420->[fd00:10:244:1::c078]:8000(tcp) ipv6_rcv + eth0:9 [fd00:10:244:3::3d8]:51420->[fd00:10:244:1::c078]:8000(tcp) ip6_rcv_core + eth0:9 [fd00:10:244:3::3d8]:51420->[fd00:10:244:1::c078]:8000(tcp) nf_hook_slow + eth0:9 [fd00:10:244:3::3d8]:51420->[fd00:10:244:1::c078]:8000(tcp) inet_proto_csum_replace_by_diff + eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) tcp_v6_early_demux + eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) ip6_route_input + eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) ip6_input + eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) ip6_input_finish + eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) ip6_protocol_deliver_rcu + eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) raw6_local_deliver + eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) ipv6_raw_deliver + eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) tcp_v6_rcv + eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) __skb_checksum_complete + eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) kfree_skb_reason(SKB_DROP_REASON_TCP_CSUM) + eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) skb_release_head_state + eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) skb_release_data + eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) skb_free_head + eth0:9 [fd00:10:244:3::3d8]:51420->[3333:0:0:1::c078]:8000(tcp) kfree_skbmem + +This is happening because inet_proto_csum_replace_by_diff is updating +skb->csum when it shouldn't. The L4 checksum is updated such that it +"cancels" the IPv6 address change in terms of checksum computation, so +the impact on skb->csum is null. + +Note this would be different for an IPv4 packet since three fields +would be updated: the IPv4 address, the IP checksum, and the L4 +checksum. Two would cancel each other and skb->csum would still need +to be updated to take the L4 checksum change into account. + +This patch fixes it by passing an ipv6 flag to +inet_proto_csum_replace_by_diff, to skip the skb->csum update if we're +in the IPv6 case. Note the behavior of the only other user of +inet_proto_csum_replace_by_diff, the BPF subsystem, is left as is in +this patch and fixed in the subsequent patch. + +With the fix, using the reproduction from above, I can confirm +skb->csum is not touched by inet_proto_csum_replace_by_diff and the TCP +SYN proceeds to the application after the ILA translation. + +Link: https://github.com/cilium/pwru [1] +Fixes: 65d7ab8de582 ("net: Identifier Locator Addressing module") +Signed-off-by: Paul Chaignon <paul.chaignon@gmail.com> +Acked-by: Daniel Borkmann <daniel@iogearbox.net> +Link: https://patch.msgid.link/b5539869e3550d46068504feb02d37653d939c0b.1748509484.git.paul.chaignon@gmail.com +Signed-off-by: Jakub Kicinski <kuba@kernel.org> +Signed-off-by: Paul Chaignon <paul.chaignon@gmail.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + include/net/checksum.h | 2 +- + net/core/filter.c | 2 +- + net/core/utils.c | 4 ++-- + net/ipv6/ila/ila_common.c | 6 +++--- + 4 files changed, 7 insertions(+), 7 deletions(-) + +--- a/include/net/checksum.h ++++ b/include/net/checksum.h +@@ -158,7 +158,7 @@ void inet_proto_csum_replace16(__sum16 * + const __be32 *from, const __be32 *to, + bool pseudohdr); + void inet_proto_csum_replace_by_diff(__sum16 *sum, struct sk_buff *skb, +- __wsum diff, bool pseudohdr); ++ __wsum diff, bool pseudohdr, bool ipv6); + + static __always_inline + void inet_proto_csum_replace2(__sum16 *sum, struct sk_buff *skb, +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -1999,7 +1999,7 @@ BPF_CALL_5(bpf_l4_csum_replace, struct s + if (unlikely(from != 0)) + return -EINVAL; + +- inet_proto_csum_replace_by_diff(ptr, skb, to, is_pseudo); ++ inet_proto_csum_replace_by_diff(ptr, skb, to, is_pseudo, false); + break; + case 2: + inet_proto_csum_replace2(ptr, skb, from, to, is_pseudo); +--- a/net/core/utils.c ++++ b/net/core/utils.c +@@ -473,11 +473,11 @@ void inet_proto_csum_replace16(__sum16 * + EXPORT_SYMBOL(inet_proto_csum_replace16); + + void inet_proto_csum_replace_by_diff(__sum16 *sum, struct sk_buff *skb, +- __wsum diff, bool pseudohdr) ++ __wsum diff, bool pseudohdr, bool ipv6) + { + if (skb->ip_summed != CHECKSUM_PARTIAL) { + csum_replace_by_diff(sum, diff); +- if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr) ++ if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr && !ipv6) + skb->csum = ~csum_sub(diff, skb->csum); + } else if (pseudohdr) { + *sum = ~csum_fold(csum_add(diff, csum_unfold(*sum))); +--- a/net/ipv6/ila/ila_common.c ++++ b/net/ipv6/ila/ila_common.c +@@ -86,7 +86,7 @@ static void ila_csum_adjust_transport(st + + diff = get_csum_diff(ip6h, p); + inet_proto_csum_replace_by_diff(&th->check, skb, +- diff, true); ++ diff, true, true); + } + break; + case NEXTHDR_UDP: +@@ -97,7 +97,7 @@ static void ila_csum_adjust_transport(st + if (uh->check || skb->ip_summed == CHECKSUM_PARTIAL) { + diff = get_csum_diff(ip6h, p); + inet_proto_csum_replace_by_diff(&uh->check, skb, +- diff, true); ++ diff, true, true); + if (!uh->check) + uh->check = CSUM_MANGLED_0; + } +@@ -111,7 +111,7 @@ static void ila_csum_adjust_transport(st + + diff = get_csum_diff(ip6h, p); + inet_proto_csum_replace_by_diff(&ih->icmp6_cksum, skb, +- diff, true); ++ diff, true, true); + } + break; + } diff --git a/queue-6.12/nfsd-use-threads-array-as-is-in-netlink-interface.patch b/queue-6.12/nfsd-use-threads-array-as-is-in-netlink-interface.patch new file mode 100644 index 00000000000..96db7c38fc2 --- /dev/null +++ b/queue-6.12/nfsd-use-threads-array-as-is-in-netlink-interface.patch @@ -0,0 +1,58 @@ +From 8ea688a3372e8369dc04395b39b4e71a6d91d4d5 Mon Sep 17 00:00:00 2001 +From: Jeff Layton <jlayton@kernel.org> +Date: Tue, 27 May 2025 20:12:47 -0400 +Subject: nfsd: use threads array as-is in netlink interface + +From: Jeff Layton <jlayton@kernel.org> + +commit 8ea688a3372e8369dc04395b39b4e71a6d91d4d5 upstream. + +The old nfsdfs interface for starting a server with multiple pools +handles the special case of a single entry array passed down from +userland by distributing the threads over every NUMA node. + +The netlink control interface however constructs an array of length +nfsd_nrpools() and fills any unprovided slots with 0's. This behavior +defeats the special casing that the old interface relies on. + +Change nfsd_nl_threads_set_doit() to pass down the array from userland +as-is. + +Fixes: 7f5c330b2620 ("nfsd: allow passing in array of thread counts via netlink") +Cc: stable@vger.kernel.org +Reported-by: Mike Snitzer <snitzer@kernel.org> +Closes: https://lore.kernel.org/linux-nfs/aDC-ftnzhJAlwqwh@kernel.org/ +Signed-off-by: Jeff Layton <jlayton@kernel.org> +Reviewed-by: Simon Horman <horms@kernel.org> +Tested-by: Mike Snitzer <snitzer@kernel.org> +Signed-off-by: Chuck Lever <chuck.lever@oracle.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + fs/nfsd/nfsctl.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/fs/nfsd/nfsctl.c ++++ b/fs/nfsd/nfsctl.c +@@ -1653,7 +1653,7 @@ out_unlock: + */ + int nfsd_nl_threads_set_doit(struct sk_buff *skb, struct genl_info *info) + { +- int *nthreads, count = 0, nrpools, i, ret = -EOPNOTSUPP, rem; ++ int *nthreads, nrpools = 0, i, ret = -EOPNOTSUPP, rem; + struct net *net = genl_info_net(info); + struct nfsd_net *nn = net_generic(net, nfsd_net_id); + const struct nlattr *attr; +@@ -1665,12 +1665,11 @@ int nfsd_nl_threads_set_doit(struct sk_b + /* count number of SERVER_THREADS values */ + nlmsg_for_each_attr(attr, info->nlhdr, GENL_HDRLEN, rem) { + if (nla_type(attr) == NFSD_A_SERVER_THREADS) +- count++; ++ nrpools++; + } + + mutex_lock(&nfsd_mutex); + +- nrpools = max(count, nfsd_nrpools(net)); + nthreads = kcalloc(nrpools, sizeof(int), GFP_KERNEL); + if (!nthreads) { + ret = -ENOMEM; diff --git a/queue-6.12/rust-compile-libcore-with-edition-2024-for-1.87.patch b/queue-6.12/rust-compile-libcore-with-edition-2024-for-1.87.patch new file mode 100644 index 00000000000..2e92e28a2c5 --- /dev/null +++ b/queue-6.12/rust-compile-libcore-with-edition-2024-for-1.87.patch @@ -0,0 +1,169 @@ +From f4daa80d6be7d3c55ca72a8e560afc4e21f886aa Mon Sep 17 00:00:00 2001 +From: Gary Guo <gary@garyguo.net> +Date: Sat, 17 May 2025 09:55:59 +0100 +Subject: rust: compile libcore with edition 2024 for 1.87+ + +From: Gary Guo <gary@garyguo.net> + +commit f4daa80d6be7d3c55ca72a8e560afc4e21f886aa upstream. + +Rust 1.87 (released on 2025-05-15) compiles core library with edition +2024 instead of 2021 [1]. Ensure that the edition matches libcore's +expectation to avoid potential breakage. + +[ J3m3 reported in Zulip [2] that the `rust-analyzer` target was + broken after this patch -- indeed, we need to avoid `core-cfgs` + since those are passed to the `rust-analyzer` target. + + So, instead, I tweaked the patch to create a new `core-edition` + variable and explicitly mention the `--edition` flag instead of + reusing `core-cfg`s. + + In addition, pass a new argument using this new variable to + `generate_rust_analyzer.py` so that we set the right edition there. + + By the way, for future reference: the `filter-out` change is needed + for Rust < 1.87, since otherwise we would skip the `--edition=2021` + we just added, ending up with no edition flag, and thus the compiler + would default to the 2015 one. + + [2] https://rust-for-linux.zulipchat.com/#narrow/channel/291565/topic/x/near/520206547 + + - Miguel ] + +Cc: stable@vger.kernel.org # Needed in 6.12.y and later (Rust is pinned in older LTSs). +Link: https://github.com/rust-lang/rust/pull/138162 [1] +Reported-by: est31 <est31@protonmail.com> +Closes: https://github.com/Rust-for-Linux/linux/issues/1163 +Signed-off-by: Gary Guo <gary@garyguo.net> +Link: https://lore.kernel.org/r/20250517085600.2857460-1-gary@garyguo.net +Signed-off-by: Miguel Ojeda <ojeda@kernel.org> +[ Solved conflicts for 6.12.y backport. - Miguel ] +Signed-off-by: Miguel Ojeda <ojeda@kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + rust/Makefile | 14 ++++++++------ + scripts/generate_rust_analyzer.py | 13 ++++++++----- + 2 files changed, 16 insertions(+), 11 deletions(-) + +--- a/rust/Makefile ++++ b/rust/Makefile +@@ -53,6 +53,8 @@ endif + core-cfgs = \ + --cfg no_fp_fmt_parse + ++core-edition := $(if $(call rustc-min-version,108700),2024,2021) ++ + quiet_cmd_rustdoc = RUSTDOC $(if $(rustdoc_host),H, ) $< + cmd_rustdoc = \ + OBJTREE=$(abspath $(objtree)) \ +@@ -95,8 +97,8 @@ rustdoc-macros: $(src)/macros/lib.rs FOR + + # Starting with Rust 1.82.0, skipping `-Wrustdoc::unescaped_backticks` should + # not be needed -- see https://github.com/rust-lang/rust/pull/128307. +-rustdoc-core: private skip_flags = -Wrustdoc::unescaped_backticks +-rustdoc-core: private rustc_target_flags = $(core-cfgs) ++rustdoc-core: private skip_flags = --edition=2021 -Wrustdoc::unescaped_backticks ++rustdoc-core: private rustc_target_flags = --edition=$(core-edition) $(core-cfgs) + rustdoc-core: $(RUST_LIB_SRC)/core/src/lib.rs FORCE + +$(call if_changed,rustdoc) + +@@ -372,7 +374,7 @@ quiet_cmd_rustc_library = $(if $(skip_cl + cmd_rustc_library = \ + OBJTREE=$(abspath $(objtree)) \ + $(if $(skip_clippy),$(RUSTC),$(RUSTC_OR_CLIPPY)) \ +- $(filter-out $(skip_flags),$(rust_flags) $(rustc_target_flags)) \ ++ $(filter-out $(skip_flags),$(rust_flags)) $(rustc_target_flags) \ + --emit=dep-info=$(depfile) --emit=obj=$@ \ + --emit=metadata=$(dir $@)$(patsubst %.o,lib%.rmeta,$(notdir $@)) \ + --crate-type rlib -L$(objtree)/$(obj) \ +@@ -383,7 +385,7 @@ quiet_cmd_rustc_library = $(if $(skip_cl + + rust-analyzer: + $(Q)$(srctree)/scripts/generate_rust_analyzer.py \ +- --cfgs='core=$(core-cfgs)' \ ++ --cfgs='core=$(core-cfgs)' $(core-edition) \ + $(realpath $(srctree)) $(realpath $(objtree)) \ + $(rustc_sysroot) $(RUST_LIB_SRC) $(KBUILD_EXTMOD) > \ + $(if $(KBUILD_EXTMOD),$(extmod_prefix),$(objtree))/rust-project.json +@@ -407,9 +409,9 @@ define rule_rustc_library + endef + + $(obj)/core.o: private skip_clippy = 1 +-$(obj)/core.o: private skip_flags = -Wunreachable_pub ++$(obj)/core.o: private skip_flags = --edition=2021 -Wunreachable_pub + $(obj)/core.o: private rustc_objcopy = $(foreach sym,$(redirect-intrinsics),--redefine-sym $(sym)=__rust$(sym)) +-$(obj)/core.o: private rustc_target_flags = $(core-cfgs) ++$(obj)/core.o: private rustc_target_flags = --edition=$(core-edition) $(core-cfgs) + $(obj)/core.o: $(RUST_LIB_SRC)/core/src/lib.rs \ + $(wildcard $(objtree)/include/config/RUSTC_VERSION_TEXT) FORCE + +$(call if_changed_rule,rustc_library) +--- a/scripts/generate_rust_analyzer.py ++++ b/scripts/generate_rust_analyzer.py +@@ -18,7 +18,7 @@ def args_crates_cfgs(cfgs): + + return crates_cfgs + +-def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs): ++def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs, core_edition): + # Generate the configuration list. + cfg = [] + with open(objtree / "include" / "generated" / "rustc_cfg") as fd: +@@ -34,7 +34,7 @@ def generate_crates(srctree, objtree, sy + crates_indexes = {} + crates_cfgs = args_crates_cfgs(cfgs) + +- def append_crate(display_name, root_module, deps, cfg=[], is_workspace_member=True, is_proc_macro=False): ++ def append_crate(display_name, root_module, deps, cfg=[], is_workspace_member=True, is_proc_macro=False, edition="2021"): + crates_indexes[display_name] = len(crates) + crates.append({ + "display_name": display_name, +@@ -43,7 +43,7 @@ def generate_crates(srctree, objtree, sy + "is_proc_macro": is_proc_macro, + "deps": [{"crate": crates_indexes[dep], "name": dep} for dep in deps], + "cfg": cfg, +- "edition": "2021", ++ "edition": edition, + "env": { + "RUST_MODFILE": "This is only for rust-analyzer" + } +@@ -53,6 +53,7 @@ def generate_crates(srctree, objtree, sy + display_name, + deps, + cfg=[], ++ edition="2021", + ): + append_crate( + display_name, +@@ -60,12 +61,13 @@ def generate_crates(srctree, objtree, sy + deps, + cfg, + is_workspace_member=False, ++ edition=edition, + ) + + # NB: sysroot crates reexport items from one another so setting up our transitive dependencies + # here is important for ensuring that rust-analyzer can resolve symbols. The sources of truth + # for this dependency graph are `(sysroot_src / crate / "Cargo.toml" for crate in crates)`. +- append_sysroot_crate("core", [], cfg=crates_cfgs.get("core", [])) ++ append_sysroot_crate("core", [], cfg=crates_cfgs.get("core", []), edition=core_edition) + append_sysroot_crate("alloc", ["core"]) + append_sysroot_crate("std", ["alloc", "core"]) + append_sysroot_crate("proc_macro", ["core", "std"]) +@@ -155,6 +157,7 @@ def main(): + parser = argparse.ArgumentParser() + parser.add_argument('--verbose', '-v', action='store_true') + parser.add_argument('--cfgs', action='append', default=[]) ++ parser.add_argument("core_edition") + parser.add_argument("srctree", type=pathlib.Path) + parser.add_argument("objtree", type=pathlib.Path) + parser.add_argument("sysroot", type=pathlib.Path) +@@ -171,7 +174,7 @@ def main(): + assert args.sysroot in args.sysroot_src.parents + + rust_project = { +- "crates": generate_crates(args.srctree, args.objtree, args.sysroot_src, args.exttree, args.cfgs), ++ "crates": generate_crates(args.srctree, args.objtree, args.sysroot_src, args.exttree, args.cfgs, args.core_edition), + "sysroot": str(args.sysroot), + } + diff --git a/queue-6.12/series b/queue-6.12/series index 23183914f61..8ed3ff77d86 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -337,3 +337,11 @@ alsa-hda-realtek-add-quirk-for-asus-gu605c.patch iio-accel-fxls8962af-fix-temperature-calculation.patch mm-hugetlb-unshare-page-tables-during-vma-split-not-before.patch drm-amdgpu-read-back-register-after-written-for-vcn-v4.0.5.patch +kbuild-rust-add-rustc-min-version-support-function.patch +rust-compile-libcore-with-edition-2024-for-1.87.patch +net-fix-checksum-update-for-ila-adj-transport.patch +bpf-fix-l4-csum-update-on-ipv6-in-checksum_complete.patch +erofs-remove-unused-trace-event-erofs_destroy_inode.patch +nfsd-use-threads-array-as-is-in-netlink-interface.patch +sunrpc-handle-svc_garbage-during-svc-auth-processing-as-auth-error.patch +drm-v3d-avoid-null-pointer-dereference-in-v3d_job_update_stats.patch diff --git a/queue-6.12/sunrpc-handle-svc_garbage-during-svc-auth-processing-as-auth-error.patch b/queue-6.12/sunrpc-handle-svc_garbage-during-svc-auth-processing-as-auth-error.patch new file mode 100644 index 00000000000..afc0b8c208d --- /dev/null +++ b/queue-6.12/sunrpc-handle-svc_garbage-during-svc-auth-processing-as-auth-error.patch @@ -0,0 +1,67 @@ +From 94d10a4dba0bc482f2b01e39f06d5513d0f75742 Mon Sep 17 00:00:00 2001 +From: Jeff Layton <jlayton@kernel.org> +Date: Thu, 19 Jun 2025 06:01:55 -0400 +Subject: sunrpc: handle SVC_GARBAGE during svc auth processing as auth error + +From: Jeff Layton <jlayton@kernel.org> + +commit 94d10a4dba0bc482f2b01e39f06d5513d0f75742 upstream. + +tianshuo han reported a remotely-triggerable crash if the client sends a +kernel RPC server a specially crafted packet. If decoding the RPC reply +fails in such a way that SVC_GARBAGE is returned without setting the +rq_accept_statp pointer, then that pointer can be dereferenced and a +value stored there. + +If it's the first time the thread has processed an RPC, then that +pointer will be set to NULL and the kernel will crash. In other cases, +it could create a memory scribble. + +The server sunrpc code treats a SVC_GARBAGE return from svc_authenticate +or pg_authenticate as if it should send a GARBAGE_ARGS reply. RFC 5531 +says that if authentication fails that the RPC should be rejected +instead with a status of AUTH_ERR. + +Handle a SVC_GARBAGE return as an AUTH_ERROR, with a reason of +AUTH_BADCRED instead of returning GARBAGE_ARGS in that case. This +sidesteps the whole problem of touching the rpc_accept_statp pointer in +this situation and avoids the crash. + +Cc: stable@kernel.org +Fixes: 29cd2927fb91 ("SUNRPC: Fix encoding of accepted but unsuccessful RPC replies") +Reported-by: tianshuo han <hantianshuo233@gmail.com> +Reviewed-by: Chuck Lever <chuck.lever@oracle.com> +Signed-off-by: Jeff Layton <jlayton@kernel.org> +Signed-off-by: Chuck Lever <chuck.lever@oracle.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + net/sunrpc/svc.c | 11 ++--------- + 1 file changed, 2 insertions(+), 9 deletions(-) + +--- a/net/sunrpc/svc.c ++++ b/net/sunrpc/svc.c +@@ -1369,7 +1369,8 @@ svc_process_common(struct svc_rqst *rqst + case SVC_OK: + break; + case SVC_GARBAGE: +- goto err_garbage_args; ++ rqstp->rq_auth_stat = rpc_autherr_badcred; ++ goto err_bad_auth; + case SVC_SYSERR: + goto err_system_err; + case SVC_DENIED: +@@ -1510,14 +1511,6 @@ err_bad_proc: + *rqstp->rq_accept_statp = rpc_proc_unavail; + goto sendit; + +-err_garbage_args: +- svc_printk(rqstp, "failed to decode RPC header\n"); +- +- if (serv->sv_stats) +- serv->sv_stats->rpcbadfmt++; +- *rqstp->rq_accept_statp = rpc_garbage_args; +- goto sendit; +- + err_system_err: + if (serv->sv_stats) + serv->sv_stats->rpcbadfmt++; |