From 0ec9fcec3a9b1d207359b06196639ccae49e1913 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 14 Jul 2026 17:58:52 +0200 Subject: [PATCH] 6.1-stable patches added patches: bpf-reject-fragmented-frames-in-devmap.patch bpf-restore-sysctl-new-value-from-1-to-0.patch hfs-hfsplus-zero-initialize-buffer-in-hfs_bnode_read.patch nilfs2-reject-clean_segments-ioctl-with-out-of-range-segment-numbers.patch xfs-fix-unreachable-bigtime-check-in-dquot-flush-validation.patch xfs-use-null-daddr-for-unset-first-bad-log-block.patch --- ...f-reject-fragmented-frames-in-devmap.patch | 69 +++++++++++ ...restore-sysctl-new-value-from-1-to-0.patch | 52 ++++++++ ...-initialize-buffer-in-hfs_bnode_read.patch | 58 +++++++++ ...tl-with-out-of-range-segment-numbers.patch | 114 ++++++++++++++++++ queue-6.1/series | 6 + ...time-check-in-dquot-flush-validation.patch | 59 +++++++++ ...-daddr-for-unset-first-bad-log-block.patch | 55 +++++++++ 7 files changed, 413 insertions(+) create mode 100644 queue-6.1/bpf-reject-fragmented-frames-in-devmap.patch create mode 100644 queue-6.1/bpf-restore-sysctl-new-value-from-1-to-0.patch create mode 100644 queue-6.1/hfs-hfsplus-zero-initialize-buffer-in-hfs_bnode_read.patch create mode 100644 queue-6.1/nilfs2-reject-clean_segments-ioctl-with-out-of-range-segment-numbers.patch create mode 100644 queue-6.1/xfs-fix-unreachable-bigtime-check-in-dquot-flush-validation.patch create mode 100644 queue-6.1/xfs-use-null-daddr-for-unset-first-bad-log-block.patch diff --git a/queue-6.1/bpf-reject-fragmented-frames-in-devmap.patch b/queue-6.1/bpf-reject-fragmented-frames-in-devmap.patch new file mode 100644 index 0000000000..817c82e0c2 --- /dev/null +++ b/queue-6.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 +@@ -552,6 +552,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; +@@ -697,6 +701,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-6.1/bpf-restore-sysctl-new-value-from-1-to-0.patch b/queue-6.1/bpf-restore-sysctl-new-value-from-1-to-0.patch new file mode 100644 index 0000000000..1090e1ee40 --- /dev/null +++ b/queue-6.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 +@@ -1744,7 +1744,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-6.1/hfs-hfsplus-zero-initialize-buffer-in-hfs_bnode_read.patch b/queue-6.1/hfs-hfsplus-zero-initialize-buffer-in-hfs_bnode_read.patch new file mode 100644 index 0000000000..1afea4d8e3 --- /dev/null +++ b/queue-6.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 + int bytes_read; + int 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; + int l; + ++ memset(buf, 0, len); ++ + if (!is_bnode_offset_valid(node, off)) + return; + diff --git a/queue-6.1/nilfs2-reject-clean_segments-ioctl-with-out-of-range-segment-numbers.patch b/queue-6.1/nilfs2-reject-clean_segments-ioctl-with-out-of-range-segment-numbers.patch new file mode 100644 index 0000000000..8773702b53 --- /dev/null +++ b/queue-6.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 +@@ -2503,12 +2503,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; +@@ -2549,6 +2570,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-6.1/series b/queue-6.1/series index e4b57b49d3..df0fdc762d 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -156,3 +156,9 @@ hid-wacom-stop-hardware-after-post-start-probe-failures.patch hid-letsketch-fix-uaf-on-inrange_timer-at-driver-unbind.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-zero-initialize-buffer-in-hfs_bnode_read.patch +nilfs2-reject-clean_segments-ioctl-with-out-of-range-segment-numbers.patch +xfs-use-null-daddr-for-unset-first-bad-log-block.patch +xfs-fix-unreachable-bigtime-check-in-dquot-flush-validation.patch +bpf-reject-fragmented-frames-in-devmap.patch +bpf-restore-sysctl-new-value-from-1-to-0.patch diff --git a/queue-6.1/xfs-fix-unreachable-bigtime-check-in-dquot-flush-validation.patch b/queue-6.1/xfs-fix-unreachable-bigtime-check-in-dquot-flush-validation.patch new file mode 100644 index 0000000000..2850f308be --- /dev/null +++ b/queue-6.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 +@@ -1174,6 +1174,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; + +@@ -1189,14 +1197,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-6.1/xfs-use-null-daddr-for-unset-first-bad-log-block.patch b/queue-6.1/xfs-use-null-daddr-for-unset-first-bad-log-block.patch new file mode 100644 index 0000000000..ce73ea7eba --- /dev/null +++ b/queue-6.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. +@@ -3538,4 +3539,3 @@ xlog_recover_cancel( + if (xlog_recovery_needed(log)) + xlog_recover_cancel_intents(log); + } +- -- 2.47.3