From: Greg Kroah-Hartman Date: Tue, 14 Jul 2026 15:55:54 +0000 (+0200) Subject: 7.1-stable patches X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cec501e802426cb4601edddf531ccc63174d5437;p=thirdparty%2Fkernel%2Fstable-queue.git 7.1-stable patches added patches: bpf-allow-lpm-map-access-from-sleepable-bpf-programs.patch bpf-keep-dynamic-inner-array-lookups-nullable.patch bpf-reject-fragmented-frames-in-devmap.patch bpf-restore-sysctl-new-value-from-1-to-0.patch bpf-validate-btf-repeated-field-counts-before-expansion.patch hfs-hfsplus-fix-u32-overflow-in-check_and_correct_requested_length.patch hfs-hfsplus-zero-initialize-buffer-in-hfs_bnode_read.patch media-mtk-jpeg-cancel-workqueue-on-release-for-supported-platforms-only.patch nilfs2-reject-clean_segments-ioctl-with-out-of-range-segment-numbers.patch serial-8250_mid-disable-dma-for-selected-platforms.patch xfs-fix-exchmaps-reservation-limit-check.patch xfs-fix-memory-leak-in-xfs_dqinode_metadir_create.patch xfs-fix-pointer-arithmetic-error-on-32-bit-systems.patch xfs-fix-unreachable-bigtime-check-in-dquot-flush-validation.patch xfs-initialize-iomap-flags-earlier-in-xfs_bmbt_to_iomap.patch xfs-only-log-freed-extents-for-the-current-rtg-in-zoned-growfs.patch xfs-pass-back-updated-nb-from-xfs_growfs_compute_deltas.patch xfs-release-dquot-buffer-after-dqflush-failure.patch xfs-use-null-daddr-for-unset-first-bad-log-block.patch --- diff --git a/queue-7.1/bpf-allow-lpm-map-access-from-sleepable-bpf-programs.patch b/queue-7.1/bpf-allow-lpm-map-access-from-sleepable-bpf-programs.patch new file mode 100644 index 0000000000..72869c0385 --- /dev/null +++ b/queue-7.1/bpf-allow-lpm-map-access-from-sleepable-bpf-programs.patch @@ -0,0 +1,114 @@ +From 2f884d371fafea137afea504d49ee4a7c8d7985b Mon Sep 17 00:00:00 2001 +From: Vlad Poenaru +Date: Tue, 9 Jun 2026 06:55:57 -0700 +Subject: bpf: Allow LPM map access from sleepable BPF programs + +From: Vlad Poenaru + +commit 2f884d371fafea137afea504d49ee4a7c8d7985b upstream. + +trie_lookup_elem() annotates its rcu_dereference_check() walks with +only rcu_read_lock_bh_held(). Because rcu_dereference_check(p, c) +resolves to "c || rcu_read_lock_held()", this passes for XDP/NAPI and +classic RCU readers but fails for sleepable BPF programs, which enter +via __bpf_prog_enter_sleepable() and hold only rcu_read_lock_trace(). + +trie_update_elem() and trie_delete_elem() have the same problem in a +different form: they walk the trie with plain rcu_dereference(), which +asserts rcu_read_lock_held() unconditionally. Both are reachable from +sleepable BPF programs via the bpf_map_update_elem / bpf_map_delete_elem +helpers, and from the syscall path under classic rcu_read_lock(). In +the writer paths the trie is actually protected by trie->lock (an +rqspinlock taken across the walk); we never relied on the RCU read-side +lock to keep nodes alive there. + +A sleepable LSM hook that ends up touching an LPM trie therefore +triggers lockdep on debug kernels: + + ============================= + WARNING: suspicious RCU usage + 7.1.0-... Tainted: G E + ----------------------------- + kernel/bpf/lpm_trie.c:249 suspicious rcu_dereference_check() usage! + 1 lock held by net_tests/540: + #0: (rcu_tasks_trace_srcu_struct){....}-{0:0}, + at: __bpf_prog_enter_sleepable+0x26/0x280 + Call Trace: + dump_stack_lvl + lockdep_rcu_suspicious + trie_lookup_elem + bpf_prog_..._enforce_security_socket_connect + bpf_trampoline_... + security_socket_connect + __sys_connect + do_syscall_64 + +This is lockdep-only -- no UAF, since Tasks Trace RCU does serialize +against the trie's reclaim path -- but it spams the console once per +distinct callsite on every debug kernel running a sleepable BPF LSM +that touches an LPM trie, which is increasingly common. + +For the lookup path, switch the rcu_dereference_check() annotation +from rcu_read_lock_bh_held() to bpf_rcu_lock_held(), which accepts all +three contexts (classic, BH, Tasks Trace). Other map types already +follow this convention. + +For trie_update_elem() and trie_delete_elem(), annotate the walks as +rcu_dereference_protected(*p, 1) -- matching trie_free() in the same +file -- since trie->lock is held across the walk. rqspinlock has no +lockdep_map, so the predicate degenerates to '1' rather than +lockdep_is_held(&trie->lock); the protection is real but not +machine-verifiable. trie_get_next_key() also uses bare +rcu_dereference() but is reachable only from the BPF syscall, which +holds classic rcu_read_lock() before dispatching, so it is left +untouched. + +Fixes: 694cea395fde ("bpf: Allow RCU-protected lookups to happen from bh context") +Cc: stable@vger.kernel.org +Signed-off-by: Vlad Poenaru +Reviewed-by: Emil Tsalapatis +Link: https://lore.kernel.org/r/20260609135558.193287-2-vlad.wing@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Greg Kroah-Hartman +--- + kernel/bpf/lpm_trie.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/kernel/bpf/lpm_trie.c ++++ b/kernel/bpf/lpm_trie.c +@@ -246,7 +246,7 @@ static void *trie_lookup_elem(struct bpf + + /* Start walking the trie from the root node ... */ + +- for (node = rcu_dereference_check(trie->root, rcu_read_lock_bh_held()); ++ for (node = rcu_dereference_check(trie->root, bpf_rcu_lock_held()); + node;) { + unsigned int next_bit; + size_t matchlen; +@@ -280,7 +280,7 @@ static void *trie_lookup_elem(struct bpf + */ + next_bit = extract_bit(key->data, node->prefixlen); + node = rcu_dereference_check(node->child[next_bit], +- rcu_read_lock_bh_held()); ++ bpf_rcu_lock_held()); + } + + if (!found) +@@ -359,7 +359,7 @@ static long trie_update_elem(struct bpf_ + */ + slot = &trie->root; + +- while ((node = rcu_dereference(*slot))) { ++ while ((node = rcu_dereference_protected(*slot, 1))) { + matchlen = longest_prefix_match(trie, node, key); + + if (node->prefixlen != matchlen || +@@ -482,7 +482,7 @@ static long trie_delete_elem(struct bpf_ + trim = &trie->root; + trim2 = trim; + parent = NULL; +- while ((node = rcu_dereference(*trim))) { ++ while ((node = rcu_dereference_protected(*trim, 1))) { + matchlen = longest_prefix_match(trie, node, key); + + if (node->prefixlen != matchlen || diff --git a/queue-7.1/bpf-keep-dynamic-inner-array-lookups-nullable.patch b/queue-7.1/bpf-keep-dynamic-inner-array-lookups-nullable.patch new file mode 100644 index 0000000000..e07affb9b3 --- /dev/null +++ b/queue-7.1/bpf-keep-dynamic-inner-array-lookups-nullable.patch @@ -0,0 +1,83 @@ +From 53040a81ae57cdca8af8ac36fe4e661730cf7c6b Mon Sep 17 00:00:00 2001 +From: Nuoqi Gui +Date: Sun, 7 Jun 2026 21:24:13 +0800 +Subject: bpf: Keep dynamic inner array lookups nullable + +From: Nuoqi Gui + +commit 53040a81ae57cdca8af8ac36fe4e661730cf7c6b upstream. + +An ARRAY_OF_MAPS can use an array created with BPF_F_INNER_MAP as its +inner map template. A concrete inner array with a different max_entries +value can then replace the template. + +After a successful outer map lookup, the verifier represents the +resulting map pointer using the inner map template. Const-key lookup +nullness elision consequently uses the template max_entries even though +the runtime helper uses the concrete inner map max_entries. + +Do not elide lookup result nullness for maps marked with BPF_F_INNER_MAP, +because the template max_entries does not prove that the key is in bounds +for the concrete runtime map. + +Fixes: d2102f2f5d75 ("bpf: verifier: Support eliding map lookup nullness") +Signed-off-by: Nuoqi Gui +Acked-by: Eduard Zingerman +Acked-by: Jiri Olsa +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/bpf/20260607-f01-v2-v2-1-da48453146e8@mails.tsinghua.edu.cn +Signed-off-by: Kumar Kartikeya Dwivedi +Signed-off-by: Greg Kroah-Hartman +--- + kernel/bpf/verifier.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -8471,7 +8471,7 @@ static int get_constant_map_key(struct b + return 0; + } + +-static bool can_elide_value_nullness(enum bpf_map_type type); ++static bool can_elide_value_nullness(const struct bpf_map *map); + + static int check_func_arg(struct bpf_verifier_env *env, u32 arg, + struct bpf_call_arg_meta *meta, +@@ -8621,7 +8621,7 @@ skip_type_check: + err = check_helper_mem_access(env, regno, key_size, BPF_READ, false, NULL); + if (err) + return err; +- if (can_elide_value_nullness(meta->map.ptr->map_type)) { ++ if (can_elide_value_nullness(meta->map.ptr)) { + err = get_constant_map_key(env, reg, key_size, &meta->const_map_key); + if (err < 0) { + meta->const_map_key = -1; +@@ -10221,13 +10221,16 @@ static void update_loop_inline_state(str + state->callback_subprogno == subprogno); + } + +-/* Returns whether or not the given map type can potentially elide ++/* Returns whether or not the given map can potentially elide + * lookup return value nullness check. This is possible if the key + * is statically known. + */ +-static bool can_elide_value_nullness(enum bpf_map_type type) ++static bool can_elide_value_nullness(const struct bpf_map *map) + { +- switch (type) { ++ if (map->map_flags & BPF_F_INNER_MAP) ++ return false; ++ ++ switch (map->map_type) { + case BPF_MAP_TYPE_ARRAY: + case BPF_MAP_TYPE_PERCPU_ARRAY: + return true; +@@ -10589,7 +10592,7 @@ static int check_helper_call(struct bpf_ + } + + if (func_id == BPF_FUNC_map_lookup_elem && +- can_elide_value_nullness(meta.map.ptr->map_type) && ++ can_elide_value_nullness(meta.map.ptr) && + meta.const_map_key >= 0 && + meta.const_map_key < meta.map.ptr->max_entries) + ret_flag &= ~PTR_MAYBE_NULL; diff --git a/queue-7.1/bpf-reject-fragmented-frames-in-devmap.patch b/queue-7.1/bpf-reject-fragmented-frames-in-devmap.patch new file mode 100644 index 0000000000..de9601f620 --- /dev/null +++ b/queue-7.1/bpf-reject-fragmented-frames-in-devmap.patch @@ -0,0 +1,69 @@ +From aa496720618f1a6054f1c870bf10b4f6c99bf656 Mon Sep 17 00:00:00 2001 +From: Zhao Zhang +Date: Tue, 2 Jun 2026 16:43:33 +0800 +Subject: bpf: Reject fragmented frames in devmap +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Zhao Zhang + +commit aa496720618f1a6054f1c870bf10b4f6c99bf656 upstream. + +Devmap broadcast redirects clone the packet for all but the last +destination. + +For native XDP, that clone path copies only the linear xdp_frame data, +while fragmented frames keep skb_shared_info in tailroom outside the +linear area. Cloning such a frame leaves XDP_FLAGS_HAS_FRAGS set but +without valid frag metadata, and the later free path can interpret +uninitialized tail data as skb_shared_info, leading to an out-of-bounds +access during frame return. + +Reject fragmented native XDP frames in dev_map_enqueue_clone(). + +Add the same restriction to the generic XDP clone path in +dev_map_redirect_clone(). Generic XDP represents fragmented packets as +nonlinear skbs, and rejecting them here keeps clone-based broadcast +support aligned between native and generic XDP. + +Fixes: e624d4ed4aa8 ("xdp: Extend xdp_redirect_map with broadcast support") +Cc: stable@kernel.org +Reported-by: Yuan Tan +Reported-by: Zhengchuan Liang +Reported-by: Xin Liu +Assisted-by: Codex:GPT-5.4 +Signed-off-by: Zhao Zhang +Signed-off-by: Ren Wei +Reviewed-by: Emil Tsalapatis +Reviewed-by: Toke Høiland-Jørgensen +Link: https://lore.kernel.org/r/21c2d153dd25603d359069a02bf06779b51f6423.1780385378.git.zzhan461@ucr.edu +Signed-off-by: Alexei Starovoitov +Signed-off-by: Greg Kroah-Hartman +--- + kernel/bpf/devmap.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/kernel/bpf/devmap.c ++++ b/kernel/bpf/devmap.c +@@ -581,6 +581,10 @@ static int dev_map_enqueue_clone(struct + { + struct xdp_frame *nxdpf; + ++ /* Frags live outside the linear frame and cannot be cloned safely. */ ++ if (unlikely(xdp_frame_has_frags(xdpf))) ++ return -EOPNOTSUPP; ++ + nxdpf = xdpf_clone(xdpf); + if (!nxdpf) + return -ENOMEM; +@@ -726,6 +730,9 @@ static int dev_map_redirect_clone(struct + struct sk_buff *nskb; + int err; + ++ if (unlikely(skb_is_nonlinear(skb))) ++ return -EOPNOTSUPP; ++ + nskb = skb_clone(skb, GFP_ATOMIC); + if (!nskb) + return -ENOMEM; diff --git a/queue-7.1/bpf-restore-sysctl-new-value-from-1-to-0.patch b/queue-7.1/bpf-restore-sysctl-new-value-from-1-to-0.patch new file mode 100644 index 0000000000..e7529fa7f9 --- /dev/null +++ b/queue-7.1/bpf-restore-sysctl-new-value-from-1-to-0.patch @@ -0,0 +1,52 @@ +From 2566c3b24219c5b30e35205cba029ff34ff7c78b Mon Sep 17 00:00:00 2001 +From: Dawei Feng +Date: Wed, 3 Jun 2026 18:53:17 +0800 +Subject: bpf: Restore sysctl new-value from 1 to 0 + +From: Dawei Feng + +commit 2566c3b24219c5b30e35205cba029ff34ff7c78b upstream. + +Commit 4e63acdff864 ("bpf: Introduce bpf_sysctl_{get,set}_new_value +helpers") changed the success return value to 0, but failed to update the +corresponding check in __cgroup_bpf_run_filter_sysctl(). Since +bpf_prog_run_array_cg() now returns 0 on success, the legacy ret == 1 +condition is never satisfied. As a result, the modified value is ignored, +and bpf_sysctl_set_new_value() fails to replace the write buffer. + +Fix this by checking for a return value of 0 instead, so cgroup/sysctl +programs can correctly replace the pending sysctl buffer. + +This bug was discovered during a manual code review. Tested via a +cgroup/sysctl BPF reproducer overriding writes to a target sysctl. +Pre-fix, bpf_sysctl_set_new_value("foo") was silently ignored: the write +returned 8192 and the value remained "600". Post-fix, the BPF replacement +buffer properly propagates: the write returns 3 and the value updates to +"foo". + +Fixes: f10d05966196 ("bpf: Make BPF_PROG_RUN_ARRAY return -err instead of allow boolean") +Cc: stable@vger.kernel.org + +Acked-by: Yonghong Song +Signed-off-by: Zilin Guan +Signed-off-by: Dawei Feng +Reviewed-by: Jiayuan Chen +Acked-by: Xu Kuohai +Link: https://lore.kernel.org/r/20260603105317.944304-4-dawei.feng@seu.edu.cn +Signed-off-by: Alexei Starovoitov +Signed-off-by: Greg Kroah-Hartman +--- + kernel/bpf/cgroup.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/kernel/bpf/cgroup.c ++++ b/kernel/bpf/cgroup.c +@@ -1935,7 +1935,7 @@ int __cgroup_bpf_run_filter_sysctl(struc + + kfree(ctx.cur_val); + +- if (ret == 1 && ctx.new_updated) { ++ if (!ret && ctx.new_updated) { + kvfree(*buf); + *buf = ctx.new_val; + *pcount = ctx.new_len; diff --git a/queue-7.1/bpf-validate-btf-repeated-field-counts-before-expansion.patch b/queue-7.1/bpf-validate-btf-repeated-field-counts-before-expansion.patch new file mode 100644 index 0000000000..c8be4e8208 --- /dev/null +++ b/queue-7.1/bpf-validate-btf-repeated-field-counts-before-expansion.patch @@ -0,0 +1,58 @@ +From b9452b594fd3aecbfd4aa0a6a1f741330a37dab7 Mon Sep 17 00:00:00 2001 +From: Paul Moses +Date: Fri, 5 Jun 2026 23:43:09 +0000 +Subject: bpf: Validate BTF repeated field counts before expansion + +From: Paul Moses + +commit b9452b594fd3aecbfd4aa0a6a1f741330a37dab7 upstream. + +btf_parse_struct_metas() walks user-supplied BTF during BPF_BTF_LOAD, +and btf_repeat_fields() expands repeatable fields from array elements +into the fixed BTF_FIELDS_MAX scratch array used by btf_parse_fields(). + +The remaining-capacity check performs the expanded field count calculation +in u32. A malformed BTF can wrap that calculation, causing the check to +pass even when the expanded field count exceeds the scratch array +capacity. The following memcpy() can then write past the end of the +array. + +Use checked addition and multiplication before copying repeated fields +and reject impossible counts. + +Fixes: 797d73ee232d ("bpf: Check the remaining info_cnt before repeating btf fields") +Cc: stable@vger.kernel.org +Signed-off-by: Paul Moses +Acked-by: Eduard Zingerman +Link: https://lore.kernel.org/bpf/20260605234301.1109063-1-p@1g4.org +Signed-off-by: Kumar Kartikeya Dwivedi +Signed-off-by: Greg Kroah-Hartman +--- + kernel/bpf/btf.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +--- a/kernel/bpf/btf.c ++++ b/kernel/bpf/btf.c +@@ -3668,7 +3668,7 @@ end: + static int btf_repeat_fields(struct btf_field_info *info, int info_cnt, + u32 field_cnt, u32 repeat_cnt, u32 elem_size) + { +- u32 i, j; ++ u32 i, j, total_cnt, total_repeats; + u32 cur; + + /* Ensure not repeating fields that should not be repeated. */ +@@ -3686,10 +3686,9 @@ static int btf_repeat_fields(struct btf_ + } + } + +- /* The type of struct size or variable size is u32, +- * so the multiplication will not overflow. +- */ +- if (field_cnt * (repeat_cnt + 1) > info_cnt) ++ if (check_add_overflow(repeat_cnt, 1, &total_repeats) || ++ check_mul_overflow(field_cnt, total_repeats, &total_cnt) || ++ total_cnt > (u32)info_cnt) + return -E2BIG; + + cur = field_cnt; diff --git a/queue-7.1/hfs-hfsplus-fix-u32-overflow-in-check_and_correct_requested_length.patch b/queue-7.1/hfs-hfsplus-fix-u32-overflow-in-check_and_correct_requested_length.patch new file mode 100644 index 0000000000..dd2f079e48 --- /dev/null +++ b/queue-7.1/hfs-hfsplus-fix-u32-overflow-in-check_and_correct_requested_length.patch @@ -0,0 +1,65 @@ +From 966cb76fb2857a4242cab6ea2ea17acf818a3da7 Mon Sep 17 00:00:00 2001 +From: Tristan Madani +Date: Tue, 5 May 2026 11:12:58 +0000 +Subject: hfs/hfsplus: fix u32 overflow in check_and_correct_requested_length + +From: Tristan Madani + +commit 966cb76fb2857a4242cab6ea2ea17acf818a3da7 upstream. + +check_and_correct_requested_length() compares (off + len) against +node_size using u32 arithmetic. When the caller passes a large len +value (e.g. from an underflowed subtraction in hfs_brec_remove()), +off + len can wrap past 2^32 and produce a small result, causing the +bounds check to pass when it should fail. + +For example, with off=14 and len=0xFFFFFFF2 (underflowed from +data_off - keyoffset - size in hfs_brec_remove), off + len wraps to 6, +which is less than a typical node_size of 512, so the check passes and +the subsequent memmove reads ~4GB past the node buffer. + +Fix this by widening the addition to u64 before comparing against +node_size. This prevents the u32 wrap while keeping the logic +straightforward. + +Reported-by: syzbot+6df204b70bf3261691c5@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=6df204b70bf3261691c5 +Tested-by: syzbot+6df204b70bf3261691c5@syzkaller.appspotmail.com +Reported-by: syzbot+e76bf3d19b85350571ac@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=e76bf3d19b85350571ac +Tested-by: syzbot+e76bf3d19b85350571ac@syzkaller.appspotmail.com +Fixes: a431930c9bac ("hfs: fix slab-out-of-bounds in hfs_bnode_read()") +Cc: stable@vger.kernel.org +Signed-off-by: Tristan Madani +Reviewed-by: Viacheslav Dubeyko +Signed-off-by: Viacheslav Dubeyko +Link: https://lore.kernel.org/r/20260505111300.3592757-2-tristmd@gmail.com +Signed-off-by: Viacheslav Dubeyko +Signed-off-by: Greg Kroah-Hartman +--- + fs/hfs/bnode.c | 2 +- + fs/hfsplus/hfsplus_fs.h | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/fs/hfs/bnode.c ++++ b/fs/hfs/bnode.c +@@ -41,7 +41,7 @@ u32 check_and_correct_requested_length(s + + node_size = node->tree->node_size; + +- if ((off + len) > node_size) { ++ if ((u64)off + len > node_size) { + u32 new_len = node_size - off; + + pr_err("requested length has been corrected: " +--- a/fs/hfsplus/hfsplus_fs.h ++++ b/fs/hfsplus/hfsplus_fs.h +@@ -600,7 +600,7 @@ u32 check_and_correct_requested_length(s + + node_size = node->tree->node_size; + +- if ((off + len) > node_size) { ++ if ((u64)off + len > node_size) { + u32 new_len = node_size - off; + + pr_err("requested length has been corrected: " diff --git a/queue-7.1/hfs-hfsplus-zero-initialize-buffer-in-hfs_bnode_read.patch b/queue-7.1/hfs-hfsplus-zero-initialize-buffer-in-hfs_bnode_read.patch new file mode 100644 index 0000000000..2177946c88 --- /dev/null +++ b/queue-7.1/hfs-hfsplus-zero-initialize-buffer-in-hfs_bnode_read.patch @@ -0,0 +1,58 @@ +From d67aadee19ffdf3cc8520c5a4f4d5b2916d30baf Mon Sep 17 00:00:00 2001 +From: Tristan Madani +Date: Tue, 5 May 2026 11:12:59 +0000 +Subject: hfs/hfsplus: zero-initialize buffer in hfs_bnode_read + +From: Tristan Madani + +commit d67aadee19ffdf3cc8520c5a4f4d5b2916d30baf upstream. + +hfs_bnode_read() can return early without writing to the output buffer +when is_bnode_offset_valid() fails or when check_and_correct_requested_ +length() corrects the length to zero. Callers such as hfs_bnode_read_ +u16() and hfs_bnode_read_u8() pass stack-allocated buffers and use the +result unconditionally, leading to KMSAN uninit-value reports. + +Rather than initializing at each individual call site, zero the buffer +at the start of hfs_bnode_read() before any validation checks. This +ensures all callers in both hfs and hfsplus get a deterministic zero +value regardless of which early-return path is taken. + +Reported-by: syzbot+217eb327242d08197efb@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=217eb327242d08197efb +Tested-by: syzbot+217eb327242d08197efb@syzkaller.appspotmail.com +Fixes: a431930c9bac ("hfs: fix slab-out-of-bounds in hfs_bnode_read()") +Cc: stable@vger.kernel.org +Signed-off-by: Tristan Madani +Reviewed-by: Viacheslav Dubeyko +Signed-off-by: Viacheslav Dubeyko +Link: https://lore.kernel.org/r/20260505111300.3592757-3-tristmd@gmail.com +Signed-off-by: Viacheslav Dubeyko +Signed-off-by: Greg Kroah-Hartman +--- + fs/hfs/bnode.c | 2 ++ + fs/hfsplus/bnode.c | 2 ++ + 2 files changed, 4 insertions(+) + +--- a/fs/hfs/bnode.c ++++ b/fs/hfs/bnode.c +@@ -64,6 +64,8 @@ void hfs_bnode_read(struct hfs_bnode *no + u32 bytes_read; + u32 bytes_to_read; + ++ memset(buf, 0, len); ++ + if (!is_bnode_offset_valid(node, off)) + return; + +--- a/fs/hfsplus/bnode.c ++++ b/fs/hfsplus/bnode.c +@@ -25,6 +25,8 @@ void hfs_bnode_read(struct hfs_bnode *no + struct page **pagep; + u32 l; + ++ memset(buf, 0, len); ++ + if (!is_bnode_offset_valid(node, off)) + return; + diff --git a/queue-7.1/media-mtk-jpeg-cancel-workqueue-on-release-for-supported-platforms-only.patch b/queue-7.1/media-mtk-jpeg-cancel-workqueue-on-release-for-supported-platforms-only.patch new file mode 100644 index 0000000000..d354eadf62 --- /dev/null +++ b/queue-7.1/media-mtk-jpeg-cancel-workqueue-on-release-for-supported-platforms-only.patch @@ -0,0 +1,48 @@ +From b1845a227fda37b2fe5327df3ca0015d7e290235 Mon Sep 17 00:00:00 2001 +From: Louis-Alexis Eyraud +Date: Wed, 1 Apr 2026 11:44:15 +0200 +Subject: media: mtk-jpeg: cancel workqueue on release for supported platforms only + +From: Louis-Alexis Eyraud + +commit b1845a227fda37b2fe5327df3ca0015d7e290235 upstream. + +Since a recent fix the mtk_jpeg_release function cancels any pending +or running work present in the driver workqueue using +cancel_work_sync function. +Currently, only the multicore based variants use this workqueue and they +have the jpeg_worker platform data field initialized with a workqueue +callback function. For the others, this field value remain NULL by +default. +The cancel_work_sync function is unconditionally called in +mtk_jpeg_release function, even for the variants that do not use the +workqueue. This call generates a WARN_ON print in __flush_work because +the workqueue callback function presence check fails in __flush_work +function (used by cancel_work_sync). + +So, to avoid these warnings, call cancel_work_sync only if a workqueue +callback is defined in platform data. + +Fixes: 34c519feef3e ("media: mtk-jpeg: fix use-after-free in release path due to uncancelled work") +Cc: stable@vger.kernel.org +Signed-off-by: Louis-Alexis Eyraud +Reviewed-by: Nicolas Dufresne +Signed-off-by: Nicolas Dufresne +Signed-off-by: Hans Verkuil +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c ++++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c +@@ -1202,7 +1202,8 @@ static int mtk_jpeg_release(struct file + struct mtk_jpeg_dev *jpeg = video_drvdata(file); + struct mtk_jpeg_ctx *ctx = mtk_jpeg_file_to_ctx(file); + +- cancel_work_sync(&ctx->jpeg_work); ++ if (jpeg->variant->jpeg_worker) ++ cancel_work_sync(&ctx->jpeg_work); + mutex_lock(&jpeg->lock); + v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); + v4l2_ctrl_handler_free(&ctx->ctrl_hdl); diff --git a/queue-7.1/nilfs2-reject-clean_segments-ioctl-with-out-of-range-segment-numbers.patch b/queue-7.1/nilfs2-reject-clean_segments-ioctl-with-out-of-range-segment-numbers.patch new file mode 100644 index 0000000000..f135166c9d --- /dev/null +++ b/queue-7.1/nilfs2-reject-clean_segments-ioctl-with-out-of-range-segment-numbers.patch @@ -0,0 +1,114 @@ +From 0e7a690fe435f8d5ea3feb7c1d8d73ba7e8b8aa9 Mon Sep 17 00:00:00 2001 +From: Deepanshu Kartikey +Date: Sun, 3 May 2026 13:33:29 +0900 +Subject: nilfs2: reject CLEAN_SEGMENTS ioctl with out-of-range segment numbers + +From: Deepanshu Kartikey + +commit 0e7a690fe435f8d5ea3feb7c1d8d73ba7e8b8aa9 upstream. + +Syzbot reported a hung task in nilfs_transaction_begin() where multiple +tasks performing chmod() on a nilfs2 mount blocked for over 143 seconds +waiting to acquire ns_segctor_sem for read: + + INFO: task syz.0.17:5918 blocked for more than 143 seconds. + Call Trace: + schedule+0x164/0x360 + rwsem_down_read_slowpath+0x6d9/0x940 + down_read+0x99/0x2e0 + nilfs_transaction_begin+0x364/0x710 fs/nilfs2/segment.c:221 + nilfs_setattr+0x124/0x2c0 fs/nilfs2/inode.c:921 + notify_change+0xc1a/0xf40 + chmod_common+0x273/0x4a0 + do_fchmodat+0x12d/0x230 + +The writer holding ns_segctor_sem was a concurrent +NILFS_IOCTL_CLEAN_SEGMENTS caller, stuck inside printk while emitting +per-element warnings from nilfs_sufile_updatev(): + + __nilfs_msg+0x373/0x450 fs/nilfs2/super.c:78 + nilfs_sufile_updatev+0x21c/0x6d0 fs/nilfs2/sufile.c:186 + nilfs_sufile_freev fs/nilfs2/sufile.h:93 [inline] + nilfs_free_segments fs/nilfs2/segment.c:1140 [inline] + nilfs_segctor_collect_blocks fs/nilfs2/segment.c:1261 [inline] + nilfs_segctor_do_construct+0x1f55/0x76c0 + nilfs_clean_segments+0x3bd/0xa50 + nilfs_ioctl_clean_segments fs/nilfs2/ioctl.c:922 [inline] + nilfs_ioctl+0x261f/0x2780 + +The root cause is that user-supplied segment numbers are not validated +before nilfs_clean_segments() begins doing work; the range check on +each segnum is performed deep inside the call chain by +nilfs_sufile_updatev(), which emits a nilfs_warn() per invalid entry +while still holding the segctor lock and the sufile mi_sem. Under load +(repeated invocations across multiple mounts saturating the global +printk path), the cumulative printk latency keeps ns_segctor_sem held +long enough to trip the hung_task watchdog, blocking concurrent +operations such as chmod() that need ns_segctor_sem for read. + +Fix by validating the contents of kbufs[4] in nilfs_clean_segments() +immediately after acquiring ns_segctor_sem via nilfs_transaction_lock(). +Holding ns_segctor_sem serializes the check against +nilfs_ioctl_resize(), which can modify ns_nsegments, so the validation +uses a consistent value. Out-of-range segment numbers are rejected +with -EINVAL before any segment-cleaning work begins, so the bad +entries never reach the per-element diagnostic path inside +nilfs_sufile_updatev(). + +Reported-by: syzbot+62f0f99d2f2bb8e3bbd7@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=62f0f99d2f2bb8e3bbd7 +Tested-by: syzbot+62f0f99d2f2bb8e3bbd7@syzkaller.appspotmail.com +Cc: stable@vger.kernel.org +Signed-off-by: Deepanshu Kartikey +Fixes: 071cb4b81987 ("nilfs2: eliminate removal list of segments") +Signed-off-by: Ryusuke Konishi +Signed-off-by: Viacheslav Dubeyko +Signed-off-by: Greg Kroah-Hartman +--- + fs/nilfs2/segment.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +--- a/fs/nilfs2/segment.c ++++ b/fs/nilfs2/segment.c +@@ -2512,12 +2512,33 @@ int nilfs_clean_segments(struct super_bl + struct nilfs_sc_info *sci = nilfs->ns_writer; + struct nilfs_transaction_info ti; + int err; ++ size_t i, nfreesegs = argv[4].v_nmembs; ++ __u64 *segnumv = kbufs[4]; + + if (unlikely(!sci)) + return -EROFS; + + nilfs_transaction_lock(sb, &ti, 1); + ++ /* ++ * Validate segment numbers under ns_segctor_sem (held for write ++ * by nilfs_transaction_lock above) so the check is serialized ++ * against nilfs_ioctl_resize(), which can modify ns_nsegments. ++ * Rejecting bad input here, before any segment-cleaning work ++ * begins, avoids the per-element diagnostic path inside ++ * nilfs_sufile_updatev() that would otherwise run under this ++ * same lock and stall concurrent readers. ++ */ ++ for (i = 0; i < nfreesegs; i++) { ++ if (segnumv[i] >= nilfs->ns_nsegments) { ++ nilfs_err(sb, ++ "Segment number %llu to be freed is out of range", ++ (unsigned long long)segnumv[i]); ++ err = -EINVAL; ++ goto bail_unlock; ++ } ++ } ++ + err = nilfs_mdt_save_to_shadow_map(nilfs->ns_dat); + if (unlikely(err)) + goto out_unlock; +@@ -2558,6 +2579,7 @@ int nilfs_clean_segments(struct super_bl + sci->sc_freesegs = NULL; + sci->sc_nfreesegs = 0; + nilfs_mdt_clear_shadow_map(nilfs->ns_dat); ++ bail_unlock: + nilfs_transaction_unlock(sb); + return err; + } diff --git a/queue-7.1/serial-8250_mid-disable-dma-for-selected-platforms.patch b/queue-7.1/serial-8250_mid-disable-dma-for-selected-platforms.patch new file mode 100644 index 0000000000..200b64ceaa --- /dev/null +++ b/queue-7.1/serial-8250_mid-disable-dma-for-selected-platforms.patch @@ -0,0 +1,59 @@ +From b1b4efea05a56c0995e4702a86d6624b4fdff32f Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Fri, 26 Jun 2026 11:49:37 +0200 +Subject: serial: 8250_mid: Disable DMA for selected platforms + +From: Andy Shevchenko + +commit b1b4efea05a56c0995e4702a86d6624b4fdff32f upstream. + +In accordance with Errata (specification updates) +HSUART May Stop Functioning when DMA is Active. + +- Denverton document #572409, rev 3.4, DNV60 +- Ice Lake Xeon D document #714070, ICXD65 +- Snowridge document #731931, SNR44 + +For a quick fix just disable the respective callbacks during the device probe. +Depending on the future development we might remove them completely. + +Reported-by: micas-opensource +Closes: https://lore.kernel.org/linux-serial/20250625031409.2404219-1-opensource@ruijie.com.cn/ +Fixes: 6ede6dcd87aa ("serial: 8250_mid: add support for DMA engine handling from UART MMIO") +Cc: stable +Signed-off-by: Andy Shevchenko +Link: https://patch.msgid.link/20260626094937.561776-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/serial/8250/8250_mid.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +--- a/drivers/tty/serial/8250/8250_mid.c ++++ b/drivers/tty/serial/8250/8250_mid.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + + #include + +@@ -368,8 +369,16 @@ static const struct mid8250_board dnv_bo + .freq = 133333333, + .base_baud = 115200, + .bar = 1, +- .setup = dnv_setup, +- .exit = dnv_exit, ++ /* ++ * Errata: ++ * HSUART May Stop Functioning when DMA is Active. ++ * ++ * - Denverton document #572409, rev 3.4, DNV60 ++ * - Ice Lake Xeon D document #714070, ICXD65 ++ * - Snowridge document #731931, SNR44 ++ */ ++ .setup = PTR_IF(false, dnv_setup), ++ .exit = PTR_IF(false, dnv_exit), + }; + + static const struct pci_device_id pci_ids[] = { diff --git a/queue-7.1/series b/queue-7.1/series index 4699ca1b79..1c46716882 100644 --- a/queue-7.1/series +++ b/queue-7.1/series @@ -274,3 +274,22 @@ hid-multitouch-fix-out-of-bounds-bit-access-on-mt_io_flags.patch hid-appleir-fix-uaf-on-pending-key_up_timer-in-remove.patch hid-lg-g15-cancel-pending-work-on-remove-to-fix-a-use-after-free.patch hid-sensor-hub-add-sensor_hub_input_attr_read_values-for-multi-byte-reads.patch +hfs-hfsplus-fix-u32-overflow-in-check_and_correct_requested_length.patch +hfs-hfsplus-zero-initialize-buffer-in-hfs_bnode_read.patch +nilfs2-reject-clean_segments-ioctl-with-out-of-range-segment-numbers.patch +media-mtk-jpeg-cancel-workqueue-on-release-for-supported-platforms-only.patch +serial-8250_mid-disable-dma-for-selected-platforms.patch +xfs-use-null-daddr-for-unset-first-bad-log-block.patch +xfs-release-dquot-buffer-after-dqflush-failure.patch +xfs-pass-back-updated-nb-from-xfs_growfs_compute_deltas.patch +xfs-only-log-freed-extents-for-the-current-rtg-in-zoned-growfs.patch +xfs-initialize-iomap-flags-earlier-in-xfs_bmbt_to_iomap.patch +xfs-fix-unreachable-bigtime-check-in-dquot-flush-validation.patch +xfs-fix-pointer-arithmetic-error-on-32-bit-systems.patch +xfs-fix-exchmaps-reservation-limit-check.patch +xfs-fix-memory-leak-in-xfs_dqinode_metadir_create.patch +bpf-reject-fragmented-frames-in-devmap.patch +bpf-restore-sysctl-new-value-from-1-to-0.patch +bpf-validate-btf-repeated-field-counts-before-expansion.patch +bpf-keep-dynamic-inner-array-lookups-nullable.patch +bpf-allow-lpm-map-access-from-sleepable-bpf-programs.patch diff --git a/queue-7.1/xfs-fix-exchmaps-reservation-limit-check.patch b/queue-7.1/xfs-fix-exchmaps-reservation-limit-check.patch new file mode 100644 index 0000000000..494e285663 --- /dev/null +++ b/queue-7.1/xfs-fix-exchmaps-reservation-limit-check.patch @@ -0,0 +1,40 @@ +From 0a5213bbff62b51c7d4999ac8c7e11ea57d00d45 Mon Sep 17 00:00:00 2001 +From: Yingjie Gao +Date: Thu, 4 Jun 2026 20:03:17 +0800 +Subject: xfs: fix exchmaps reservation limit check + +From: Yingjie Gao + +commit 0a5213bbff62b51c7d4999ac8c7e11ea57d00d45 upstream. + +xfs_exchmaps_estimate_overhead() adds the bmbt and rmapbt +overhead to a local resblks variable, but the final UINT_MAX +check still tests req->resblks. That is the reservation value +from before the overhead was added. + +The computed value is stored back in req->resblks and later passed +to xfs_trans_alloc(), whose block reservation argument is unsigned +int. Check the computed reservation so the existing limit applies +to the value that will be used. + +Fixes: 966ceafc7a43 ("xfs: create deferred log items for file mapping exchanges") +Cc: stable@vger.kernel.org # v6.10 +Signed-off-by: Yingjie Gao +Reviewed-by: "Darrick J. Wong" +Signed-off-by: Carlos Maiolino +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/libxfs/xfs_exchmaps.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/xfs/libxfs/xfs_exchmaps.c ++++ b/fs/xfs/libxfs/xfs_exchmaps.c +@@ -711,7 +711,7 @@ xfs_exchmaps_estimate_overhead( + return -ENOSPC; + + /* Can't actually reserve more than UINT_MAX blocks. */ +- if (req->resblks > UINT_MAX) ++ if (resblks > UINT_MAX) + return -ENOSPC; + + req->resblks = resblks; diff --git a/queue-7.1/xfs-fix-memory-leak-in-xfs_dqinode_metadir_create.patch b/queue-7.1/xfs-fix-memory-leak-in-xfs_dqinode_metadir_create.patch new file mode 100644 index 0000000000..a427060e2c --- /dev/null +++ b/queue-7.1/xfs-fix-memory-leak-in-xfs_dqinode_metadir_create.patch @@ -0,0 +1,75 @@ +From 45de375b25060edf46e20abb36521ba530336ceb Mon Sep 17 00:00:00 2001 +From: Dawei Feng +Date: Sat, 27 Jun 2026 14:04:02 +0800 +Subject: xfs: fix memory leak in xfs_dqinode_metadir_create() + +From: Dawei Feng + +commit 45de375b25060edf46e20abb36521ba530336ceb upstream. + +If xfs_metadir_create() fails in xfs_dqinode_metadir_create(), the current +code returns directly, leaking the allocated update and transaction state. +If the subsequent commit fails, the caller-owned inode reference is left +behind. + +Fix this memory leak by routing the create failure path through +xfs_metadir_cancel(). For both create and commit failures, finish and +release any inode returned to the caller, mirroring the unwind pattern in +xfs_metadir_mkdir(). + +The bug was first flagged by an experimental analysis tool we are +developing for kernel memory-management bugs while analyzing +v6.13-rc1. The tool is still under development and is not yet publicly +available. Manual inspection confirms that the bug is still +present in v7.1.1. + +An x86_64 allyesconfig build showed no new warnings. Runtime validation +used kprobe fault injection during `mount -o uquota` on a metadir XFS +image. Injecting xfs_metadir_create() reproduced the old active-update path +that left mount stuck later in mount setup; after this change, the same +injection reported cancel_hits=1 and irele_hits=1. Injecting +xfs_metadir_commit() exercised the old inode-reference leak path; after +this change, it reported irele_hits=1. + +Fixes: e80fbe1ad8ef ("xfs: use metadir for quota inodes") +Cc: stable@vger.kernel.org # v6.13 +Signed-off-by: Dawei Feng +Reviewed-by: "Darrick J. Wong" +Signed-off-by: Carlos Maiolino +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/libxfs/xfs_dquot_buf.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +--- a/fs/xfs/libxfs/xfs_dquot_buf.c ++++ b/fs/xfs/libxfs/xfs_dquot_buf.c +@@ -436,17 +436,27 @@ xfs_dqinode_metadir_create( + + error = xfs_metadir_create(&upd, S_IFREG); + if (error) +- return error; ++ goto out_cancel; + + xfs_trans_log_inode(upd.tp, upd.ip, XFS_ILOG_CORE); + + error = xfs_metadir_commit(&upd); + if (error) +- return error; ++ goto out_irele; + + xfs_finish_inode_setup(upd.ip); + *ipp = upd.ip; + return 0; ++ ++out_cancel: ++ xfs_metadir_cancel(&upd, error); ++out_irele: ++ /* Have to finish setting up the inode to ensure it's deleted. */ ++ if (upd.ip) { ++ xfs_finish_inode_setup(upd.ip); ++ xfs_irele(upd.ip); ++ } ++ return error; + } + + #ifndef __KERNEL__ diff --git a/queue-7.1/xfs-fix-pointer-arithmetic-error-on-32-bit-systems.patch b/queue-7.1/xfs-fix-pointer-arithmetic-error-on-32-bit-systems.patch new file mode 100644 index 0000000000..a1d68c506c --- /dev/null +++ b/queue-7.1/xfs-fix-pointer-arithmetic-error-on-32-bit-systems.patch @@ -0,0 +1,39 @@ +From 84eec3f7fc73144d1a230c9e8ad92721e37dcaab Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Tue, 9 Jun 2026 21:57:24 -0700 +Subject: xfs: fix pointer arithmetic error on 32-bit systems + +From: Darrick J. Wong + +commit 84eec3f7fc73144d1a230c9e8ad92721e37dcaab upstream. + +The translation of the old XFS_BMBT_KEY_ADDR macro into a static +function is not correct on 32-bit systems because the sizeof() argument +went from being a xfs_bmbt_key_t (i.e. a struct) to a (struct +xfs_bmbt_key *) (i.e. a pointer to the same struct). On 64-bit systems +this turns out ok because they are the same size, but on 32-bit systems +this is catastrophic because they are not the same size. So far there +have been no complaints, most likely because the xfs developers urge +against running it on 32-bit systems. But this needs fixing asap. + +Cc: stable@vger.kernel.org # v6.12 +Fixes: 79124b37400635 ("xfs: replace shouty XFS_BM{BT,DR} macros") +Signed-off-by: "Darrick J. Wong" +Reviewed-by: Christoph Hellwig +Signed-off-by: Carlos Maiolino +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/libxfs/xfs_bmap_btree.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/xfs/libxfs/xfs_bmap_btree.h ++++ b/fs/xfs/libxfs/xfs_bmap_btree.h +@@ -89,7 +89,7 @@ xfs_bmbt_key_addr( + { + return (struct xfs_bmbt_key *) + ((char *)block + xfs_bmbt_block_len(mp) + +- (index - 1) * sizeof(struct xfs_bmbt_key *)); ++ (index - 1) * sizeof(struct xfs_bmbt_key)); + } + + static inline xfs_bmbt_ptr_t * diff --git a/queue-7.1/xfs-fix-unreachable-bigtime-check-in-dquot-flush-validation.patch b/queue-7.1/xfs-fix-unreachable-bigtime-check-in-dquot-flush-validation.patch new file mode 100644 index 0000000000..e2f90c11d7 --- /dev/null +++ b/queue-7.1/xfs-fix-unreachable-bigtime-check-in-dquot-flush-validation.patch @@ -0,0 +1,59 @@ +From 03866d130ed33ab68cc7faaf4bf2c4abef96d42e Mon Sep 17 00:00:00 2001 +From: Alexey Nepomnyashih +Date: Wed, 3 Jun 2026 20:41:47 +0000 +Subject: xfs: fix unreachable BIGTIME check in dquot flush validation + +From: Alexey Nepomnyashih + +commit 03866d130ed33ab68cc7faaf4bf2c4abef96d42e upstream. + +The dqp->q_id == 0 check inside the XFS_DQTYPE_BIGTIME block is +unreachable because root dquots return successfully earlier. Reject root +dquots with XFS_DQTYPE_BIGTIME before that early return, preserving the +intended validation and removing the unreachable condition. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 4ea1ff3b4968 ("xfs: widen ondisk quota expiration timestamps to handle y2038+") +Cc: stable@vger.kernel.org # v5.10+ +Signed-off-by: Alexey Nepomnyashih +Reviewed-by: "Darrick J. Wong" +Reviewed-by: Allison Henderson +Signed-off-by: Carlos Maiolino +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/xfs_dquot.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +--- a/fs/xfs/xfs_dquot.c ++++ b/fs/xfs/xfs_dquot.c +@@ -1216,6 +1216,14 @@ xfs_qm_dqflush_check( + type != XFS_DQTYPE_PROJ) + return __this_address; + ++ /* bigtime flag should never be set on root dquots */ ++ if (dqp->q_type & XFS_DQTYPE_BIGTIME) { ++ if (!xfs_has_bigtime(dqp->q_mount)) ++ return __this_address; ++ if (dqp->q_id == 0) ++ return __this_address; ++ } ++ + if (dqp->q_id == 0) + return NULL; + +@@ -1231,14 +1239,6 @@ xfs_qm_dqflush_check( + !dqp->q_rtb.timer) + return __this_address; + +- /* bigtime flag should never be set on root dquots */ +- if (dqp->q_type & XFS_DQTYPE_BIGTIME) { +- if (!xfs_has_bigtime(dqp->q_mount)) +- return __this_address; +- if (dqp->q_id == 0) +- return __this_address; +- } +- + return NULL; + } + diff --git a/queue-7.1/xfs-initialize-iomap-flags-earlier-in-xfs_bmbt_to_iomap.patch b/queue-7.1/xfs-initialize-iomap-flags-earlier-in-xfs_bmbt_to_iomap.patch new file mode 100644 index 0000000000..24e6beb146 --- /dev/null +++ b/queue-7.1/xfs-initialize-iomap-flags-earlier-in-xfs_bmbt_to_iomap.patch @@ -0,0 +1,41 @@ +From 327e58826eb72f8bae9419cf1a4e722b57c85694 Mon Sep 17 00:00:00 2001 +From: Christoph Hellwig +Date: Tue, 9 Jun 2026 09:53:44 +0200 +Subject: xfs: initialize iomap->flags earlier in xfs_bmbt_to_iomap + +From: Christoph Hellwig + +commit 327e58826eb72f8bae9419cf1a4e722b57c85694 upstream. + +Otherwise we lose the IOMAP_IOEND_BOUNDARY assingment for writes to the +first block in a realtime group, and could cause incorrect merges for +such writes. + +Fixes: b91afef72471 ("xfs: don't merge ioends across RTGs") +Cc: # v6.13 +Signed-off-by: Christoph Hellwig +Reviewed-by: "Darrick J. Wong" +Signed-off-by: Carlos Maiolino +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/xfs_iomap.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/xfs/xfs_iomap.c ++++ b/fs/xfs/xfs_iomap.c +@@ -113,6 +113,7 @@ xfs_bmbt_to_iomap( + return xfs_alert_fsblock_zero(ip, imap); + } + ++ iomap->flags = iomap_flags; + if (imap->br_startblock == HOLESTARTBLOCK) { + iomap->addr = IOMAP_NULL_ADDR; + iomap->type = IOMAP_HOLE; +@@ -143,7 +144,6 @@ xfs_bmbt_to_iomap( + } + iomap->offset = XFS_FSB_TO_B(mp, imap->br_startoff); + iomap->length = XFS_FSB_TO_B(mp, imap->br_blockcount); +- iomap->flags = iomap_flags; + if (mapping_flags & IOMAP_DAX) { + iomap->dax_dev = target->bt_daxdev; + } else { diff --git a/queue-7.1/xfs-only-log-freed-extents-for-the-current-rtg-in-zoned-growfs.patch b/queue-7.1/xfs-only-log-freed-extents-for-the-current-rtg-in-zoned-growfs.patch new file mode 100644 index 0000000000..447c7990db --- /dev/null +++ b/queue-7.1/xfs-only-log-freed-extents-for-the-current-rtg-in-zoned-growfs.patch @@ -0,0 +1,58 @@ +From 44cccefe65749821d9a13523c8b763bf1262ef73 Mon Sep 17 00:00:00 2001 +From: Christoph Hellwig +Date: Wed, 10 Jun 2026 07:07:21 +0200 +Subject: xfs: only log freed extents for the current RTG in zoned growfs + +From: Christoph Hellwig + +commit 44cccefe65749821d9a13523c8b763bf1262ef73 upstream. + +Otherwise a power fail or crash during growfs could lead to an +elevated sb_rblocks counter. + +Note that the step function is much simpler compared to the classic RT +allocator as zoned RT sections must be aligned to real time group +boundaries. + +Fixes: 01b71e64bb87 ("xfs: support growfs on zoned file systems") +Cc: # v6.15 +Signed-off-by: Christoph Hellwig +Reviewed-by: "Darrick J. Wong" +Reviewed-by: Damien Le Moal +Signed-off-by: Carlos Maiolino +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/xfs_rtalloc.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/fs/xfs/xfs_rtalloc.c ++++ b/fs/xfs/xfs_rtalloc.c +@@ -890,8 +890,7 @@ xfs_growfs_rt_sb_fields( + + static int + xfs_growfs_rt_zoned( +- struct xfs_rtgroup *rtg, +- xfs_rfsblock_t nrblocks) ++ struct xfs_rtgroup *rtg) + { + struct xfs_mount *mp = rtg_mount(rtg); + struct xfs_mount *nmp; +@@ -903,7 +902,8 @@ xfs_growfs_rt_zoned( + * Calculate new sb and mount fields for this round. Also ensure the + * rtg_extents value is uptodate as the rtbitmap code relies on it. + */ +- nmp = xfs_growfs_rt_alloc_fake_mount(mp, nrblocks, ++ nmp = xfs_growfs_rt_alloc_fake_mount(mp, ++ xfs_rtgs_to_rfsbs(mp, rtg_rgno(rtg) + 1), + mp->m_sb.sb_rextsize); + if (!nmp) + return -ENOMEM; +@@ -1218,7 +1218,7 @@ xfs_growfs_rtg( + } + + if (xfs_has_zoned(mp)) { +- error = xfs_growfs_rt_zoned(rtg, nrblocks); ++ error = xfs_growfs_rt_zoned(rtg); + goto out_rele; + } + diff --git a/queue-7.1/xfs-pass-back-updated-nb-from-xfs_growfs_compute_deltas.patch b/queue-7.1/xfs-pass-back-updated-nb-from-xfs_growfs_compute_deltas.patch new file mode 100644 index 0000000000..31e8807567 --- /dev/null +++ b/queue-7.1/xfs-pass-back-updated-nb-from-xfs_growfs_compute_deltas.patch @@ -0,0 +1,96 @@ +From 4cb6e89a3d901d4da515977e55f9a9a779238660 Mon Sep 17 00:00:00 2001 +From: Christoph Hellwig +Date: Tue, 9 Jun 2026 09:52:44 +0200 +Subject: xfs: pass back updated nb from xfs_growfs_compute_deltas + +From: Christoph Hellwig + +commit 4cb6e89a3d901d4da515977e55f9a9a779238660 upstream. + +xfs_growfs_compute_deltas can update nb for corner cases like a number +of blocks that would create a less the minimal sized AG, or running +past the max AG limit. Pass back the calculated value to the caller, +as it relies on to calculate the new number of perag structures. + +Note that the grown file system size is not affected by this +miscalculation as it uses the passed back delta value. + +Fixes: a49b7ff63f98 ("xfs: Refactoring the nagcount and delta calculation") +Cc: stable@vger.kernel.org # v7.0 +Signed-off-by: Christoph Hellwig +Reviewed-by: "Darrick J. Wong" +Reviewed-by: Carlos Maiolino +Signed-off-by: Carlos Maiolino +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/libxfs/xfs_ag.c | 10 +++++----- + fs/xfs/libxfs/xfs_ag.h | 2 +- + fs/xfs/xfs_fsops.c | 2 +- + 3 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c +index dcd2f93b6a6c..0c5f0548021f 100644 +--- a/fs/xfs/libxfs/xfs_ag.c ++++ b/fs/xfs/libxfs/xfs_ag.c +@@ -866,7 +866,7 @@ xfs_ag_shrink_space( + void + xfs_growfs_compute_deltas( + struct xfs_mount *mp, +- xfs_rfsblock_t nb, ++ xfs_rfsblock_t *nb, + int64_t *deltap, + xfs_agnumber_t *nagcountp) + { +@@ -874,19 +874,19 @@ xfs_growfs_compute_deltas( + int64_t delta; + xfs_agnumber_t nagcount; + +- nb_div = nb; ++ nb_div = *nb; + nb_mod = do_div(nb_div, mp->m_sb.sb_agblocks); + if (nb_mod && nb_mod >= XFS_MIN_AG_BLOCKS) + nb_div++; + else if (nb_mod) +- nb = nb_div * mp->m_sb.sb_agblocks; ++ *nb = nb_div * mp->m_sb.sb_agblocks; + + if (nb_div > XFS_MAX_AGNUMBER + 1) { + nb_div = XFS_MAX_AGNUMBER + 1; +- nb = nb_div * mp->m_sb.sb_agblocks; ++ *nb = nb_div * mp->m_sb.sb_agblocks; + } + nagcount = nb_div; +- delta = nb - mp->m_sb.sb_dblocks; ++ delta = *nb - mp->m_sb.sb_dblocks; + *deltap = delta; + *nagcountp = nagcount; + } +diff --git a/fs/xfs/libxfs/xfs_ag.h b/fs/xfs/libxfs/xfs_ag.h +index 16a9b43a3c27..8aa4266c5571 100644 +--- a/fs/xfs/libxfs/xfs_ag.h ++++ b/fs/xfs/libxfs/xfs_ag.h +@@ -330,7 +330,7 @@ int xfs_ag_init_headers(struct xfs_mount *mp, struct aghdr_init_data *id); + int xfs_ag_shrink_space(struct xfs_perag *pag, struct xfs_trans **tpp, + xfs_extlen_t delta); + void +-xfs_growfs_compute_deltas(struct xfs_mount *mp, xfs_rfsblock_t nb, ++xfs_growfs_compute_deltas(struct xfs_mount *mp, xfs_rfsblock_t *nb, + int64_t *deltap, xfs_agnumber_t *nagcountp); + int xfs_ag_extend_space(struct xfs_perag *pag, struct xfs_trans *tp, + xfs_extlen_t len); +diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c +index 8d64d904d73c..436857356a0a 100644 +--- a/fs/xfs/xfs_fsops.c ++++ b/fs/xfs/xfs_fsops.c +@@ -124,7 +124,7 @@ xfs_growfs_data_private( + mp->m_sb.sb_rextsize); + if (error) + return error; +- xfs_growfs_compute_deltas(mp, nb, &delta, &nagcount); ++ xfs_growfs_compute_deltas(mp, &nb, &delta, &nagcount); + + /* + * Reject filesystems with a single AG because they are not +-- +2.55.0 + diff --git a/queue-7.1/xfs-release-dquot-buffer-after-dqflush-failure.patch b/queue-7.1/xfs-release-dquot-buffer-after-dqflush-failure.patch new file mode 100644 index 0000000000..0f030da6af --- /dev/null +++ b/queue-7.1/xfs-release-dquot-buffer-after-dqflush-failure.patch @@ -0,0 +1,42 @@ +From 0c1b3a823a22af623d55f225fe2ac7e8b9052821 Mon Sep 17 00:00:00 2001 +From: Yingjie Gao +Date: Thu, 25 Jun 2026 21:16:23 +0800 +Subject: xfs: release dquot buffer after dqflush failure + +From: Yingjie Gao + +commit 0c1b3a823a22af623d55f225fe2ac7e8b9052821 upstream. + +xfs_qm_dqpurge() gets a locked buffer from xfs_dquot_use_attached_buf(). +If xfs_qm_dqflush() fails, the error path skips xfs_buf_relse() and then +calls xfs_dquot_detach_buf(), which tries to lock the same buffer again. + +Release the buffer after xfs_qm_dqflush() returns so the error path drops +the caller hold and unlocks the buffer before the dquot is detached, +matching the other dqflush callers. + +Fixes: a40fe30868ba ("xfs: separate dquot buffer reads from xfs_dqflush") +Cc: stable@vger.kernel.org # v6.13+ +Signed-off-by: Yingjie Gao +Reviewed-by: "Darrick J. Wong" +Signed-off-by: Carlos Maiolino +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/xfs_qm.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/fs/xfs/xfs_qm.c ++++ b/fs/xfs/xfs_qm.c +@@ -166,10 +166,9 @@ xfs_qm_dqpurge( + * does it on success. + */ + error = xfs_qm_dqflush(dqp, bp); +- if (!error) { ++ if (!error) + error = xfs_bwrite(bp); +- xfs_buf_relse(bp); +- } ++ xfs_buf_relse(bp); + xfs_dqflock(dqp); + } + xfs_dquot_detach_buf(dqp); diff --git a/queue-7.1/xfs-use-null-daddr-for-unset-first-bad-log-block.patch b/queue-7.1/xfs-use-null-daddr-for-unset-first-bad-log-block.patch new file mode 100644 index 0000000000..41b85aa7ca --- /dev/null +++ b/queue-7.1/xfs-use-null-daddr-for-unset-first-bad-log-block.patch @@ -0,0 +1,55 @@ +From cc9af5e461ea5f6e37738f3f1e41c45a9b7f45d6 Mon Sep 17 00:00:00 2001 +From: Yousef Alhouseen +Date: Tue, 30 Jun 2026 12:06:07 +0200 +Subject: xfs: use null daddr for unset first bad log block + +From: Yousef Alhouseen + +commit cc9af5e461ea5f6e37738f3f1e41c45a9b7f45d6 upstream. + +xlog_do_recovery_pass() may return before setting first_bad. The caller +must distinguish that case from an error at a valid log block, including +block zero after the log wraps. + +Initialize first_bad to XFS_BUF_DADDR_NULL and test it explicitly before +treating the error as a torn write. + +Fixes: 7088c4136fa1 ("xfs: detect and trim torn writes during log recovery") +Suggested-by: Darrick J. Wong +Reported-by: syzbot+b7dfbed0c6c2b5e9fd34@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=b7dfbed0c6c2b5e9fd34 +Cc: stable@vger.kernel.org # v4.5 +Signed-off-by: Yousef Alhouseen +Reviewed-by: "Darrick J. Wong" +Signed-off-by: Carlos Maiolino +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/xfs_log_recover.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/fs/xfs/xfs_log_recover.c ++++ b/fs/xfs/xfs_log_recover.c +@@ -1028,7 +1028,7 @@ xlog_verify_head( + { + struct xlog_rec_header *tmp_rhead; + char *tmp_buffer; +- xfs_daddr_t first_bad; ++ xfs_daddr_t first_bad = XFS_BUF_DADDR_NULL; + xfs_daddr_t tmp_rhead_blk; + int found; + int error; +@@ -1057,7 +1057,8 @@ xlog_verify_head( + */ + error = xlog_do_recovery_pass(log, *head_blk, tmp_rhead_blk, + XLOG_RECOVER_CRCPASS, &first_bad); +- if ((error == -EFSBADCRC || error == -EFSCORRUPTED) && first_bad) { ++ if ((error == -EFSBADCRC || error == -EFSCORRUPTED) && ++ first_bad != XFS_BUF_DADDR_NULL) { + /* + * We've hit a potential torn write. Reset the error and warn + * about it. +@@ -3575,4 +3576,3 @@ xlog_recover_cancel( + if (xlog_recovery_needed(log)) + xlog_recover_cancel_intents(log); + } +-