From: Namjae Jeon linkinjeon@kernel.org
[ Upstream commit b39a1833cc4a2755b02603eec3a71a85e9dff926 ]
Under high concurrency, A tree-connection object (tcon) is freed on a disconnect path while another path still holds a reference and later executes *_put()/write on it.
Reported-by: Qianchang Zhao pioooooooooip@gmail.com Reported-by: Zhitong Liu liuzhitong1993@gmail.com Signed-off-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
fs/smb/server/mgmt/tree_connect.c | 18 ++++-------------- fs/smb/server/mgmt/tree_connect.h | 1 - fs/smb/server/smb2pdu.c | 3 --- 3 files changed, 4 insertions(+), 18 deletions(-)
diff --git a/fs/smb/server/mgmt/tree_connect.c b/fs/smb/server/mgmt/tree_connect.c index ecfc575086712..d3483d9c757c7 100644 --- a/fs/smb/server/mgmt/tree_connect.c +++ b/fs/smb/server/mgmt/tree_connect.c @@ -78,7 +78,6 @@ ksmbd_tree_conn_connect(struct ksmbd_work *work, const char *share_name) tree_conn->t_state = TREE_NEW; status.tree_conn = tree_conn; atomic_set(&tree_conn->refcount, 1); - init_waitqueue_head(&tree_conn->refcount_q);
ret = xa_err(xa_store(&sess->tree_conns, tree_conn->id, tree_conn, KSMBD_DEFAULT_GFP)); @@ -100,14 +99,8 @@ ksmbd_tree_conn_connect(struct ksmbd_work *work, const char *share_name)
void ksmbd_tree_connect_put(struct ksmbd_tree_connect *tcon) { - /* - * Checking waitqueue to releasing tree connect on - * tree disconnect. waitqueue_active is safe because it - * uses atomic operation for condition. - */ - if (!atomic_dec_return(&tcon->refcount) && - waitqueue_active(&tcon->refcount_q)) - wake_up(&tcon->refcount_q); + if (atomic_dec_and_test(&tcon->refcount)) + kfree(tcon); }
int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess, @@ -119,14 +112,11 @@ int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess, xa_erase(&sess->tree_conns, tree_conn->id); write_unlock(&sess->tree_conns_lock);
- if (!atomic_dec_and_test(&tree_conn->refcount)) - wait_event(tree_conn->refcount_q, - atomic_read(&tree_conn->refcount) == 0); - ret = ksmbd_ipc_tree_disconnect_request(sess->id, tree_conn->id); ksmbd_release_tree_conn_id(sess, tree_conn->id); ksmbd_share_config_put(tree_conn->share_conf); - kfree(tree_conn); + if (atomic_dec_and_test(&tree_conn->refcount)) + kfree(tree_conn); return ret; }
diff --git a/fs/smb/server/mgmt/tree_connect.h b/fs/smb/server/mgmt/tree_connect.h index a42cdd0510411..f0023d86716f2 100644 --- a/fs/smb/server/mgmt/tree_connect.h +++ b/fs/smb/server/mgmt/tree_connect.h @@ -33,7 +33,6 @@ struct ksmbd_tree_connect { int maximal_access; bool posix_extensions; atomic_t refcount; - wait_queue_head_t refcount_q; unsigned int t_state; };
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index a2830ec67e782..dba29881debdc 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -2200,7 +2200,6 @@ int smb2_tree_disconnect(struct ksmbd_work *work) goto err_out; }
- WARN_ON_ONCE(atomic_dec_and_test(&tcon->refcount)); tcon->t_state = TREE_DISCONNECTED; write_unlock(&sess->tree_conns_lock);
@@ -2210,8 +2209,6 @@ int smb2_tree_disconnect(struct ksmbd_work *work) goto err_out; }
- work->tcon = NULL; - rsp->StructureSize = cpu_to_le16(4); err = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_tree_disconnect_rsp));
From: Max Chou max.chou@realtek.com
[ Upstream commit 32caa197b9b603e20f49fd3a0dffecd0cd620499 ]
Add the support ID(0x0489, 0xE12F) to usb_device_id table for Realtek RTL8852BE-VT.
The device info from /sys/kernel/debug/usb/devices as below.
T: Bus=04 Lev=02 Prnt=02 Port=05 Cnt=01 Dev#= 86 Spd=12 MxCh= 0 D: Ver= 1.00 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=0489 ProdID=e12f Rev= 0.00 S: Manufacturer=Realtek S: Product=Bluetooth Radio S: SerialNumber=00e04c000001 C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
Signed-off-by: Max Chou max.chou@realtek.com Signed-off-by: Luiz Augusto von Dentz luiz.von.dentz@intel.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
drivers/bluetooth/btusb.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index bd26a8db64096..b92bfd131567e 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -587,6 +587,8 @@ static const struct usb_device_id quirks_table[] = { /* Realtek 8852BT/8852BE-VT Bluetooth devices */ { USB_DEVICE(0x0bda, 0x8520), .driver_info = BTUSB_REALTEK | BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x0489, 0xe12f), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH },
/* Realtek 8922AE Bluetooth devices */ { USB_DEVICE(0x0bda, 0x8922), .driver_info = BTUSB_REALTEK |
From: Qu Wenruo wqu@suse.com
[ Upstream commit 54df8b80cc63aa0f22c4590cad11542731ed43ff ]
[BUG] When a scrub failed immediately without any byte scrubbed, the returned btrfs_scrub_progress::last_physical will always be 0, even if there is a non-zero @start passed into btrfs_scrub_dev() for resume cases.
This will reset the progress and make later scrub resume start from the beginning.
[CAUSE] The function btrfs_scrub_dev() accepts a @progress parameter to copy its updated progress to the caller, there are cases where we either don't touch progress::last_physical at all or copy 0 into last_physical:
- last_physical not updated at all If some error happened before scrubbing any super block or chunk, we will not copy the progress, leaving the @last_physical untouched.
E.g. failed to allocate @sctx, scrubbing a missing device or even there is already a running scrub and so on.
All those cases won't touch @progress at all, resulting the last_physical untouched and will be left as 0 for most cases.
- Error out before scrubbing any bytes In those case we allocated @sctx, and sctx->stat.last_physical is all zero (initialized by kvzalloc()). Unfortunately some critical errors happened during scrub_enumerate_chunks() or scrub_supers() before any stripe is really scrubbed.
In that case although we will copy sctx->stat back to @progress, since no byte is really scrubbed, last_physical will be overwritten to 0.
[FIX] Make sure the parameter @progress always has its @last_physical member updated to @start parameter inside btrfs_scrub_dev().
At the very beginning of the function, set @progress->last_physical to @start, so that even if we error out without doing progress copying, last_physical is still at @start.
Then after we got @sctx allocated, set sctx->stat.last_physical to @start, this will make sure even if we didn't get any byte scrubbed, at the progress copying stage the @last_physical is not left as zero.
This should resolve the resume progress reset problem.
Signed-off-by: Qu Wenruo wqu@suse.com Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
fs/btrfs/scrub.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index ba20d9286a340..cff67ed630196 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c @@ -3039,6 +3039,10 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, unsigned int nofs_flag; bool need_commit = false;
+ /* Set the basic fallback @last_physical before we got a sctx. */ + if (progress) + progress->last_physical = start; + if (btrfs_fs_closing(fs_info)) return -EAGAIN;
@@ -3057,6 +3061,7 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, sctx = scrub_setup_ctx(fs_info, is_dev_replace); if (IS_ERR(sctx)) return PTR_ERR(sctx); + sctx->stat.last_physical = start;
ret = scrub_workers_get(fs_info); if (ret)
From: ChenXiaoSong chenxiaosong@kylinos.cn
[ Upstream commit 269df046c1e15ab34fa26fd90db9381f022a0963 ]
__process_request() will not print error messages if smb2_ioctl() always returns 0.
Fix this by returning the correct value at the end of function.
Signed-off-by: ChenXiaoSong chenxiaosong@kylinos.cn Acked-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
fs/smb/server/smb2pdu.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index f901ae18e68ad..a2830ec67e782 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -8164,7 +8164,7 @@ int smb2_ioctl(struct ksmbd_work *work) id = req->VolatileFileId;
if (req->Flags != cpu_to_le32(SMB2_0_IOCTL_IS_FSCTL)) { - rsp->hdr.Status = STATUS_NOT_SUPPORTED; + ret = -EOPNOTSUPP; goto out; }
@@ -8184,8 +8184,9 @@ int smb2_ioctl(struct ksmbd_work *work) case FSCTL_DFS_GET_REFERRALS: case FSCTL_DFS_GET_REFERRALS_EX: /* Not support DFS yet */ + ret = -EOPNOTSUPP; rsp->hdr.Status = STATUS_FS_DRIVER_REQUIRED; - goto out; + goto out2; case FSCTL_CREATE_OR_GET_OBJECT_ID: { struct file_object_buf_type1_ioctl_rsp *obj_buf; @@ -8475,8 +8476,10 @@ int smb2_ioctl(struct ksmbd_work *work) rsp->hdr.Status = STATUS_BUFFER_TOO_SMALL; else if (ret < 0 || rsp->hdr.Status == 0) rsp->hdr.Status = STATUS_INVALID_PARAMETER; + +out2: smb2_set_err_rsp(work); - return 0; + return ret; }
/**
From: Konstantin Komarov almaz.alexandrovich@paragon-software.com
[ Upstream commit 1b2ae190ea43bebb8c73d21f076addc8a8c71849 ]
Ensure fsync() returns -EIO when the ntfs3 filesystem is in forced shutdown, instead of silently succeeding via generic_file_fsync().
Signed-off-by: Konstantin Komarov almaz.alexandrovich@paragon-software.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
## Analysis Summary
### What the commit does: Adds a new wrapper function `ntfs_file_fsync()` that checks if the ntfs3 filesystem is in forced shutdown state before calling `generic_file_fsync()`. If the filesystem is shutting down, it returns `-EIO` instead of silently succeeding.
### Technical mechanism: The fix is straightforward: 1. Get the inode from the file 2. Call `ntfs3_forced_shutdown(inode->i_sb)` to check if filesystem is in error state 3. Return `-EIO` if true, otherwise delegate to `generic_file_fsync()`
### Is this a real bug fix? **Yes** - this fixes a data integrity semantics issue. When a filesystem is in forced shutdown (typically after critical I/O errors), fsync() should return an error to inform applications their data was not synced. Silently succeeding could cause data loss without applications knowing.
### Stable kernel criteria evaluation:
| Criteria | Assessment | |----------|------------| | Fixes real bug | Yes - data integrity semantics issue | | Small/contained | Yes - ~10 lines, single function | | Obviously correct | Yes - follows existing pattern in ntfs3 | | Stable tag | **NO** - maintainer didn't request stable | | Fixes: tag | **NO** - no indication of when bug was introduced |
### Critical dependency issue: The `ntfs3_forced_shutdown()` function was introduced in **kernel 6.8** (commit 6c3684e703837). My verification shows: - **v6.6**: Does NOT have `ntfs3_forced_shutdown` (0 occurrences) - **v6.8+**: Has the shutdown infrastructure
This means: - Stable trees **6.6.y**, **6.1.y**, **5.15.y**, etc. cannot use this fix without first backporting the entire shutdown feature (~75 lines across 7 files) - Only newer stable trees (if any exist based on 6.8+) would benefit
### Risk vs Benefit: - **Benefit**: Correct fsync() error handling during filesystem shutdown - **Risk**: Low for applicable kernels - simple logic, well-tested pattern - **Applicability**: Very limited - only affects recent kernels with shutdown support
### Conclusion: While this is a legitimate fix for a data integrity issue, several factors argue against backporting:
1. **No maintainer request**: No "Cc: stable@vger.kernel.org" tag indicates the maintainer didn't consider this critical for stable 2. **Dependency on new feature**: Requires the shutdown infrastructure from 6.8, which is not in most active stable trees (6.6.y, 6.1.y, 5.15.y) 3. **Limited impact scope**: Only applies to the relatively recent kernel versions that have the shutdown feature 4. **The shutdown feature itself is new**: The forced shutdown functionality only existed for a short time before this fix, meaning the exposure window is small
This fix would require significant infrastructure backporting to be useful in most stable trees, making it unsuitable as-is for stable backporting.
**NO**
fs/ntfs3/file.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c index 4c90ec2fa2eae..83f0072f0896c 100644 --- a/fs/ntfs3/file.c +++ b/fs/ntfs3/file.c @@ -1375,6 +1375,18 @@ static ssize_t ntfs_file_splice_write(struct pipe_inode_info *pipe, return iter_file_splice_write(pipe, file, ppos, len, flags); }
+/* + * ntfs_file_fsync - file_operations::fsync + */ +static int ntfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync) +{ + struct inode *inode = file_inode(file); + if (unlikely(ntfs3_forced_shutdown(inode->i_sb))) + return -EIO; + + return generic_file_fsync(file, start, end, datasync); +} + // clang-format off const struct inode_operations ntfs_file_inode_operations = { .getattr = ntfs_getattr, @@ -1397,7 +1409,7 @@ const struct file_operations ntfs_file_operations = { .splice_write = ntfs_file_splice_write, .mmap_prepare = ntfs_file_mmap_prepare, .open = ntfs_file_open, - .fsync = generic_file_fsync, + .fsync = ntfs_file_fsync, .fallocate = ntfs_fallocate, .release = ntfs_file_release, };
From: Andreas Gruenbacher agruenba@redhat.com
[ Upstream commit 8a157e0a0aa5143b5d94201508c0ca1bb8cfb941 ]
In gfs2_chain_bio(), the call to bio_chain() has its arguments swapped. The result is leaked bios and incorrect synchronization (only the last bio will actually be waited for). This code is only used during mount and filesystem thaw, so the bug normally won't be noticeable.
Reported-by: Stephen Zhang starzhangzsd@gmail.com Signed-off-by: Andreas Gruenbacher agruenba@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
fs/gfs2/lops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index 9c8c305a75c46..914d03f6c4e82 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c @@ -487,7 +487,7 @@ static struct bio *gfs2_chain_bio(struct bio *prev, unsigned int nr_iovecs) new = bio_alloc(prev->bi_bdev, nr_iovecs, prev->bi_opf, GFP_NOIO); bio_clone_blkg_association(new, prev); new->bi_iter.bi_sector = bio_end_sector(prev); - bio_chain(new, prev); + bio_chain(prev, new); submit_bio(prev); return new; }
From: Gongwei Li ligongwei@kylinos.cn
[ Upstream commit 525459da4bd62a81142fea3f3d52188ceb4d8907 ]
Add VID 13d3 & PID 3533 for Realtek RTL8821CE USB Bluetooth chip.
The information in /sys/kernel/debug/usb/devices about the Bluetooth device is listed as the below.
T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=13d3 ProdID=3533 Rev= 1.10 S: Manufacturer=Realtek S: Product=Bluetooth Radio S: SerialNumber=00e04c000001 C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
Signed-off-by: Gongwei Li ligongwei@kylinos.cn Signed-off-by: Luiz Augusto von Dentz luiz.von.dentz@intel.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
drivers/bluetooth/btusb.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 22f1932fe9126..bd26a8db64096 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -504,6 +504,8 @@ static const struct usb_device_id quirks_table[] = { /* Realtek 8821CE Bluetooth devices */ { USB_DEVICE(0x13d3, 0x3529), .driver_info = BTUSB_REALTEK | BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x13d3, 0x3533), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH },
/* Realtek 8822CE Bluetooth devices */ { USB_DEVICE(0x0bda, 0xb00c), .driver_info = BTUSB_REALTEK |
From: Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp
[ Upstream commit 005d4b0d33f6b4a23d382b7930f7a96b95b01f39 ]
syzbot is reporting that S_IFMT bits of inode->i_mode can become bogus when the S_IFMT bits of the 16bits "mode" field loaded from disk are corrupted.
According to [1], the permissions field was treated as reserved in Mac OS 8 and 9. According to [2], the reserved field was explicitly initialized with 0, and that field must remain 0 as long as reserved. Therefore, when the "mode" field is not 0 (i.e. no longer reserved), the file must be S_IFDIR if dir == 1, and the file must be one of S_IFREG/S_IFLNK/S_IFCHR/ S_IFBLK/S_IFIFO/S_IFSOCK if dir == 0.
Reported-by: syzbot syzbot+895c23f6917da440ed0d@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=895c23f6917da440ed0d Link: https://developer.apple.com/library/archive/technotes/tn/tn1150.html#HFSPlus... [1] Link: https://developer.apple.com/library/archive/technotes/tn/tn1150.html#Reserve... [2] Signed-off-by: Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp Reviewed-by: Viacheslav Dubeyko slava@dubeyko.com Signed-off-by: Viacheslav Dubeyko slava@dubeyko.com Link: https://lore.kernel.org/r/04ded9f9-73fb-496c-bfa5-89c4f5d1d7bb@I-love.SAKURA... Signed-off-by: Viacheslav Dubeyko slava@dubeyko.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
## Analysis of hfsplus: Verify inode mode when loading from disk
### 1. COMMIT MESSAGE ANALYSIS
**Key indicators:** - **Reported-by: syzbot** - This is a real bug found by automated fuzzing - **Closes:** link to syzkaller bug report confirms this is a genuine issue - **Reviewed-by:** present from the HFS+ maintainer (Viacheslav Dubeyko) - **No "Cc: stable@vger.kernel.org"** tag - **No "Fixes:" tag** - bug appears to exist since original HFS+ implementation
The commit describes that corrupted S_IFMT bits in the on-disk "mode" field can cause inode->i_mode to become bogus when loaded from disk. The commit message references Apple technical documentation explaining the expected values for the mode field.
### 2. CODE CHANGE ANALYSIS
The fix modifies `hfsplus_get_perms()` in two ways:
**a) Adds validation logic (the core fix):** ```c if (dir) { if (mode && !S_ISDIR(mode)) goto bad_type; } else if (mode) { switch (mode & S_IFMT) { case S_IFREG: case S_IFLNK: case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK: break; default: goto bad_type; } } ``` This validates that: - For directories (`dir=1`): mode must be 0 or actually be a directory type - For files (`dir=0`): mode must be 0 or one of the valid file types (regular, symlink, char/block device, FIFO, socket)
**b) Changes return type from `void` to `int`:** - Returns -EIO on invalid mode with an error message - Callers (`hfsplus_cat_read_inode`) now check the return value and propagate errors
**Root cause:** The original code blindly trusted the mode field from disk without validating that the S_IFMT bits are consistent with the directory flag.
### 3. CLASSIFICATION
- **Type:** Bug fix (input validation) - **Security relevance:** Yes - crafted filesystem images could trigger this - **Category:** Filesystem robustness/hardening against corrupted data
### 4. SCOPE AND RISK ASSESSMENT
| Aspect | Assessment | |--------|------------| | Lines changed | ~30+ additions, moderate size | | Files touched | 1 file (fs/hfsplus/inode.c) | | Complexity | Low - straightforward validation logic | | Regression risk | **LOW** - only rejects clearly invalid data |
The validation is conservative and follows Apple's official HFS+ specification. It only rejects modes that are definitively wrong.
### 5. USER IMPACT
- **Affected users:** Those mounting HFS+ filesystems (macOS external drives, dual-boot setups) - **Trigger:** Mounting a corrupted or maliciously crafted HFS+ filesystem image - **Impact of bug:** Bogus inode mode can lead to undefined kernel behavior when processing the inode - **Impact of fix:** Graceful rejection with -EIO instead of corrupted internal state
### 6. STABILITY INDICATORS
- Reviewed by subsystem maintainer ✓ - Clean, standalone fix with no dependencies ✓ - The modified functions exist in older stable kernels ✓ - No unusual code patterns or risky constructs ✓
### 7. DEPENDENCY CHECK
This is a standalone fix. The `hfsplus_get_perms` and `hfsplus_cat_read_inode` functions exist in all stable trees where HFS+ is supported.
---
## Summary
**What it fixes:** Prevents corrupted or maliciously crafted HFS+ filesystem images from causing bogus inode modes to be loaded into the kernel.
**Why it matters for stable:** This is a defensive fix that prevents accepting corrupted data, which could lead to undefined behavior. syzbot found this bug, indicating it can be triggered by crafted input - a potential security concern.
**Meets stable criteria:** - ✓ Obviously correct (validates according to Apple's HFS+ specification) - ✓ Fixes a real bug that affects users (syzbot found it with crafted images) - ✓ Small and contained (single file, ~30 lines of validation) - ✓ Low regression risk (only rejects clearly invalid data) - ✗ No explicit stable tag (author didn't request it)
**Risk vs Benefit:** - **Risk:** Very low - adds validation that only rejects invalid data - **Benefit:** Prevents kernel from operating on corrupted inode modes from crafted/corrupted filesystems
The lack of explicit stable tags suggests the author may not have intended this for stable, but the fix clearly meets stable criteria as a filesystem robustness fix against corrupted input. Filesystem fixes for handling crafted/corrupted data are generally appropriate for stable trees.
**YES**
fs/hfsplus/inode.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-)
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index b51a411ecd237..e290e417ed3a7 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c @@ -180,13 +180,29 @@ const struct dentry_operations hfsplus_dentry_operations = { .d_compare = hfsplus_compare_dentry, };
-static void hfsplus_get_perms(struct inode *inode, - struct hfsplus_perm *perms, int dir) +static int hfsplus_get_perms(struct inode *inode, + struct hfsplus_perm *perms, int dir) { struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb); u16 mode;
mode = be16_to_cpu(perms->mode); + if (dir) { + if (mode && !S_ISDIR(mode)) + goto bad_type; + } else if (mode) { + switch (mode & S_IFMT) { + case S_IFREG: + case S_IFLNK: + case S_IFCHR: + case S_IFBLK: + case S_IFIFO: + case S_IFSOCK: + break; + default: + goto bad_type; + } + }
i_uid_write(inode, be32_to_cpu(perms->owner)); if ((test_bit(HFSPLUS_SB_UID, &sbi->flags)) || (!i_uid_read(inode) && !mode)) @@ -212,6 +228,10 @@ static void hfsplus_get_perms(struct inode *inode, inode->i_flags |= S_APPEND; else inode->i_flags &= ~S_APPEND; + return 0; +bad_type: + pr_err("invalid file type 0%04o for inode %lu\n", mode, inode->i_ino); + return -EIO; }
static int hfsplus_file_open(struct inode *inode, struct file *file) @@ -516,7 +536,9 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) } hfs_bnode_read(fd->bnode, &entry, fd->entryoffset, sizeof(struct hfsplus_cat_folder)); - hfsplus_get_perms(inode, &folder->permissions, 1); + res = hfsplus_get_perms(inode, &folder->permissions, 1); + if (res) + goto out; set_nlink(inode, 1); inode->i_size = 2 + be32_to_cpu(folder->valence); inode_set_atime_to_ts(inode, hfsp_mt2ut(folder->access_date)); @@ -545,7 +567,9 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd)
hfsplus_inode_read_fork(inode, HFSPLUS_IS_RSRC(inode) ? &file->rsrc_fork : &file->data_fork); - hfsplus_get_perms(inode, &file->permissions, 0); + res = hfsplus_get_perms(inode, &file->permissions, 0); + if (res) + goto out; set_nlink(inode, 1); if (S_ISREG(inode->i_mode)) { if (file->permissions.dev)
From: Andreas Gruenbacher agruenba@redhat.com
[ Upstream commit 64c10ed9274bc46416f502afea48b4ae11279669 ]
When a node tries to delete an inode, it first requests exclusive access to the iopen glock. This triggers demote requests on all remote nodes currently holding the iopen glock. To satisfy those requests, the remote nodes evict the inode in question, or they poke the corresponding inode glock to signal that the inode is still in active use.
This behavior doesn't depend on whether or not a filesystem is read-only, so remove the incorrect read-only check.
Signed-off-by: Andreas Gruenbacher agruenba@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
fs/gfs2/glops.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index 0c0a80b3bacab..0c68ab4432b08 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c @@ -630,8 +630,7 @@ static void iopen_go_callback(struct gfs2_glock *gl, bool remote) struct gfs2_inode *ip = gl->gl_object; struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
- if (!remote || sb_rdonly(sdp->sd_vfs) || - test_bit(SDF_KILL, &sdp->sd_flags)) + if (!remote || test_bit(SDF_KILL, &sdp->sd_flags)) return;
if (gl->gl_demote_state == LM_ST_UNLOCKED &&
From: Viacheslav Dubeyko slava@dubeyko.com
[ Upstream commit ed490f36f439b877393c12a2113601e4145a5a56 ]
The xfstests' test-case generic/070 leaves HFS+ volume in corrupted state:
sudo ./check generic/070 FSTYP -- hfsplus PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.17.0-rc1+ #4 SMP PREEMPT_DYNAMIC Wed Oct 1 15:02:44 PDT 2025 MKFS_OPTIONS -- /dev/loop51 MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch
generic/070 _check_generic_filesystem: filesystem on /dev/loop50 is inconsistent (see xfstests-dev/results//generic/070.full for details)
Ran: generic/070 Failures: generic/070 Failed 1 of 1 tests
sudo fsck.hfsplus -d /dev/loop50 ** /dev/loop50 Using cacheBlockSize=32K cacheTotalBlock=1024 cacheSize=32768K. Executing fsck_hfs (version 540.1-Linux). ** Checking non-journaled HFS Plus Volume. The volume name is test ** Checking extents overflow file. Unused node is not erased (node = 1) ** Checking catalog file. ** Checking multi-linked files. ** Checking catalog hierarchy. ** Checking extended attributes file. ** Checking volume bitmap. ** Checking volume information. Verify Status: VIStat = 0x0000, ABTStat = 0x0000 EBTStat = 0x0004 CBTStat = 0x0000 CatStat = 0x00000000 ** Repairing volume. ** Rechecking volume. ** Checking non-journaled HFS Plus Volume. The volume name is test ** Checking extents overflow file. ** Checking catalog file. ** Checking multi-linked files. ** Checking catalog hierarchy. ** Checking extended attributes file. ** Checking volume bitmap. ** Checking volume information. ** The volume test was repaired successfully.
It is possible to see that fsck.hfsplus detected not erased and unused node for the case of extents overflow file. The HFS+ logic has special method that defines if the node should be erased:
bool hfs_bnode_need_zeroout(struct hfs_btree *tree) { struct super_block *sb = tree->inode->i_sb; struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); const u32 volume_attr = be32_to_cpu(sbi->s_vhdr->attributes);
return tree->cnid == HFSPLUS_CAT_CNID && volume_attr & HFSPLUS_VOL_UNUSED_NODE_FIX; }
However, it is possible to see that this method works only for the case of catalog file. But debugging of the issue has shown that HFSPLUS_VOL_UNUSED_NODE_FIX attribute has been requested for the extents overflow file too:
catalog file kernel: hfsplus: node 4, num_recs 0, flags 0x10 kernel: hfsplus: tree->cnid 4, volume_attr 0x80000800
extents overflow file kernel: hfsplus: node 1, num_recs 0, flags 0x10 kernel: hfsplus: tree->cnid 3, volume_attr 0x80000800
This patch modifies the hfs_bnode_need_zeroout() by checking only volume_attr but not the b-tree ID because node zeroing can be requested for all HFS+ b-tree types.
sudo ./check generic/070 FSTYP -- hfsplus PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.18.0-rc3+ #79 SMP PREEMPT_DYNAMIC Fri Oct 31 16:07:42 PDT 2025 MKFS_OPTIONS -- /dev/loop51 MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch
generic/070 33s ... 34s Ran: generic/070 Passed all 1 tests
Signed-off-by: Viacheslav Dubeyko slava@dubeyko.com cc: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de cc: Yangtao Li frank.li@vivo.com cc: linux-fsdevel@vger.kernel.org Link: https://lore.kernel.org/r/20251101001229.247432-1-slava@dubeyko.com Signed-off-by: Viacheslav Dubeyko slava@dubeyko.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
## Final Assessment
### Summary of Findings
**Bug Type**: Filesystem corruption (data integrity issue)
**Technical Root Cause**: The `hfs_bnode_need_zeroout()` function incorrectly restricts unused node zeroing to only the catalog B-tree (HFSPLUS_CAT_CNID). However, when the volume attribute `HFSPLUS_VOL_UNUSED_NODE_FIX` is set, it applies to ALL HFS+ B-tree types including the extents overflow file. This causes fsck.hfsplus to detect corruption: "Unused node is not erased (node = 1)".
**The Fix**: Removes the catalog-only check, allowing node zeroing for all B-tree types when the volume attribute is set.
### Stable Kernel Criteria Evaluation
| Criterion | Status | |-----------|--------| | Fixes real bug | ✅ Filesystem corruption verified by fsck | | Obviously correct | ✅ Simple condition removal, matches Apple spec | | Small and contained | ✅ 1 line change, single file | | No new features | ✅ No new functionality added | | Tested | ✅ xfstests generic/070 passes | | Exists in stable | ✅ Function introduced in kernel 3.16 (2014) |
### Risk vs Benefit
**Risk**: Very LOW - The change makes code more conservative (zeros more nodes, not fewer) - Only two call sites, both appropriately handle the result - No new code paths, just relaxing an incorrect restriction
**Benefit**: HIGH - Fixes filesystem corruption that users can actually hit - Reproducible with standard xfstests suite - Prevents data integrity issues on HFS+ volumes
### Concerns
1. **No explicit stable tags**: Missing "Cc: stable" and "Fixes:" tags. However, filesystem corruption fixes are exactly what stable is for.
2. **Stale comment**: The comment still says "if this is the catalog tree" but this is documentation debt, not a functional issue.
3. **Limited user base**: HFS+ is less commonly used on Linux than other filesystems, but users who do use it deserve working support.
### Conclusion
This commit fixes a real, reproducible filesystem corruption issue with an extremely small, safe change. The fix is obviously correct - it aligns behavior with the HFS+ specification where `HFSPLUS_VOL_UNUSED_NODE_FIX` applies to all B-trees, not just the catalog. The change is conservative (does more work, not less) minimizing regression risk. The affected code has existed since kernel 3.16, making it applicable to all active stable trees.
Despite the missing explicit stable tags, this is clearly appropriate stable material - a surgical fix for data corruption that meets all the technical criteria.
**YES**
fs/hfsplus/bnode.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index 63e652ad1e0de..edf7e27e1e375 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -704,6 +704,5 @@ bool hfs_bnode_need_zeroout(struct hfs_btree *tree) struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); const u32 volume_attr = be32_to_cpu(sbi->s_vhdr->attributes);
- return tree->cnid == HFSPLUS_CAT_CNID && - volume_attr & HFSPLUS_VOL_UNUSED_NODE_FIX; + return volume_attr & HFSPLUS_VOL_UNUSED_NODE_FIX; }
From: Bitterblue Smith rtl8821cerfe2@gmail.com
[ Upstream commit 5511ba3de434892e5ef3594d6eabbd12b1629356 ]
Flip the response rate subchannel. It was backwards, causing low speeds when using 40 MHz channel width. "iw dev ... station dump" showed a low RX rate, 11M or less.
Also fix the channel width field of RF6052_REG_MODE_AG.
Tested only with RTL8192CU, but these settings are identical for RTL8723AU.
Signed-off-by: Bitterblue Smith rtl8821cerfe2@gmail.com Reviewed-by: Ping-Ke Shih pkshih@realtek.com Signed-off-by: Ping-Ke Shih pkshih@realtek.com Link: https://patch.msgid.link/1f46571d-855b-43e1-8bfc-abacceb96043@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
## COMPREHENSIVE ANALYSIS
### 1. COMMIT MESSAGE ANALYSIS
**Subject:** "wifi: rtl8xxxu: Fix HT40 channel config for RTL8192CU, RTL8723AU"
- Contains "Fix" keyword indicating a bug fix - Describes specific affected hardware: RTL8192CU, RTL8723AU USB WiFi adapters - Explains user-visible symptom: "low speeds when using 40 MHz channel width" - Provides diagnostic evidence: "`iw dev ... station dump` showed a low RX rate, 11M or less" - **No** "Cc: stable@vger.kernel.org" tag - **No** "Fixes:" tag pointing to the original buggy commit - **Has** "Reviewed-by: Ping-Ke Shih" (Realtek's kernel maintainer) - **Has** "Tested only with RTL8192CU" - real-world testing performed
### 2. CODE CHANGE ANALYSIS
**Two distinct bugs are fixed:**
**Bug #1: RSR (Response Rate Set) subchannel configuration (lines 1255-1258):** ```c // BEFORE (buggy): if (sec_ch_above) rsr |= RSR_RSC_UPPER_SUB_CHANNEL; else rsr |= RSR_RSC_LOWER_SUB_CHANNEL;
// AFTER (fixed): if (!sec_ch_above) rsr |= RSR_RSC_UPPER_SUB_CHANNEL; else rsr |= RSR_RSC_LOWER_SUB_CHANNEL; ``` The logic was inverted - when secondary channel is above, LOWER should be set, not UPPER. Comparison with RTL8188E driver (8188e.c:462-465) confirms the fix matches the correct pattern.
**Bug #2: RF6052_REG_MODE_AG bandwidth configuration (lines 1322-1328):** ```c // BEFORE (buggy): if (hw->conf.chandef.width == NL80211_CHAN_WIDTH_40) val32 &= ~MODE_AG_CHANNEL_20MHZ; else val32 |= MODE_AG_CHANNEL_20MHZ;
// AFTER (fixed): val32 &= ~MODE_AG_BW_MASK; // Clear both bits 10 and 11 if (hw->conf.chandef.width != NL80211_CHAN_WIDTH_40) val32 |= MODE_AG_CHANNEL_20MHZ; ``` Two issues: (1) Only cleared bit 10, not the full bandwidth mask (bits 10-11), and (2) the logic flow was awkward - proper pattern is to clear mask first, then set appropriate bit only when needed.
The gen2 driver (`rtl8xxxu_gen2_config_channel` at line 1446) already uses `MODE_AG_BW_MASK` correctly, confirming this is the right approach.
### 3. CLASSIFICATION
- **Bug Type:** Logic error causing severe performance degradation - **NOT a feature:** No new functionality added - **NOT a quirk/workaround:** This is fixing incorrect code logic - **Hardware affected:** RTL8192CU, RTL8723AU (older but still commonly used USB WiFi adapters)
### 4. SCOPE AND RISK ASSESSMENT
- **Lines changed:** ~8 lines modified - **Files touched:** 1 file (core.c) - **Complexity:** LOW - simple logic inversions and proper mask usage - **Scope:** Confined to `rtl8xxxu_gen1_config_channel()` function, only affects 40MHz mode - **Risk of regression:** LOW - brings gen1 config in line with gen2 and 8188e implementations - **Dependencies:** `MODE_AG_BW_MASK` exists since 2016 (commit c3f9506f2374), present in all stable kernels
### 5. USER IMPACT
- **Affected users:** Anyone using RTL8192CU or RTL8723AU USB WiFi adapters with 40MHz channels - **Severity:** MODERATE-HIGH - WiFi functional but severely degraded speeds (capped at 11M vs expected 40MHz HT speeds which could be 150-300Mbps) - **Impact scope:** These are common, inexpensive USB WiFi adapters; many users in production environments - **Visibility:** Users would notice unusably slow WiFi and might mistakenly blame their router or network
### 6. STABILITY INDICATORS
- Reviewed by Realtek's Linux kernel maintainer (Ping-Ke Shih) - Tested on actual hardware (RTL8192CU) - Consistent with how other chip variants in the same driver family handle this - Small, surgical changes with clear correctness rationale
### 7. DEPENDENCY CHECK
- `MODE_AG_BW_MASK` macro is defined in regs.h since 2016 - No other commits needed for this fix to work - The affected function `rtl8xxxu_gen1_config_channel()` exists in all stable kernels that have the rtl8xxxu driver
### VERDICT
**Positive factors:** - Fixes a real, user-visible performance bug (severely degraded WiFi speeds) - Small, contained changes (8 lines) - Low regression risk - aligns with established patterns in related code - Reviewed and tested - No dependencies on other commits - Affects real hardware that users own
**Negative factors:** - No explicit "Cc: stable@" tag from maintainer - No "Fixes:" tag to trace original bug introduction
**Risk vs Benefit:** - Benefit: Restores proper HT40 performance for RTL8192CU/RTL8723AU users - Risk: Very low - logic corrections that match other implementations in the same driver
This is a clear bug fix for user-visible performance degradation. The changes are minimal, well-understood, properly reviewed, and consistent with how other chip variants in the same driver family handle channel configuration. The lack of explicit stable tags appears to be an oversight rather than an intentional exclusion. Users with these common USB WiFi adapters would benefit significantly from this fix.
**YES**
drivers/net/wireless/realtek/rtl8xxxu/core.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/core.c b/drivers/net/wireless/realtek/rtl8xxxu/core.c index 3ded5952729fc..d2d3bbac2861f 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/core.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/core.c @@ -1252,7 +1252,7 @@ void rtl8xxxu_gen1_config_channel(struct ieee80211_hw *hw) opmode &= ~BW_OPMODE_20MHZ; rtl8xxxu_write8(priv, REG_BW_OPMODE, opmode); rsr &= ~RSR_RSC_BANDWIDTH_40M; - if (sec_ch_above) + if (!sec_ch_above) rsr |= RSR_RSC_UPPER_SUB_CHANNEL; else rsr |= RSR_RSC_LOWER_SUB_CHANNEL; @@ -1321,9 +1321,8 @@ void rtl8xxxu_gen1_config_channel(struct ieee80211_hw *hw)
for (i = RF_A; i < priv->rf_paths; i++) { val32 = rtl8xxxu_read_rfreg(priv, i, RF6052_REG_MODE_AG); - if (hw->conf.chandef.width == NL80211_CHAN_WIDTH_40) - val32 &= ~MODE_AG_CHANNEL_20MHZ; - else + val32 &= ~MODE_AG_BW_MASK; + if (hw->conf.chandef.width != NL80211_CHAN_WIDTH_40) val32 |= MODE_AG_CHANNEL_20MHZ; rtl8xxxu_write_rfreg(priv, i, RF6052_REG_MODE_AG, val32); }
From: Konstantin Komarov almaz.alexandrovich@paragon-software.com
[ Upstream commit 5180138604323895b5c291eca6aa7c20be494ade ]
Before it used an unsigned 64-bit type, which prevented proper handling of timestamps earlier than 1970-01-01. Switch to a signed 64-bit type to support pre-epoch timestamps. The issue was caught by xfstests.
Signed-off-by: Konstantin Komarov almaz.alexandrovich@paragon-software.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
Now I have a complete understanding. Let me write the detailed analysis:
## Detailed Analysis
### 1. COMMIT MESSAGE ANALYSIS
**Subject:** `fs/ntfs3: Support timestamps prior to epoch`
**Commit Body:** - The commit explains that before this fix, the code used an **unsigned 64-bit type** (`u64`), which prevented proper handling of timestamps earlier than 1970-01-01 (the Unix epoch). - The fix switches to a **signed 64-bit type** (`s64`) to support pre- epoch timestamps. - The issue was caught by **xfstests test 258**, which specifically tests for timestamps prior to the epoch.
**Tags:** - **No `Cc: stable@vger.kernel.org` tag** is present. - **No `Fixes:` tag** is present.
### 2. CODE CHANGE ANALYSIS
#### The Bug:
In the current code (before the patch):
```980:987:fs/ntfs3/ntfs_fs.h static inline void nt2kernel(const __le64 tm, struct timespec64 *ts) { u64 t = le64_to_cpu(tm) - _100ns2seconds * SecondsToStartOf1970;
// WARNING: do_div changes its first argument(!) ts->tv_nsec = do_div(t, _100ns2seconds) * 100; ts->tv_sec = t; } ```
The variable `t` is declared as `u64` (unsigned 64-bit integer). NTFS timestamps are stored as the number of 100-nanosecond intervals since January 1, 1601. After subtracting `SecondsToStartOf1970` (0x00000002B6109100), which represents the number of seconds between 1601 and 1970, `t` represents a Unix timestamp.
**Problem:** When the NTFS timestamp represents a date before January 1, 1970, the subtraction produces a **negative** result. But since `t` is unsigned (`u64`), the negative value wraps around to a very large positive value, resulting in a wrong (future) timestamp.
**The `do_div` macro** operates on unsigned integers and uses unsigned division, which doesn't handle negative values correctly.
#### The Fix:
The patch changes: 1. `u64 t` → `s64 t` (signed 64-bit integer) 2. `do_div(t, _100ns2seconds)` → `div_s64_rem(t, _100ns2seconds, &t32)` (signed division) 3. Introduces `s32 t32` to hold the remainder
The new code: ```c static inline void nt2kernel(const __le64 tm, struct timespec64 *ts) { s32 t32; /* use signed 64 bit to support timestamps prior to epoch. xfstest 258. */ s64 t = le64_to_cpu(tm) - _100ns2seconds * SecondsToStartOf1970;
ts->tv_sec = div_s64_rem(t, _100ns2seconds, &t32); ts->tv_nsec = t32 * 100; } ```
`div_s64_rem()` is designed for signed 64-bit division with a 32-bit divisor, properly handling negative values and returning the remainder through a pointer.
**Root Cause:** Using unsigned arithmetic for a value that can be negative (pre-epoch timestamps).
### 3. CLASSIFICATION
- **Bug fix:** YES - This is fixing incorrect behavior with timestamps before 1970. - **New feature:** NO - It doesn't add new functionality, only fixes existing functionality. - **Security fix:** NO - No security implications. - **Exception category:** NO - Not a device ID, quirk, DT update, build fix, or documentation fix.
### 4. SCOPE AND RISK ASSESSMENT
**Lines Changed:** Very minimal - changes ~8 lines of code within a single inline function.
**Files Touched:** 1 file (`fs/ntfs3/ntfs_fs.h`)
**Subsystem Complexity:** - NTFS3 is a relatively new filesystem (added in 5.15) - The change is in a core time conversion function `nt2kernel()` that is called whenever reading timestamps from disk - All file timestamps (creation, modification, access times) use this function
**Risk Assessment:** - **LOW RISK** - The change is small, surgical, and uses a well- established kernel API (`div_s64_rem`) - The new code is mathematically equivalent to the old code for timestamps after 1970 - For timestamps before 1970, the new code produces correct results (negative `tv_sec` values) - The `timespec64` structure's `tv_sec` field is `time64_t` which is signed (`__s64`), so it can properly represent negative timestamps
### 5. USER IMPACT
**Who is affected?** - Users of NTFS3 filesystem - Users with NTFS volumes containing files with pre-1970 timestamps
**How severe?** - The bug causes **data corruption** (incorrect timestamp display/storage) for pre-epoch files - Without this fix, timestamps like January 1, 1960 would appear as some date far in the future - This breaks file management tools and any software relying on correct timestamps
**Test Coverage:** - The fix was identified by **xfstests generic/258**, a standard filesystem test that specifically validates pre-epoch timestamp handling - This is a well-known and commonly run test suite
### 6. STABILITY INDICATORS
- **No `Tested-by:` tag** - However, xfstests is mentioned, implying the fix was tested against this test suite - **No `Reviewed-by:` tag** - The commit is from the ntfs3 maintainer (Konstantin Komarov from Paragon Software)
### 7. DEPENDENCY CHECK
- **No dependencies** - This is a standalone fix - Uses existing kernel APIs (`div_s64_rem`, `s64`, `s32`) that have been available for a long time - The affected code (`nt2kernel` function) has existed since ntfs3 was introduced in kernel 5.15
### Summary
**YES signals:** 1. ✅ Fixes a **real bug** (incorrect timestamps for pre-epoch dates) 2. ✅ **Small and surgical** change - only 8 lines changed in one function 3. ✅ **Obviously correct** - uses proper signed arithmetic for values that can be negative 4. ✅ No new features, no new APIs 5. ✅ Caught by **xfstests**, a standard fs test suite (test 258) 6. ✅ Applies to all stable kernels that have ntfs3 (5.15+) 7. ✅ Zero risk of regression for post-epoch timestamps (mathematically equivalent) 8. ✅ Fixes **data integrity issue** (timestamp corruption)
**NO signals:** 1. ⚠️ No explicit `Cc: stable@vger.kernel.org` tag 2. ⚠️ No `Fixes:` tag 3. ⚠️ No `Tested-by:` or `Reviewed-by:` tags
**Verdict:**
This is a clear bug fix that addresses a real issue (incorrect pre-epoch timestamp handling) that affects NTFS3 users. The fix is small, surgical, uses well-tested kernel APIs, and is mathematically correct. While the commit lacks stable tags, the nature of the fix - correcting data integrity issues with timestamps - makes it appropriate for backporting. The bug has existed since ntfs3 was introduced (5.15), so all stable trees with ntfs3 would benefit from this fix.
The lack of `Cc: stable` tag is likely an oversight since the fix clearly meets stable kernel criteria: it's a bug fix, small in scope, obviously correct, and fixes a real user-visible issue (incorrect file timestamps).
**YES**
fs/ntfs3/ntfs_fs.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h index 630128716ea73..2649fbe16669d 100644 --- a/fs/ntfs3/ntfs_fs.h +++ b/fs/ntfs3/ntfs_fs.h @@ -979,11 +979,12 @@ static inline __le64 kernel2nt(const struct timespec64 *ts) */ static inline void nt2kernel(const __le64 tm, struct timespec64 *ts) { - u64 t = le64_to_cpu(tm) - _100ns2seconds * SecondsToStartOf1970; + s32 t32; + /* use signed 64 bit to support timestamps prior to epoch. xfstest 258. */ + s64 t = le64_to_cpu(tm) - _100ns2seconds * SecondsToStartOf1970;
- // WARNING: do_div changes its first argument(!) - ts->tv_nsec = do_div(t, _100ns2seconds) * 100; - ts->tv_sec = t; + ts->tv_sec = div_s64_rem(t, _100ns2seconds, &t32); + ts->tv_nsec = t32 * 100; }
static inline struct ntfs_sb_info *ntfs_sb(struct super_block *sb)
From: Chris Lu chris.lu@mediatek.com
[ Upstream commit c126f98c011f5796ba118ef2093122d02809d30d ]
Add VID 0489 & PID e135 for MediaTek MT7920 USB Bluetooth chip.
The information in /sys/kernel/debug/usb/devices about the Bluetooth device is listed as the below.
T: Bus=06 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=480 MxCh= 0 D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=0489 ProdID=e135 Rev= 1.00 S: Manufacturer=MediaTek Inc. S: Product=Wireless_Device S: SerialNumber=000000000 C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA A: FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01 I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=125us E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms I: If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 63 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 63 Ivl=1ms I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) E: Ad=8a(I) Atr=03(Int.) MxPS= 64 Ivl=125us E: Ad=0a(O) Atr=03(Int.) MxPS= 64 Ivl=125us I: If#= 2 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) E: Ad=8a(I) Atr=03(Int.) MxPS= 64 Ivl=125us E: Ad=0a(O) Atr=03(Int.) MxPS= 64 Ivl=125us
Signed-off-by: Chris Lu chris.lu@mediatek.com Reviewed-by: Paul Menzel pmenzel@molgen.mpg.de Signed-off-by: Luiz Augusto von Dentz luiz.von.dentz@intel.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
drivers/bluetooth/btusb.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 36f18f2657ab8..cc03c8c38b16f 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -621,6 +621,8 @@ static const struct usb_device_id quirks_table[] = { /* Additional MediaTek MT7920 Bluetooth devices */ { USB_DEVICE(0x0489, 0xe134), .driver_info = BTUSB_MEDIATEK | BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x0489, 0xe135), .driver_info = BTUSB_MEDIATEK | + BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x13d3, 0x3620), .driver_info = BTUSB_MEDIATEK | BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x13d3, 0x3621), .driver_info = BTUSB_MEDIATEK |
From: Chris Lu chris.lu@mediatek.com
[ Upstream commit 5a6700a31c953af9a17a7e2681335f31d922614d ]
Add VID 0489 & PID e170 for MediaTek MT7922 USB Bluetooth chip.
The information in /sys/kernel/debug/usb/devices about the Bluetooth device is listed as the below.
T: Bus=06 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=480 MxCh= 0 D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=0489 ProdID=e170 Rev= 1.00 S: Manufacturer=MediaTek Inc. S: Product=Wireless_Device S: SerialNumber=000000000 C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA A: FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01 I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=125us E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms I: If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 63 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 63 Ivl=1ms I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) E: Ad=8a(I) Atr=03(Int.) MxPS= 64 Ivl=125us E: Ad=0a(O) Atr=03(Int.) MxPS= 64 Ivl=125us I: If#= 2 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) E: Ad=8a(I) Atr=03(Int.) MxPS= 512 Ivl=125us E: Ad=0a(O) Atr=03(Int.) MxPS= 512 Ivl=125us
Signed-off-by: Chris Lu chris.lu@mediatek.com Reviewed-by: Paul Menzel pmenzel@molgen.mpg.de Signed-off-by: Luiz Augusto von Dentz luiz.von.dentz@intel.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
drivers/bluetooth/btusb.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index c70e79e69be8d..36f18f2657ab8 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -685,6 +685,8 @@ static const struct usb_device_id quirks_table[] = { BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x0489, 0xe153), .driver_info = BTUSB_MEDIATEK | BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x0489, 0xe170), .driver_info = BTUSB_MEDIATEK | + BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x04ca, 0x3804), .driver_info = BTUSB_MEDIATEK | BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x04ca, 0x38e4), .driver_info = BTUSB_MEDIATEK |
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit 7a27b73943a70ee226fa125327101fb18e94701d ]
When changing the interface type, all activity on the interface has to be stopped first. This was done independent of existing code in cfg80211_leave(), so didn't handle e.g. background radar detection. Use cfg80211_leave() to handle it the same way.
Note that cfg80211_leave() behaves slightly differently for IBSS in wireless extensions, it won't send an event in that case. We could handle that, but since nl80211 was used to change the type, IBSS is rare, and wext is already a corner case, it doesn't seem worth it.
Link: https://patch.msgid.link/20251121174021.922ef48ce007.I970c8514252ef8a864a7fb... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
## 2. CODE CHANGE ANALYSIS
Looking at the diff and comparing with `cfg80211_leave()`:
**Original inline switch did:** - AP/P2P_GO: `cfg80211_stop_ap()` - ADHOC: `cfg80211_leave_ibss(rdev, dev, false)` - note the `false` parameter - STATION/P2P_CLIENT: `cfg80211_disconnect()` - MESH_POINT: **nothing** (just a comment "mesh should be handled?") - OCB: `cfg80211_leave_ocb()`
**`cfg80211_leave()` additionally does:** 1. `cfg80211_pmsr_wdev_down(wdev)` - **new cleanup** 2. `cfg80211_stop_background_radar_detection(wdev)` - **mentioned bug fix** 3. For ADHOC: uses `true` instead of `false` (changes wext event behavior) 4. For STATION/P2P_CLIENT: stops scheduled scans + wext cleanup 5. For MESH_POINT: `cfg80211_leave_mesh()` - **fixes the TODO bug**
## 3. CLASSIFICATION
This is primarily a **code refactoring/consolidation** that: - Fixes bugs: background radar detection not stopped, MESH_POINT not handled - Changes behavior: IBSS wext event, additional scheduled scan cleanup, pmsr cleanup - The author explicitly acknowledges behavioral differences but considers them "not worth" fixing
## 4. SCOPE AND RISK ASSESSMENT
- **Lines:** Removes ~20 lines, replaces with single function call (net negative) - **Files:** 1 file (net/wireless/util.c) - **Risk:** Medium - introduces behavioral changes beyond the stated bug fixes
The behavioral differences acknowledged by the author are concerning for stable: - IBSS with wext will behave differently (no event sent) - Additional cleanup operations are now performed
## 5. USER IMPACT
The bugs fixed (background radar detection, mesh point handling) are real but: - Not crashes or security issues - More like "incomplete state cleanup" issues - Impact is limited to users changing interface types
## 6. STABILITY INDICATORS
**Missing stable signals:** - No `Cc: stable@vger.kernel.org` tag - No `Fixes:` tag pointing to when bug was introduced - Author explicitly noted behavioral differences but chose not to address them
## 7. DEPENDENCY CHECK
The change depends on `cfg80211_leave()` having the current implementation with all the necessary handlers.
## Summary
While this commit does fix real issues (background radar detection not stopped, MESH_POINT not handled), it's fundamentally a **code consolidation** that:
1. **Introduces behavioral changes** beyond the bug fixes (IBSS wext events, additional cleanup operations) 2. **Lacks explicit stable request** from the maintainer (Johannes Berg) 3. **Author acknowledged** behavioral differences but chose not to fix them 4. The bugs fixed are **not crashes, security issues, or data corruption** - they're incomplete state cleanup issues
The maintainer deliberately did not add a `Cc: stable` or `Fixes:` tag, suggesting this wasn't intended for backporting. The behavioral changes (IBSS wext, scheduled scan cleanup, pmsr cleanup) go beyond the stated bug fixes and could introduce unexpected regressions in stable trees.
This is code cleanup/improvement material, not targeted stable-critical bug fix material.
**NO**
net/wireless/util.c | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-)
diff --git a/net/wireless/util.c b/net/wireless/util.c index 56724b33af045..4eb028ad16836 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -1203,28 +1203,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, dev->ieee80211_ptr->use_4addr = false; rdev_set_qos_map(rdev, dev, NULL);
- switch (otype) { - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_P2P_GO: - cfg80211_stop_ap(rdev, dev, -1, true); - break; - case NL80211_IFTYPE_ADHOC: - cfg80211_leave_ibss(rdev, dev, false); - break; - case NL80211_IFTYPE_STATION: - case NL80211_IFTYPE_P2P_CLIENT: - cfg80211_disconnect(rdev, dev, - WLAN_REASON_DEAUTH_LEAVING, true); - break; - case NL80211_IFTYPE_MESH_POINT: - /* mesh should be handled? */ - break; - case NL80211_IFTYPE_OCB: - cfg80211_leave_ocb(rdev, dev); - break; - default: - break; - } + cfg80211_leave(rdev, dev->ieee80211_ptr);
cfg80211_process_rdev_events(rdev); cfg80211_mlme_purge_registrations(dev->ieee80211_ptr);
From: Mikhail Malyshev mike.malyshev@gmail.com
[ Upstream commit af61da281f52aba0c5b090bafb3a31c5739850ff ]
When building out-of-tree modules with CONFIG_MODULE_SIG_FORCE=y, module signing fails because the private key path uses $(srctree) while the public key path uses $(objtree). Since signing keys are generated in the build directory during kernel compilation, both paths should use $(objtree) for consistency.
This causes SSL errors like: SSL error:02001002:system library:fopen:No such file or directory sign-file: /kernel-src/certs/signing_key.pem
The issue occurs because: - sig-key uses: $(srctree)/certs/signing_key.pem (source tree) - cmd_sign uses: $(objtree)/certs/signing_key.x509 (build tree)
But both keys are generated in $(objtree) during the build.
This complements commit 25ff08aa43e37 ("kbuild: Fix signing issue for external modules") which fixed the scripts path and public key path, but missed the private key path inconsistency.
Fixes out-of-tree module signing for configurations with separate source and build directories (e.g., O=/kernel-out).
Signed-off-by: Mikhail Malyshev mike.malyshev@gmail.com Reviewed-by: Nathan Chancellor nathan@kernel.org Tested-by: Nicolas Schier nsc@kernel.org Link: https://patch.msgid.link/20251015163452.3754286-1-mike.malyshev@gmail.com Signed-off-by: Nicolas Schier nsc@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
Now I have the complete picture. All stable trees that contain commit 13b25489b6f8 (v6.13+) have the incomplete fix and need this patch. Let me finalize my analysis:
## Complete Analysis
### 1. COMMIT MESSAGE ANALYSIS
The commit message is clear and well-documented: - **Subject**: "kbuild: Use objtree for module signing key path" - clearly states what it does - **Body**: Explains the problem with detailed error messages and root cause analysis - **References**: Explicitly mentions commit 25ff08aa43e37 as the incomplete fix it complements - **No Cc: stable@vger.kernel.org tag** - the maintainer did not explicitly request stable backport - **No Fixes: tag** - However, logically this fixes the same issue as 25ff08aa43e37, which has `Fixes: 13b25489b6f8` - **Has Reviewed-by and Tested-by tags** from Nicolas Schier and Nathan Chancellor
### 2. CODE CHANGE ANALYSIS
The change is a **single character change** (literally changing one word):
```makefile # Before: sig-key := $(if $(wildcard $(CONFIG_MODULE_SIG_KEY)),,$(srctree)/)$(CONFIG_MODULE_SIG_KEY)
# After: sig-key := $(if $(wildcard $(CONFIG_MODULE_SIG_KEY)),,$(objtree)/)$(CONFIG_MODULE_SIG_KEY) ```
**Technical mechanism of the bug:** 1. When building out-of-tree modules with `CONFIG_MODULE_SIG_FORCE=y` and separate source/build directories (e.g., `O=/kernel-out`): - `$(srctree)` points to the source tree (e.g., `/kernel-src`) - `$(objtree)` points to the build tree (e.g., `/kernel-out`)
2. Module signing keys are **generated during kernel compilation** and stored in `$(objtree)/certs/`: - Private key: `$(objtree)/certs/signing_key.pem` - Public key: `$(objtree)/certs/signing_key.x509`
3. After commit 25ff08aa43e37, `cmd_sign` correctly uses `$(objtree)/certs/signing_key.x509` for the public key, but `sig-key` still uses `$(srctree)/certs/signing_key.pem` for the private key.
4. This creates an **inconsistency**: The `sign-file` tool is called with: - Private key: `/kernel-src/certs/signing_key.pem` (WRONG - file doesn't exist there) - Public key: `/kernel-out/certs/signing_key.x509` (CORRECT)
5. Result: `fopen()` fails with "No such file or directory" when trying to open the private key.
**Why the fix is correct:** - Both signing keys are generated in `$(objtree)`, so both paths should reference `$(objtree)` - The fix is logically consistent with what commit 25ff08aa43e37 did for the other paths - The conditional `$(if $(wildcard $(CONFIG_MODULE_SIG_KEY)),,$(objtree)/)` only adds the prefix if the key path is not absolute, which is correct behavior
### 3. CLASSIFICATION
- **Type**: Bug fix (not a feature) - **Category**: Build system fix - **Severity**: Causes complete failure of out-of-tree module signing with CONFIG_MODULE_SIG_FORCE=y - **Security relevance**: Low (doesn't fix a security vulnerability per se, but affects security feature - module signing) - **Exception category**: Build fix - these are explicitly allowed in stable
### 4. SCOPE AND RISK ASSESSMENT
- **Lines changed**: 1 line (trivial) - **Files touched**: 1 file (`scripts/Makefile.modinst`) - **Complexity**: Extremely simple - just changing `srctree` to `objtree` - **Subsystem**: kbuild (build system) - **Risk level**: **VERY LOW** - Only affects out-of-tree module signing with separate source/build directories - Only affects configurations with `CONFIG_MODULE_SIG_FORCE=y` or `CONFIG_MODULE_SIG_ALL=y` - The change is logically correct and consistent with the rest of the code - Cannot break anything that was working before
### 5. USER IMPACT
- **Who is affected**: - Users building out-of-tree modules (e.g., NVIDIA drivers, VirtualBox, ZFS) - With separate source and build directories (`O=/path/to/build`) - With module signature enforcement enabled - **Severity**: HIGH for affected users - module signing completely fails - **User reports**: The commit message shows this was reported as a real user problem with specific error messages - **Prevalence**: Common scenario for distribution builders and enterprise environments
### 6. STABILITY INDICATORS
- **Tested-by: Nicolas Schier** - the kbuild maintainer tested it - **Reviewed-by: Nathan Chancellor** - well-known kernel developer reviewed it - **Link to patch discussion**: Shows proper review process - **Age in mainline**: This appears to be a recent commit (October 2025 in the patch date)
### 7. DEPENDENCY CHECK
**Critical finding**: This commit has a dependency: - It requires commit **25ff08aa43e37** ("kbuild: Fix signing issue for external modules") to be present first - 25ff08aa43e37 requires commit **13b25489b6f8** ("kbuild: change working directory to external module directory with M=")
**Affected stable versions**: - v6.13.x: Has 13b25489b6f8 (the bug) and backported 25ff08aa43e37 (partial fix) → **NEEDS this patch** - v6.14.x: Has both 13b25489b6f8 and 25ff08aa43e37 → **NEEDS this patch** - v6.15.x: Has both → **NEEDS this patch** - v6.16.x: Has both → **NEEDS this patch** - v6.17.x: Has both → **NEEDS this patch** - v6.6.x and older: Does NOT have 13b25489b6f8 → **Does NOT need this patch** (and would break if applied)
**Backport note**: This commit should ONLY be backported to stable trees that already have: 1. Commit 13b25489b6f8 (the original behavior change) 2. Commit 25ff08aa43e37 (the partial fix)
This means v6.13+ stable trees only.
### SUMMARY
This commit is an **excellent candidate for stable backport** to kernel versions v6.13+:
**Positive factors:** 1. ✅ Fixes a real bug that causes complete failure of module signing 2. ✅ Extremely small change (1 line, 1 word) 3. ✅ Zero risk of regression (only fixes broken behavior) 4. ✅ Properly reviewed and tested by kbuild maintainers 5. ✅ Complements an existing fix that was already backported to stable 6. ✅ Build fix category - explicitly allowed in stable rules 7. ✅ Clear, well-documented commit message 8. ✅ Affects users who follow best practices (separate build directory)
**Concerns:** 1. ⚠️ No explicit `Cc: stable@vger.kernel.org` tag (but the first fix also didn't have one and was still backported) 2. ⚠️ No explicit `Fixes:` tag (but logically fixes the same issue as 25ff08aa43e37) 3. ⚠️ Must only be applied to v6.13+ stable trees (where 13b25489b6f8 exists)
The commit passes all stable kernel criteria: it's obviously correct, fixes a real user-visible bug, is small and surgical, has no new features, and has been tested. The incomplete fix in stable trees is currently causing module signing to fail for users with separate source/build directories.
**YES**
scripts/Makefile.modinst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst index 1628198f3e830..9ba45e5b32b18 100644 --- a/scripts/Makefile.modinst +++ b/scripts/Makefile.modinst @@ -100,7 +100,7 @@ endif # Don't stop modules_install even if we can't sign external modules. # ifeq ($(filter pkcs11:%, $(CONFIG_MODULE_SIG_KEY)),) -sig-key := $(if $(wildcard $(CONFIG_MODULE_SIG_KEY)),,$(srctree)/)$(CONFIG_MODULE_SIG_KEY) +sig-key := $(if $(wildcard $(CONFIG_MODULE_SIG_KEY)),,$(objtree)/)$(CONFIG_MODULE_SIG_KEY) else sig-key := $(CONFIG_MODULE_SIG_KEY) endif
From: Hans de Goede hansg@kernel.org
[ Upstream commit a8e5a110c0c38e08e5dd66356cd1156e91cf88e1 ]
The Acer A1 840 tablet contains quite generic names in the sys_vendor and product_name DMI strings, without this patch brcmfmac will try to load: brcmfmac43340-sdio.Insyde-BayTrail.txt as nvram file which is a bit too generic.
Add a DMI quirk so that a unique and clearly identifiable nvram file name is used on the Acer A1 840 tablet.
Acked-by: Arend van Spriel arend.vanspriel@broadcom.com Signed-off-by: Hans de Goede hansg@kernel.org Link: https://patch.msgid.link/20251103100314.353826-1-hansg@kernel.org Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
## Analysis of Commit for Stable Backporting
### 1. COMMIT MESSAGE ANALYSIS
**Subject:** wifi: brcmfmac: Add DMI nvram filename quirk for Acer A1 840 tablet
**Key observations:** - No `Cc: stable@vger.kernel.org` tag present - No `Fixes:` tag pointing to a prior commit - The commit explains that the tablet has generic DMI strings ("Insyde" / "BayTrail") - Without the patch, brcmfmac loads `brcmfmac43340-sdio.Insyde- BayTrail.txt` which is "a bit too generic"
The wording "a bit too generic" suggests this is more of an improvement/optimization rather than fixing broken functionality.
### 2. CODE CHANGE ANALYSIS
The change adds: 1. A new `brcmf_dmi_data` structure: ```c static const struct brcmf_dmi_data acer_a1_840_data = { BRCM_CC_43340_CHIP_ID, 2, "acer-a1-840" }; ```
2. A DMI match entry with three match criteria (vendor, product, BIOS date) to identify this specific tablet and associate it with the new data structure.
**Technical nature:** Pure data addition - adds static const data and a DMI table entry using existing infrastructure.
### 3. CLASSIFICATION
This is a **hardware quirk** for DMI-based nvram filename selection. Hardware quirks are generally allowable in stable per the documented exceptions.
### 4. SCOPE AND RISK ASSESSMENT
- **Size:** ~15 lines added, very small - **Files:** Single file (dmi.c) - **Risk:** Extremely low - only affects the specific Acer A1 840 tablet - **Pattern:** Follows identical pattern to ~15 other existing DMI quirks in this file
### 5. USER IMPACT
- **Who is affected:** Only Acer Iconia One 8 A1-840 tablet owners - **Severity:** The commit message says the generic filename is "a bit too generic" - not that WiFi is broken - **Nature:** This enables using a device-specific nvram file instead of a generic one
### 6. STABILITY INDICATORS
- Acked by Broadcom maintainer (Arend van Spriel) - Hans de Goede is well-known for x86 tablet quirks - No explicit stable request from maintainers
### 7. DEPENDENCY CHECK
- Requires corresponding `brcmfmac43340-sdio.acer-a1-840.txt` file in linux-firmware - No code dependencies on other kernel commits - DMI quirk infrastructure exists in all stable trees
### Decision Rationale
**Arguments for backporting:** - Falls under "hardware quirks" exception - Zero risk to other systems - Small, contained change - Uses existing infrastructure
**Arguments against backporting:** 1. **No stable tags:** The maintainers did not add `Cc: stable@vger.kernel.org`, suggesting they don't consider this critical for stable 2. **Not fixing broken functionality:** The commit says the generic name is "a bit too generic" - not that WiFi doesn't work. This is an improvement, not a fix for completely broken hardware 3. **Firmware dependency:** Requires a corresponding nvram file in linux-firmware that may not be present in stable distributions 4. **Enablement vs Fix:** This is adding device-specific customization rather than fixing a bug. The generic nvram file path still works, just isn't optimally specific 5. **No reported bug:** No `Reported-by:` tag or link to a bug report indicating users are affected
### Conclusion
While hardware quirks are sometimes appropriate for stable, this particular quirk is more of an enhancement to use a more specific nvram filename rather than a fix for broken functionality. The maintainer's decision not to add stable tags, combined with the "a bit too generic" language (rather than "doesn't work"), indicates this is a quality-of- life improvement rather than a critical fix. Stable trees should focus on fixes for actual broken functionality, not optimizations for firmware filename selection.
**NO**
.../net/wireless/broadcom/brcm80211/brcmfmac/dmi.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c index c3a602197662b..abe7f6501e5ed 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c @@ -24,6 +24,10 @@ static const struct brcmf_dmi_data acepc_t8_data = { BRCM_CC_4345_CHIP_ID, 6, "acepc-t8" };
+static const struct brcmf_dmi_data acer_a1_840_data = { + BRCM_CC_43340_CHIP_ID, 2, "acer-a1-840" +}; + /* The Chuwi Hi8 Pro uses the same Ampak AP6212 module as the Chuwi Vi8 Plus * and the nvram for the Vi8 Plus is already in linux-firmware, so use that. */ @@ -91,6 +95,16 @@ static const struct dmi_system_id dmi_platform_data[] = { }, .driver_data = (void *)&acepc_t8_data, }, + { + /* Acer Iconia One 8 A1-840 (non FHD version) */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Insyde"), + DMI_MATCH(DMI_PRODUCT_NAME, "BayTrail"), + /* Above strings are too generic also match BIOS date */ + DMI_MATCH(DMI_BIOS_DATE, "04/01/2014"), + }, + .driver_data = (void *)&acer_a1_840_data, + }, { /* Chuwi Hi8 Pro with D2D3_Hi8Pro.233 BIOS */ .matches = {
From: Shuai Zhang quic_shuaz@quicinc.com
[ Upstream commit a8b38d19857d42a1f2e90c9d9b0f74de2500acd7 ]
The new platform uses the QCA2066 chip along with a new board ID, which requires a dedicated firmware file to ensure proper initialization. Without this entry, the driver cannot locate and load the correct firmware, resulting in Bluetooth bring-up failure.
This patch adds a new entry to the firmware table for QCA2066 so that the driver can correctly identify the board ID and load the appropriate firmware from 'qca/QCA2066/' in the linux-firmware repository.
Signed-off-by: Shuai Zhang quic_shuaz@quicinc.com Acked-by: Dmitry Baryshkov dmitry.baryshkov@oss.qualcomm.com Signed-off-by: Luiz Augusto von Dentz luiz.von.dentz@intel.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
drivers/bluetooth/btusb.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index cc03c8c38b16f..22f1932fe9126 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -3267,6 +3267,7 @@ static const struct qca_device_info qca_devices_table[] = {
static const struct qca_custom_firmware qca_custom_btfws[] = { { 0x00130201, 0x030A, "QCA2066" }, + { 0x00130201, 0x030B, "QCA2066" }, { }, };
From: Viacheslav Dubeyko slava@dubeyko.com
[ Upstream commit 3f04ee216bc1406cb6214ceaa7e544114108e0fa ]
The xfstests' test-case generic/101 leaves HFS+ volume in corrupted state:
sudo ./check generic/101 FSTYP -- hfsplus PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.17.0-rc1+ #4 SMP PREEMPT_DYNAMIC Wed Oct 1 15:02:44 PDT 2025 MKFS_OPTIONS -- /dev/loop51 MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch
generic/101 _check_generic_filesystem: filesystem on /dev/loop51 is inconsistent (see XFSTESTS-2/xfstests-dev/results//generic/101.full for details)
Ran: generic/101 Failures: generic/101 Failed 1 of 1 tests
sudo fsck.hfsplus -d /dev/loop51 ** /dev/loop51 Using cacheBlockSize=32K cacheTotalBlock=1024 cacheSize=32768K. Executing fsck_hfs (version 540.1-Linux). ** Checking non-journaled HFS Plus Volume. The volume name is untitled ** Checking extents overflow file. ** Checking catalog file. ** Checking multi-linked files. ** Checking catalog hierarchy. ** Checking extended attributes file. ** Checking volume bitmap. ** Checking volume information. Invalid volume free block count (It should be 2614350 instead of 2614382) Verify Status: VIStat = 0x8000, ABTStat = 0x0000 EBTStat = 0x0000 CBTStat = 0x0000 CatStat = 0x00000000 ** Repairing volume. ** Rechecking volume. ** Checking non-journaled HFS Plus Volume. The volume name is untitled ** Checking extents overflow file. ** Checking catalog file. ** Checking multi-linked files. ** Checking catalog hierarchy. ** Checking extended attributes file. ** Checking volume bitmap. ** Checking volume information. ** The volume untitled was repaired successfully.
This test executes such steps: "Test that if we truncate a file to a smaller size, then truncate it to its original size or a larger size, then fsyncing it and a power failure happens, the file will have the range [first_truncate_size, last_size[ with all bytes having a value of 0x00 if we read it the next time the filesystem is mounted.".
HFS+ keeps volume's free block count in the superblock. However, hfsplus_file_fsync() doesn't store superblock's content. As a result, superblock contains not correct value of free blocks if a power failure happens.
This patch adds functionality of saving superblock's content during hfsplus_file_fsync() call.
sudo ./check generic/101 FSTYP -- hfsplus PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.18.0-rc3+ #96 SMP PREEMPT_DYNAMIC Wed Nov 19 12:47:37 PST 2025 MKFS_OPTIONS -- /dev/loop51 MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch
generic/101 32s ... 30s Ran: generic/101 Passed all 1 tests
sudo fsck.hfsplus -d /dev/loop51 ** /dev/loop51 Using cacheBlockSize=32K cacheTotalBlock=1024 cacheSize=32768K. Executing fsck_hfs (version 540.1-Linux). ** Checking non-journaled HFS Plus Volume. The volume name is untitled ** Checking extents overflow file. ** Checking catalog file. ** Checking multi-linked files. ** Checking catalog hierarchy. ** Checking extended attributes file. ** Checking volume bitmap. ** Checking volume information. ** The volume untitled appears to be OK.
Signed-off-by: Viacheslav Dubeyko slava@dubeyko.com cc: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de cc: Yangtao Li frank.li@vivo.com cc: linux-fsdevel@vger.kernel.org Link: https://lore.kernel.org/r/20251119223219.1824434-1-slava@dubeyko.com Signed-off-by: Viacheslav Dubeyko slava@dubeyko.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
fs/hfsplus/hfsplus_fs.h | 2 + fs/hfsplus/inode.c | 9 +++++ fs/hfsplus/super.c | 87 +++++++++++++++++++++++++---------------- 3 files changed, 65 insertions(+), 33 deletions(-)
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index 89e8b19c127b0..de801942ae471 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h @@ -477,6 +477,8 @@ int hfs_part_find(struct super_block *sb, sector_t *part_start, /* super.c */ struct inode *hfsplus_iget(struct super_block *sb, unsigned long ino); void hfsplus_mark_mdb_dirty(struct super_block *sb); +void hfsplus_prepare_volume_header_for_commit(struct hfsplus_vh *vhdr); +int hfsplus_commit_superblock(struct super_block *sb);
/* tables.c */ extern u16 hfsplus_case_fold_table[]; diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index e290e417ed3a7..7ae6745ca7ae1 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c @@ -325,6 +325,7 @@ int hfsplus_file_fsync(struct file *file, loff_t start, loff_t end, struct inode *inode = file->f_mapping->host; struct hfsplus_inode_info *hip = HFSPLUS_I(inode); struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb); + struct hfsplus_vh *vhdr = sbi->s_vhdr; int error = 0, error2;
error = file_write_and_wait_range(file, start, end); @@ -368,6 +369,14 @@ int hfsplus_file_fsync(struct file *file, loff_t start, loff_t end, error = error2; }
+ mutex_lock(&sbi->vh_mutex); + hfsplus_prepare_volume_header_for_commit(vhdr); + mutex_unlock(&sbi->vh_mutex); + + error2 = hfsplus_commit_superblock(inode->i_sb); + if (!error) + error = error2; + if (!test_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags)) blkdev_issue_flush(inode->i_sb->s_bdev);
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 16bc4abc67e08..67a7a2a093476 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c @@ -187,40 +187,15 @@ static void hfsplus_evict_inode(struct inode *inode) } }
-static int hfsplus_sync_fs(struct super_block *sb, int wait) +int hfsplus_commit_superblock(struct super_block *sb) { struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); struct hfsplus_vh *vhdr = sbi->s_vhdr; int write_backup = 0; - int error, error2; - - if (!wait) - return 0; + int error = 0, error2;
hfs_dbg("starting...\n");
- /* - * Explicitly write out the special metadata inodes. - * - * While these special inodes are marked as hashed and written - * out peridocically by the flusher threads we redirty them - * during writeout of normal inodes, and thus the life lock - * prevents us from getting the latest state to disk. - */ - error = filemap_write_and_wait(sbi->cat_tree->inode->i_mapping); - error2 = filemap_write_and_wait(sbi->ext_tree->inode->i_mapping); - if (!error) - error = error2; - if (sbi->attr_tree) { - error2 = - filemap_write_and_wait(sbi->attr_tree->inode->i_mapping); - if (!error) - error = error2; - } - error2 = filemap_write_and_wait(sbi->alloc_file->i_mapping); - if (!error) - error = error2; - mutex_lock(&sbi->vh_mutex); mutex_lock(&sbi->alloc_mutex); vhdr->free_blocks = cpu_to_be32(sbi->free_blocks); @@ -249,11 +224,52 @@ static int hfsplus_sync_fs(struct super_block *sb, int wait) sbi->part_start + sbi->sect_count - 2, sbi->s_backup_vhdr_buf, NULL, REQ_OP_WRITE); if (!error) - error2 = error; + error = error2; out: mutex_unlock(&sbi->alloc_mutex); mutex_unlock(&sbi->vh_mutex);
+ hfs_dbg("finished: err %d\n", error); + + return error; +} + +static int hfsplus_sync_fs(struct super_block *sb, int wait) +{ + struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); + int error, error2; + + if (!wait) + return 0; + + hfs_dbg("starting...\n"); + + /* + * Explicitly write out the special metadata inodes. + * + * While these special inodes are marked as hashed and written + * out peridocically by the flusher threads we redirty them + * during writeout of normal inodes, and thus the life lock + * prevents us from getting the latest state to disk. + */ + error = filemap_write_and_wait(sbi->cat_tree->inode->i_mapping); + error2 = filemap_write_and_wait(sbi->ext_tree->inode->i_mapping); + if (!error) + error = error2; + if (sbi->attr_tree) { + error2 = + filemap_write_and_wait(sbi->attr_tree->inode->i_mapping); + if (!error) + error = error2; + } + error2 = filemap_write_and_wait(sbi->alloc_file->i_mapping); + if (!error) + error = error2; + + error2 = hfsplus_commit_superblock(sb); + if (!error) + error = error2; + if (!test_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags)) blkdev_issue_flush(sb->s_bdev);
@@ -395,6 +411,15 @@ static const struct super_operations hfsplus_sops = { .show_options = hfsplus_show_options, };
+void hfsplus_prepare_volume_header_for_commit(struct hfsplus_vh *vhdr) +{ + vhdr->last_mount_vers = cpu_to_be32(HFSP_MOUNT_VERSION); + vhdr->modify_date = hfsp_now2mt(); + be32_add_cpu(&vhdr->write_count, 1); + vhdr->attributes &= cpu_to_be32(~HFSPLUS_VOL_UNMNT); + vhdr->attributes |= cpu_to_be32(HFSPLUS_VOL_INCNSTNT); +} + static int hfsplus_fill_super(struct super_block *sb, struct fs_context *fc) { struct hfsplus_vh *vhdr; @@ -562,11 +587,7 @@ static int hfsplus_fill_super(struct super_block *sb, struct fs_context *fc) * H+LX == hfsplusutils, H+Lx == this driver, H+lx is unused * all three are registered with Apple for our use */ - vhdr->last_mount_vers = cpu_to_be32(HFSP_MOUNT_VERSION); - vhdr->modify_date = hfsp_now2mt(); - be32_add_cpu(&vhdr->write_count, 1); - vhdr->attributes &= cpu_to_be32(~HFSPLUS_VOL_UNMNT); - vhdr->attributes |= cpu_to_be32(HFSPLUS_VOL_INCNSTNT); + hfsplus_prepare_volume_header_for_commit(vhdr); hfsplus_sync_fs(sb, 1);
if (!sbi->hidden_dir) {
From: Yang Chenzhi yang.chenzhi@vivo.com
[ Upstream commit 152af114287851583cf7e0abc10129941f19466a ]
When sync() and link() are called concurrently, both threads may enter hfs_bnode_find() without finding the node in the hash table and proceed to create it.
Thread A: hfsplus_write_inode() -> hfsplus_write_system_inode() -> hfs_btree_write() -> hfs_bnode_find(tree, 0) -> __hfs_bnode_create(tree, 0)
Thread B: hfsplus_create_cat() -> hfs_brec_insert() -> hfs_bnode_split() -> hfs_bmap_alloc() -> hfs_bnode_find(tree, 0) -> __hfs_bnode_create(tree, 0)
In this case, thread A creates the bnode, sets refcnt=1, and hashes it. Thread B also tries to create the same bnode, notices it has already been inserted, drops its own instance, and uses the hashed one without getting the node.
```
node2 = hfs_bnode_findhash(tree, cnid); if (!node2) { <- Thread A hash = hfs_bnode_hash(cnid); node->next_hash = tree->node_hash[hash]; tree->node_hash[hash] = node; tree->node_hash_cnt++; } else { <- Thread B spin_unlock(&tree->hash_lock); kfree(node); wait_event(node2->lock_wq, !test_bit(HFS_BNODE_NEW, &node2->flags)); return node2; } ```
However, hfs_bnode_find() requires each call to take a reference. Here both threads end up setting refcnt=1. When they later put the node, this triggers:
BUG_ON(!atomic_read(&node->refcnt))
In this scenario, Thread B in fact finds the node in the hash table rather than creating a new one, and thus must take a reference.
Fix this by calling hfs_bnode_get() when reusing a bnode newly created by another thread to ensure the refcount is updated correctly.
A similar bug was fixed in HFS long ago in commit a9dc087fd3c4 ("fix missing hfs_bnode_get() in __hfs_bnode_create") but the same issue remained in HFS+ until now.
Reported-by: syzbot+005d2a9ecd9fbf525f6a@syzkaller.appspotmail.com Signed-off-by: Yang Chenzhi yang.chenzhi@vivo.com Signed-off-by: Viacheslav Dubeyko slava@dubeyko.com Link: https://lore.kernel.org/r/20250829093912.611853-1-yang.chenzhi@vivo.com Signed-off-by: Viacheslav Dubeyko slava@dubeyko.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
## Analysis Summary
### 1. COMMIT MESSAGE ANALYSIS
**Subject:** "hfsplus: fix missing hfs_bnode_get() in __hfs_bnode_create"
**Key signals:** - Clear "fix" keyword indicating bug fix - Reported-by syzbot - reproducible crash bug - Detailed race condition explanation with call stacks - References identical HFS fix from 2022 (commit a9dc087fd3c4) - No explicit `Cc: stable` tag, but no `Fixes:` tag either since the bug exists from the file's creation
### 2. CODE CHANGE ANALYSIS
**The Bug:** When `sync()` and `link()` are called concurrently, both threads may race into `__hfs_bnode_create()`: - Thread A creates a bnode with `refcnt=1` and inserts it into the hash table - Thread B finds the hash table entry, but returns the node **without incrementing refcnt** - Both threads believe they own a reference, but only one reference exists - When both call `hfs_bnode_put()`, the second call triggers: `BUG_ON(!atomic_read(&node->refcnt))`
**The Fix:** Single line addition at `fs/hfsplus/bnode.c:484`: ```c } else { + hfs_bnode_get(node2); // <-- Missing refcount increment added spin_unlock(&tree->hash_lock); kfree(node); ```
**Why it's correct:** `hfs_bnode_get()` simply does `atomic_inc(&node->refcnt)` (line 658), ensuring correct reference counting when reusing a shared bnode.
### 3. CLASSIFICATION
- **Bug fix:** YES - fixes a crash (BUG_ON kernel panic) - **Feature addition:** NO - **Security consideration:** Crash can be triggered by normal operations - potential DoS vector
### 4. SCOPE AND RISK ASSESSMENT
| Metric | Value | |--------|-------| | Lines changed | 1 | | Files touched | 1 | | Complexity | Very low | | Subsystem | HFS+ filesystem | | Regression risk | Very low |
The fix is a **single function call** that mirrors a proven fix from HFS (commit a9dc087fd3c4) that has been stable since December 2022.
### 5. USER IMPACT
- **Affected users:** Anyone using HFS+ filesystems (common for Mac disk compatibility, external drives, dual-boot systems) - **Trigger condition:** Concurrent sync() and link() operations - can occur in normal workloads - **Severity:** **KERNEL CRASH** (BUG_ON triggers panic)
### 6. STABILITY INDICATORS
- **syzbot reported:** Bug is reproducible - **Maintainer signed:** Yes (Viacheslav Dubeyko, HFS+ maintainer) - **LKML link:** Present - **Precedent:** Identical fix applied to HFS in 2022 with no regressions
### 7. DEPENDENCY CHECK
- **Dependencies:** None - completely self-contained - **Applies to stable:** The affected code pattern has existed unchanged for many years in stable trees
## Final Assessment
**This commit should be backported to stable kernels.**
**Rationale:** 1. **Fixes a real crash** - BUG_ON triggers kernel panic in a reproducible race condition 2. **Minimal and surgical** - Single line change adding one function call 3. **Obviously correct** - Adds missing reference count increment, matching HFS pattern 4. **Proven safe** - Identical fix in HFS has been stable for 2+ years 5. **No dependencies** - Will apply cleanly to all stable kernels 6. **Real user impact** - HFS+ is commonly used for Mac disk compatibility
The lack of explicit `Cc: stable` tag does not preclude backporting when all other stable criteria are clearly met. This is a textbook case of a small, obviously correct fix for a real crash bug.
**YES**
fs/hfsplus/bnode.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index edf7e27e1e375..482a6c5faa197 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -481,6 +481,7 @@ static struct hfs_bnode *__hfs_bnode_create(struct hfs_btree *tree, u32 cnid) tree->node_hash[hash] = node; tree->node_hash_cnt++; } else { + hfs_bnode_get(node2); spin_unlock(&tree->hash_lock); kfree(node); wait_event(node2->lock_wq,
From: Chingbin Li liqb365@163.com
[ Upstream commit 8dbbb5423c0802ec21266765de80fd491868fab1 ]
Add VID 2b89 & PID 6275 for Realtek RTL8761BUV USB Bluetooth chip.
The information in /sys/kernel/debug/usb/devices about the Bluetooth device is listed as the below.
T: Bus=01 Lev=01 Prnt=01 Port=02 Cnt=01 Dev#= 6 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=2b89 ProdID=6275 Rev= 2.00 S: Manufacturer=Realtek S: Product=Bluetooth Radio S: SerialNumber=00E04C239987 C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
Signed-off-by: Chingbin Li liqb365@163.com Signed-off-by: Luiz Augusto von Dentz luiz.von.dentz@intel.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
drivers/bluetooth/btusb.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index fa683bb7f0b49..c70e79e69be8d 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -781,6 +781,8 @@ static const struct usb_device_id quirks_table[] = { BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x2b89, 0x8761), .driver_info = BTUSB_REALTEK | BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x2b89, 0x6275), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH },
/* Additional Realtek 8821AE Bluetooth devices */ { USB_DEVICE(0x0b05, 0x17dc), .driver_info = BTUSB_REALTEK },
From: Pedro Demarchi Gomes pedrodemargomes@gmail.com
[ Upstream commit d1693a7d5a38acf6424235a6070bcf5b186a360d ]
When mounting, sb->s_blocksize is used to read the boot_block without being defined or validated. Set a dummy blocksize before attempting to read the boot_block.
The issue can be triggered with the following syz reproducer:
mkdirat(0xffffffffffffff9c, &(0x7f0000000080)='./file1\x00', 0x0) r4 = openat$nullb(0xffffffffffffff9c, &(0x7f0000000040), 0x121403, 0x0) ioctl$FS_IOC_SETFLAGS(r4, 0x40081271, &(0x7f0000000980)=0x4000) mount(&(0x7f0000000140)=@nullb, &(0x7f0000000040)='./cgroup\x00', &(0x7f0000000000)='ntfs3\x00', 0x2208004, 0x0) syz_clone(0x88200200, 0x0, 0x0, 0x0, 0x0, 0x0)
Here, the ioctl sets the bdev block size to 16384. During mount, get_tree_bdev_flags() calls sb_set_blocksize(sb, block_size(bdev)), but since block_size(bdev) > PAGE_SIZE, sb_set_blocksize() leaves sb->s_blocksize at zero.
Later, ntfs_init_from_boot() attempts to read the boot_block while sb->s_blocksize is still zero, which triggers the bug.
Reported-by: syzbot+f4f84b57a01d6b8364ad@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=f4f84b57a01d6b8364ad Signed-off-by: Pedro Demarchi Gomes pedrodemargomes@gmail.com [almaz.alexandrovich@paragon-software.com: changed comment style, added return value handling] Signed-off-by: Konstantin Komarov almaz.alexandrovich@paragon-software.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
Now I have a complete picture of the issue. Let me summarize my analysis:
## Summary of Analysis
### The Bug
The commit fixes a bug in ntfs3's `ntfs_init_from_boot()` function where `ntfs_bread()` is called to read the boot block **before** `sb->s_blocksize` is properly set.
### Root Cause Analysis
1. **Mount Flow**: When mounting an ntfs3 filesystem: - `get_tree_bdev()` calls `setup_bdev_super()` which calls `sb_set_blocksize(sb, block_size(bdev))` - If `block_size(bdev) > PAGE_SIZE` (which can happen via ioctl `FS_IOC_SETFLAGS` setting bdev block size to 16384 as shown in the reproducer), and the filesystem doesn't have `FS_LBS` flag, `sb_set_blocksize()` returns 0 and leaves `sb->s_blocksize = 0`
2. **The Crash Path**: In `ntfs_init_from_boot()`: ```c sbi->volume.blocks = dev_size >> PAGE_SHIFT; // sb->s_blocksize is 0 here! bh = ntfs_bread(sb, boot_block); // Uses sb->s_blocksize = 0 ```
3. **Cascade to Infinite Loop**: - `ntfs_bread()` → `sb_bread_unmovable()` → `__bread_gfp()` with size=0 - `bdev_getblk()` → `__getblk_slow()` → `grow_buffers()` → `grow_dev_folio()` → `folio_alloc_buffers()` - In `folio_alloc_buffers()`: `while ((offset -= size) >= 0)` with size=0 causes infinite loop
### The Fix
The fix adds a call to `sb_min_blocksize(sb, PAGE_SIZE)` before attempting to read the boot block:
```c /* Set dummy blocksize to read boot_block. */ if (!sb_min_blocksize(sb, PAGE_SIZE)) { return -EINVAL; } ```
This ensures: 1. `sb->s_blocksize` is set to at least the device's logical block size, capped at PAGE_SIZE 2. If this fails, mount fails gracefully with `-EINVAL` instead of hanging
### Backport Assessment
**STRONG YES signals:** 1. ✅ **Fixes a real crash/hang** - System hangs due to infinite loop in `folio_alloc_buffers()` 2. ✅ **Syzbot reported** - Has syzkaller reproducer (`f4f84b57a01d6b8364ad`) 3. ✅ **Small, surgical fix** - Only 4 lines added 4. ✅ **Clear, obvious fix** - Sets blocksize before using it for reads 5. ✅ **Uses well-established API** - `sb_min_blocksize()` is a standard helper used by many filesystems 6. ✅ **Affects production users** - ntfs3 is widely used (included since 5.15) 7. ✅ **Denial of Service potential** - A local user can trigger the hang
**Risk Assessment:** - **Very Low Risk**: The fix adds a safety check before an I/O operation - **No behavioral change** for normal cases - the blocksize would have been set to PAGE_SIZE anyway after successful boot read - **Graceful failure** if `sb_min_blocksize()` fails (which would be very rare in practice)
**Stable Trees Affected:** - All stable trees with ntfs3: 5.15.y, 6.1.y, 6.6.y, 6.10.y, 6.11.y, etc. - The bug has existed since ntfs3 was introduced in v5.15 - The recent `FS_LBS` change (March 2025) made it easier to trigger but the underlying issue predates it
**Dependencies:** - The fix is standalone and uses existing kernel APIs - No other patches required for backport - `sb_min_blocksize()` has been available since at least 2.6.x
**YES**
fs/ntfs3/super.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c index ddff94c091b8c..e6c0908e27c29 100644 --- a/fs/ntfs3/super.c +++ b/fs/ntfs3/super.c @@ -933,6 +933,11 @@ static int ntfs_init_from_boot(struct super_block *sb, u32 sector_size,
sbi->volume.blocks = dev_size >> PAGE_SHIFT;
+ /* Set dummy blocksize to read boot_block. */ + if (!sb_min_blocksize(sb, PAGE_SIZE)) { + return -EINVAL; + } + read_boot: bh = ntfs_bread(sb, boot_block); if (!bh)
From: Viacheslav Dubeyko slava@dubeyko.com
[ Upstream commit 24e17a29cf7537f0947f26a50f85319abd723c6c ]
The xfstests' test-case generic/073 leaves HFS+ volume in corrupted state:
sudo ./check generic/073 FSTYP -- hfsplus PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.17.0-rc1+ #4 SMP PREEMPT_DYNAMIC Wed Oct 1 15:02:44 PDT 2025 MKFS_OPTIONS -- /dev/loop51 MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch
generic/073 _check_generic_filesystem: filesystem on /dev/loop51 is inconsistent (see XFSTESTS-2/xfstests-dev/results//generic/073.full for details)
Ran: generic/073 Failures: generic/073 Failed 1 of 1 tests
sudo fsck.hfsplus -d /dev/loop51 ** /dev/loop51 Using cacheBlockSize=32K cacheTotalBlock=1024 cacheSize=32768K. Executing fsck_hfs (version 540.1-Linux). ** Checking non-journaled HFS Plus Volume. The volume name is untitled ** Checking extents overflow file. ** Checking catalog file. ** Checking multi-linked files. ** Checking catalog hierarchy. Invalid directory item count (It should be 1 instead of 0) ** Checking extended attributes file. ** Checking volume bitmap. ** Checking volume information. Verify Status: VIStat = 0x0000, ABTStat = 0x0000 EBTStat = 0x0000 CBTStat = 0x0000 CatStat = 0x00004000 ** Repairing volume. ** Rechecking volume. ** Checking non-journaled HFS Plus Volume. The volume name is untitled ** Checking extents overflow file. ** Checking catalog file. ** Checking multi-linked files. ** Checking catalog hierarchy. ** Checking extended attributes file. ** Checking volume bitmap. ** Checking volume information. ** The volume untitled was repaired successfully.
The test is doing these steps on final phase:
mv $SCRATCH_MNT/testdir_1/bar $SCRATCH_MNT/testdir_2/bar $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/testdir_1 $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/foo
So, we move file bar from testdir_1 into testdir_2 folder. It means that HFS+ logic decrements the number of entries in testdir_1 and increments number of entries in testdir_2. Finally, we do fsync only for testdir_1 and foo but not for testdir_2. As a result, this is the reason why fsck.hfsplus detects the volume corruption afterwards.
This patch fixes the issue by means of adding the hfsplus_cat_write_inode() call for old_dir and new_dir in hfsplus_rename() after the successful ending of hfsplus_rename_cat(). This method makes modification of in-core inode objects for old_dir and new_dir but it doesn't save these modifications in Catalog File's entries. It was expected that hfsplus_write_inode() will save these modifications afterwards. However, because generic/073 does fsync only for testdir_1 and foo then testdir_2 modification hasn't beed saved into Catalog File's entry and it was flushed without this modification. And it was detected by fsck.hfsplus. Now, hfsplus_rename() stores in Catalog File all modified entries and correct state of Catalog File will be flushed during hfsplus_file_fsync() call. Finally, it makes fsck.hfsplus happy.
sudo ./check generic/073 FSTYP -- hfsplus PLATFORM -- Linux/x86_64 hfsplus-testing-0001 6.18.0-rc3+ #93 SMP PREEMPT_DYNAMIC Wed Nov 12 14:37:49 PST 2025 MKFS_OPTIONS -- /dev/loop51 MOUNT_OPTIONS -- /dev/loop51 /mnt/scratch
generic/073 32s ... 32s Ran: generic/073 Passed all 1 tests
Signed-off-by: Viacheslav Dubeyko slava@dubeyko.com cc: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de cc: Yangtao Li frank.li@vivo.com cc: linux-fsdevel@vger.kernel.org Link: https://lore.kernel.org/r/20251112232522.814038-1-slava@dubeyko.com Signed-off-by: Viacheslav Dubeyko slava@dubeyko.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
Based on my thorough analysis, here is my assessment:
---
## COMMIT ANALYSIS
### 1. PROBLEM DESCRIPTION This commit fixes a **volume corruption issue** in HFS+ where renaming a file between directories can lead to an inconsistent catalog file if only one of the directories is subsequently fsync'd.
**The bug mechanism:** 1. When `hfsplus_rename()` moves a file from `old_dir` to `new_dir`, it calls `hfsplus_rename_cat()` 2. `hfsplus_rename_cat()` modifies both directories in memory: - `dst_dir->i_size++` (destination gains an entry) - `src_dir->i_size--` (source loses an entry) - Marks both dirty with `hfsplus_mark_inode_dirty()` 3. Marking dirty does NOT write to disk - it just flags for later writeback 4. If only one directory is fsync'd (as in xfstests generic/073), the other's changes may be lost 5. This creates a mismatch: the catalog file shows incorrect directory entry counts
**User-visible symptom:** `fsck.hfsplus` reports "Invalid directory item count"
### 2. CODE CHANGE ANALYSIS
The fix is **extremely small and surgical** - only 5 lines added:
```c - if (!res) + if (!res) { new_dentry->d_fsdata = old_dentry->d_fsdata; + + res = hfsplus_cat_write_inode(old_dir); + if (!res) + res = hfsplus_cat_write_inode(new_dir); + } ```
**What it does:** After a successful rename, explicitly calls `hfsplus_cat_write_inode()` for both directories, which writes their catalog entries (including the valence/entry count) to the catalog file immediately.
**Why it's correct:** `hfsplus_cat_write_inode()` is the established function for writing directory catalog entries in HFS+. The fix ensures both directories' updated entry counts are persisted immediately after the rename operation.
### 3. CLASSIFICATION
| Criteria | Assessment | |----------|------------| | Bug type | **Filesystem corruption** - data integrity issue | | Security | Not a CVE, but data corruption is serious | | Cc: stable tag | **No** - maintainer didn't explicitly request backport | | Fixes: tag | **No** - no specific commit cited | | User impact | HIGH for HFS+ users - volume corruption can cause data loss |
### 4. SCOPE AND RISK ASSESSMENT
- **Lines changed:** 5 lines added - **Files touched:** 1 file (`fs/hfsplus/dir.c`) - **Complexity:** Very low - adds two well-established function calls - **Bug age:** Since 2013 (commit `892f6668f3a70` introduced `hfsplus_rename`) - **Risk of regression:** **LOW** - the function being called is already used throughout HFS+ codebase
### 5. USER IMPACT
- **Who uses HFS+?** Mac users dual-booting, legacy Apple volumes, some embedded systems - **Severity:** HIGH - filesystem corruption affects data integrity - **Reproducibility:** Easily triggered by xfstests generic/073
### 6. DEPENDENCY CHECK
- `hfsplus_cat_write_inode()` has existed since the early days of hfsplus - No dependency on other recent commits - Should apply cleanly to all stable trees that include hfsplus
---
## VERDICT
**This commit SHOULD be backported** because:
1. **Fixes a real, serious bug:** Volume corruption is a significant data integrity issue 2. **Obviously correct:** The fix ensures both directories are written after rename - this is fundamental filesystem consistency 3. **Small and contained:** Only 5 lines in a single file, using existing functions 4. **Low regression risk:** Uses well-established `hfsplus_cat_write_inode()` function 5. **Long-standing bug:** Has affected users since 2013 6. **Reproducible:** Standard xfstests test case triggers the bug 7. **Follows established patterns:** Similar to how other filesystems handle rename consistency
While the commit lacks explicit "Cc: stable" and "Fixes:" tags, the stable kernel rules clearly allow important bug fixes for data corruption issues to be backported. The fix is minimal, well-understood, and addresses a real problem that affects HFS+ users.
Sources: - [xfstests generic test for fsync after renaming directory](https://patchwork.kernel.org/project/linux- btrfs/patch/1459330722-3227-1-git-send-email-fdmanana@kernel.org/) - [xfstests GitHub repository](https://github.com/kdave/xfstests)
**YES**
fs/hfsplus/dir.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index 1b3e27a0d5e03..cadf0b5f93422 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c @@ -552,8 +552,13 @@ static int hfsplus_rename(struct mnt_idmap *idmap, res = hfsplus_rename_cat((u32)(unsigned long)old_dentry->d_fsdata, old_dir, &old_dentry->d_name, new_dir, &new_dentry->d_name); - if (!res) + if (!res) { new_dentry->d_fsdata = old_dentry->d_fsdata; + + res = hfsplus_cat_write_inode(old_dir); + if (!res) + res = hfsplus_cat_write_inode(new_dir); + } return res; }
From: Quan Zhou quan.zhou@mediatek.com
[ Upstream commit 066f417be5fd8c7fe581c5550206364735dad7a3 ]
Set the MT76_STATE_MCU_RUNNING bit only after mt7921_load_clc() has successfully completed. Previously, the MCU_RUNNING state was set before loading CLC, which could cause conflict between chip mcu_init retry and mac_reset flow, result in chip init fail and chip abnormal status. By moving the state set after CLC load, firmware initialization becomes robust and resolves init fail issue.
Signed-off-by: Quan Zhou quan.zhou@mediatek.com Reviewed-by: druth@chromium.org Link: https://patch.msgid.link/19ec8e4465142e774f17801025accd0ae2214092.1763465933... Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
# Commit Analysis: wifi: mt76: mt792x: fix wifi init fail by setting MCU_RUNNING after CLC load
## 1. COMMIT MESSAGE ANALYSIS
**Subject:** Clearly indicates a bug fix ("fix wifi init fail")
**Problem described:** Setting `MT76_STATE_MCU_RUNNING` bit before CLC (Country/Legal Configuration) load completion could cause conflicts between MCU init retry and mac_reset flows, resulting in chip initialization failure and abnormal chip status.
**Tags present:** - `Signed-off-by:` Quan Zhou (MediaTek - chip vendor) and Felix Fietkau (mt76 maintainer) - `Reviewed-by:` druth@chromium.org (Chrome OS kernel team - indicates real-world Chromebook impact) - No explicit `Cc: stable@vger.kernel.org` tag - No explicit `Fixes:` tag
## 2. CODE CHANGE ANALYSIS
The change is extremely simple and surgical:
**Before the fix:** ```c set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state); // State set here err = mt7921_load_clc(dev, mt792x_ram_name(dev)); // CLC load after ```
**After the fix:** ```c err = mt7921_load_clc(dev, mt792x_ram_name(dev)); // CLC load first set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state); // State set after success ```
**Technical mechanism:** - `MT76_STATE_MCU_RUNNING` indicates the MCU is fully operational - Setting this flag prematurely (before CLC load) could allow other code paths to think the MCU is ready when it's not - If something triggers MCU init retry or mac_reset during CLC load, there's a race condition - The conflict causes complete initialization failure and abnormal chip state
**Why fix is correct:** - The state bit should only be set when initialization is truly complete - This ensures no code sees MCU_RUNNING during the vulnerable CLC loading phase - Error handling remains intact (if CLC load fails, function returns error)
## 3. CLASSIFICATION
- **Type:** Bug fix - initialization failure fix - **NOT** a feature addition - Fixes a real runtime bug affecting device usability
## 4. SCOPE AND RISK ASSESSMENT
| Factor | Assessment | |--------|------------| | Lines changed | ~6 lines (just moving 1 line in 2 files) | | Files touched | 2 (mt7921/mcu.c, mt7925/mcu.c) | | Complexity | Very low - simple reordering | | Regression risk | LOW - no logic changes, just timing | | Subsystem | Wireless driver (contained) |
The change is almost purely a reordering operation within the same function. If CLC load succeeds, the state gets set (same as before, just later). If it fails, function returns error anyway.
## 5. USER IMPACT
**Affected hardware:** MediaTek mt7921 and mt7925 WiFi chips
These are **extremely common** chips found in: - Many Chromebooks (Chrome OS review indicates this) - Consumer laptops (Dell, Lenovo, HP, etc.) - USB WiFi adapters - Various PC builds
**Severity:** HIGH - WiFi initialization failure = device doesn't work at all - "chip abnormal status" suggests chip may be left in broken state - Users cannot use their WiFi until reboot or driver reload
## 6. STABILITY INDICATORS
- Reviewed by Chromium kernel team (indicates real-world testing on Chromebooks) - From MediaTek engineer (hardware vendor knows their chip) - Accepted by mt76 maintainer Felix Fietkau - Clean, minimal change with clear rationale
## 7. DEPENDENCY CHECK
The change is self-contained. It only reorders existing function calls within `mt7921_run_firmware()` and `mt7925_run_firmware()`. No new dependencies are introduced.
The mt7921 driver has been in stable kernels for some time. The mt7925 is newer and may not exist in older stable trees, but the mt7921 portion would still be valuable.
## STABLE KERNEL CRITERIA CHECK
| Criterion | Met? | Notes | |-----------|------|-------| | Obviously correct | ✅ | Simple reordering, logic is clear | | Fixes real bug | ✅ | WiFi init failure - real user impact | | Small and contained | ✅ | 6 lines, 2 files, same subsystem | | No new features | ✅ | No new APIs or functionality | | No architectural changes | ✅ | Minimal change |
## RISK vs BENEFIT
**Benefit:** High - Fixes WiFi initialization failure on widely-deployed hardware. Without this fix, affected users may have non-functional WiFi.
**Risk:** Very low - The change is a trivial reordering of two operations. The logic remains identical; only the timing of when the state bit is set changes. The fix has been reviewed by the chip vendor and Chrome OS team.
## CONCLUSION
This commit is an ideal candidate for stable backporting:
1. **Fixes a real, user-visible bug** - WiFi doesn't work 2. **Minimal change** - Just reordering one line in each of two files 3. **Well-reviewed** - MediaTek and Chrome OS review 4. **Low regression risk** - No logic changes, simple timing fix 5. **High user impact** - mt7921/mt7925 are very common chips 6. **Contained scope** - Only affects initialization path of specific driver
The lack of `Cc: stable` tag doesn't disqualify it - many legitimate fixes don't include this tag. The important factors are all positive: it fixes a real bug, is small, safe, and affects real users.
**YES**
drivers/net/wireless/mediatek/mt76/mt7921/mcu.c | 2 +- drivers/net/wireless/mediatek/mt76/mt7925/mcu.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c index 86bd33b916a9d..edc1df3c071e5 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c @@ -646,10 +646,10 @@ int mt7921_run_firmware(struct mt792x_dev *dev) if (err) return err;
- set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state); err = mt7921_load_clc(dev, mt792x_ram_name(dev)); if (err) return err; + set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state);
return mt7921_mcu_fw_log_2_host(dev, 1); } diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c index 8eda407e4135e..c12b71b71cfc7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c @@ -1003,10 +1003,10 @@ int mt7925_run_firmware(struct mt792x_dev *dev) if (err) return err;
- set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state); err = mt7925_load_clc(dev, mt792x_ram_name(dev)); if (err) return err; + set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state);
return mt7925_mcu_fw_log_2_host(dev, 1); }
From: Andreas Gruenbacher agruenba@redhat.com
[ Upstream commit dff1fb6d8b7abe5b1119fa060f5d6b3370bf10ac ]
Commit e4a8b5481c59a ("gfs2: Switch to wait_event in gfs2_quotad") broke cyclic statfs syncing, so the numbers reported by "df" could easily get completely out of sync with reality. Fix this by reverting part of commit e4a8b5481c59a for now.
A follow-up commit will clean this code up later.
Signed-off-by: Andreas Gruenbacher agruenba@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
fs/gfs2/quota.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index 2298e06797ac3..f2df01f801b81 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c @@ -1616,7 +1616,7 @@ int gfs2_quotad(void *data)
t = min(quotad_timeo, statfs_timeo);
- t = wait_event_freezable_timeout(sdp->sd_quota_wait, + t -= wait_event_freezable_timeout(sdp->sd_quota_wait, sdp->sd_statfs_force_sync || gfs2_withdrawing_or_withdrawn(sdp) || kthread_should_stop(),
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit 9f33477b9a31a1edfe2df9f1a0359cccb0e16b4c ]
If an interface is set down or, per the previous patch, changes type, radar detection for it should be cancelled. This is done for AP mode in mac80211 (somewhat needlessly, since cfg80211 can do it, but didn't until now), but wasn't handled for mesh, so if radar detection was started and then the interface set down or its type switched (the latter sometimes happning in the hwsim test 'mesh_peer_connected_dfs'), radar detection would be around with the interface unknown to the driver, later leading to some warnings around chanctx usage.
Link: https://patch.msgid.link/20251121174021.290120e419e3.I2a5650c9062e29c988992d... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
## Summary and Analysis
### What the Bug Fixes This commit fixes a cleanup issue where radar detection (DFS CAC) was not properly stopped when a mesh interface was brought down or changed type. This left residual radar detection state that caused warnings about chanctx (channel context) usage, since the driver thought radar detection was still active for an interface that no longer existed.
### Technical Details The fix: 1. Adds a new `cfg80211_stop_radar_detection()` function in `mlme.c` that iterates through all valid links, ends CAC via `rdev_end_cac()`, and sends `NL80211_RADAR_CAC_ABORTED` notification 2. Calls this new function in `cfg80211_leave()` (the cleanup path when interfaces go down)
### Critical Dependencies The code uses **per-link DFS infrastructure** that was introduced in: - **Commit 62c16f219a73c** ("wifi: cfg80211: move DFS related members to links[] in wireless_dev") - September 2024, **first in v6.12**
This commit accesses `wdev->links[link_id].cac_started` - this structure only exists in 6.12+. In older kernels (6.11 and earlier), `cac_started` was a simple top-level member of `wireless_dev`, not per-link.
### Stable Backport Assessment
**Against backporting:** 1. **No `Cc: stable@vger.kernel.org`** - The maintainer (Johannes Berg) did not request stable backporting 2. **No `Fixes:` tag** - No specific commit is identified as introducing the bug 3. **Dependencies on recent code** - The per-link DFS infrastructure only exists in kernel 6.12+ 4. **Cannot apply to LTS trees** - Would require substantial rework for 6.6.y, 6.1.y, 5.15.y, etc. 5. **Not critical severity** - The bug causes kernel warnings, not crashes, security issues, or data corruption 6. **Niche use case** - Mesh networking combined with DFS channels is relatively uncommon 7. **Very new feature** - The affected MLO/per-link DFS code is only one release old
**Supporting backporting:** - Does fix a real bug that causes warnings - Small, localized change (~25 lines) - From a known/trusted maintainer
### Conclusion
This commit fixes a legitimate bug but does **not** meet stable kernel criteria: - The maintainer did not request stable backporting - The affected code only exists in kernel 6.12+, making it only relevant to the most recent stable branch if any - The bug severity (warnings, not crashes/corruption/security) does not warrant the backporting effort - It cannot be cleanly applied to most stable trees due to structural code differences
**NO**
net/wireless/core.c | 1 + net/wireless/core.h | 1 + net/wireless/mlme.c | 19 +++++++++++++++++++ 3 files changed, 21 insertions(+)
diff --git a/net/wireless/core.c b/net/wireless/core.c index 54a34d8d356e0..5e5c1bc380a89 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -1365,6 +1365,7 @@ void cfg80211_leave(struct cfg80211_registered_device *rdev,
cfg80211_pmsr_wdev_down(wdev);
+ cfg80211_stop_radar_detection(wdev); cfg80211_stop_background_radar_detection(wdev);
switch (wdev->iftype) { diff --git a/net/wireless/core.h b/net/wireless/core.h index b6bd7f4d6385a..d5d78752227af 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -489,6 +489,7 @@ cfg80211_start_background_radar_detection(struct cfg80211_registered_device *rde struct wireless_dev *wdev, struct cfg80211_chan_def *chandef);
+void cfg80211_stop_radar_detection(struct wireless_dev *wdev); void cfg80211_stop_background_radar_detection(struct wireless_dev *wdev);
void cfg80211_background_cac_done_wk(struct work_struct *work); diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 46394eb2086f6..3fc175f9f8686 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c @@ -1295,6 +1295,25 @@ cfg80211_start_background_radar_detection(struct cfg80211_registered_device *rde return 0; }
+void cfg80211_stop_radar_detection(struct wireless_dev *wdev) +{ + struct wiphy *wiphy = wdev->wiphy; + struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); + int link_id; + + for_each_valid_link(wdev, link_id) { + struct cfg80211_chan_def chandef; + + if (!wdev->links[link_id].cac_started) + continue; + + chandef = *wdev_chandef(wdev, link_id); + rdev_end_cac(rdev, wdev->netdev, link_id); + nl80211_radar_notify(rdev, &chandef, NL80211_RADAR_CAC_ABORTED, + wdev->netdev, GFP_KERNEL); + } +} + void cfg80211_stop_background_radar_detection(struct wireless_dev *wdev) { struct wiphy *wiphy = wdev->wiphy;
From: Qianchang Zhao pioooooooooip@gmail.com
[ Upstream commit 991f8a79db99b14c48d20d2052c82d65b9186cad ]
ksmbd maintains delete-on-close and pending-delete state in ksmbd_inode->m_flags. In vfs_cache.c this field is accessed under inconsistent locking: some paths read and modify m_flags under ci->m_lock while others do so without taking the lock at all.
Examples:
- ksmbd_query_inode_status() and __ksmbd_inode_close() use ci->m_lock when checking or updating m_flags. - ksmbd_inode_pending_delete(), ksmbd_set_inode_pending_delete(), ksmbd_clear_inode_pending_delete() and ksmbd_fd_set_delete_on_close() used to read and modify m_flags without ci->m_lock.
This creates a potential data race on m_flags when multiple threads open, close and delete the same file concurrently. In the worst case delete-on-close and pending-delete bits can be lost or observed in an inconsistent state, leading to confusing delete semantics (files that stay on disk after delete-on-close, or files that disappear while still in use).
Fix it by:
- Making ksmbd_query_inode_status() look at m_flags under ci->m_lock after dropping inode_hash_lock. - Adding ci->m_lock protection to all helpers that read or modify m_flags (ksmbd_inode_pending_delete(), ksmbd_set_inode_pending_delete(), ksmbd_clear_inode_pending_delete(), ksmbd_fd_set_delete_on_close()). - Keeping the existing ci->m_lock protection in __ksmbd_inode_close(), and moving the actual unlink/xattr removal outside the lock.
This unifies the locking around m_flags and removes the data race while preserving the existing delete-on-close behaviour.
Reported-by: Qianchang Zhao pioooooooooip@gmail.com Reported-by: Zhitong Liu liuzhitong1993@gmail.com Signed-off-by: Qianchang Zhao pioooooooooip@gmail.com Acked-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
fs/smb/server/vfs_cache.c | 88 +++++++++++++++++++++++++++------------ 1 file changed, 62 insertions(+), 26 deletions(-)
diff --git a/fs/smb/server/vfs_cache.c b/fs/smb/server/vfs_cache.c index dfed6fce89049..6ef116585af64 100644 --- a/fs/smb/server/vfs_cache.c +++ b/fs/smb/server/vfs_cache.c @@ -112,40 +112,62 @@ int ksmbd_query_inode_status(struct dentry *dentry)
read_lock(&inode_hash_lock); ci = __ksmbd_inode_lookup(dentry); - if (ci) { - ret = KSMBD_INODE_STATUS_OK; - if (ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS)) - ret = KSMBD_INODE_STATUS_PENDING_DELETE; - atomic_dec(&ci->m_count); - } read_unlock(&inode_hash_lock); + if (!ci) + return ret; + + down_read(&ci->m_lock); + if (ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS)) + ret = KSMBD_INODE_STATUS_PENDING_DELETE; + else + ret = KSMBD_INODE_STATUS_OK; + up_read(&ci->m_lock); + + atomic_dec(&ci->m_count); return ret; }
bool ksmbd_inode_pending_delete(struct ksmbd_file *fp) { - return (fp->f_ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS)); + struct ksmbd_inode *ci = fp->f_ci; + int ret; + + down_read(&ci->m_lock); + ret = (ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS)); + up_read(&ci->m_lock); + + return ret; }
void ksmbd_set_inode_pending_delete(struct ksmbd_file *fp) { - fp->f_ci->m_flags |= S_DEL_PENDING; + struct ksmbd_inode *ci = fp->f_ci; + + down_write(&ci->m_lock); + ci->m_flags |= S_DEL_PENDING; + up_write(&ci->m_lock); }
void ksmbd_clear_inode_pending_delete(struct ksmbd_file *fp) { - fp->f_ci->m_flags &= ~S_DEL_PENDING; + struct ksmbd_inode *ci = fp->f_ci; + + down_write(&ci->m_lock); + ci->m_flags &= ~S_DEL_PENDING; + up_write(&ci->m_lock); }
void ksmbd_fd_set_delete_on_close(struct ksmbd_file *fp, int file_info) { - if (ksmbd_stream_fd(fp)) { - fp->f_ci->m_flags |= S_DEL_ON_CLS_STREAM; - return; - } + struct ksmbd_inode *ci = fp->f_ci;
- fp->f_ci->m_flags |= S_DEL_ON_CLS; + down_write(&ci->m_lock); + if (ksmbd_stream_fd(fp)) + ci->m_flags |= S_DEL_ON_CLS_STREAM; + else + ci->m_flags |= S_DEL_ON_CLS; + up_write(&ci->m_lock); }
static void ksmbd_inode_hash(struct ksmbd_inode *ci) @@ -257,27 +279,41 @@ static void __ksmbd_inode_close(struct ksmbd_file *fp) struct file *filp;
filp = fp->filp; - if (ksmbd_stream_fd(fp) && (ci->m_flags & S_DEL_ON_CLS_STREAM)) { - ci->m_flags &= ~S_DEL_ON_CLS_STREAM; - err = ksmbd_vfs_remove_xattr(file_mnt_idmap(filp), - &filp->f_path, - fp->stream.name, - true); - if (err) - pr_err("remove xattr failed : %s\n", - fp->stream.name); + + if (ksmbd_stream_fd(fp)) { + bool remove_stream_xattr = false; + + down_write(&ci->m_lock); + if (ci->m_flags & S_DEL_ON_CLS_STREAM) { + ci->m_flags &= ~S_DEL_ON_CLS_STREAM; + remove_stream_xattr = true; + } + up_write(&ci->m_lock); + + if (remove_stream_xattr) { + err = ksmbd_vfs_remove_xattr(file_mnt_idmap(filp), + &filp->f_path, + fp->stream.name, + true); + if (err) + pr_err("remove xattr failed : %s\n", + fp->stream.name); + } }
if (atomic_dec_and_test(&ci->m_count)) { + bool do_unlink = false; + down_write(&ci->m_lock); if (ci->m_flags & (S_DEL_ON_CLS | S_DEL_PENDING)) { ci->m_flags &= ~(S_DEL_ON_CLS | S_DEL_PENDING); - up_write(&ci->m_lock); - ksmbd_vfs_unlink(filp); - down_write(&ci->m_lock); + do_unlink = true; } up_write(&ci->m_lock);
+ if (do_unlink) + ksmbd_vfs_unlink(filp); + ksmbd_inode_free(ci); } }
On Sat, 2025-12-06 at 09:02 -0500, Sasha Levin wrote:
### Conclusion
This commit fixes a legitimate bug but does **not** meet stable kernel criteria:
- The maintainer did not request stable backporting
- The affected code only exists in kernel 6.12+, making it only relevant to the most recent stable branch if any
- The bug severity (warnings, not crashes/corruption/security) does not warrant the backporting effort
- It cannot be cleanly applied to most stable trees due to structural code differences
**NO**
:)
To be fair, it's kind of a corner case that happened mostly during tests as far as I know, when two mesh peers getting radar detection happen to pick two incompatible channels and then give up, causing wpa_s to bring down the interface.
The thing that makes this interesting is that they both detect radar at *precisely* the same time because they're actually simulated on a single Linux system, and our regulatory code tells each and every radio if any of them detects radar.
Anyway, either way is reasonable, it's probably a much older issue than 6.12 (then we just shuffled things around due to MLO), but the issue would've been around before that, and nobody really seems to have noticed outside this specific test.
johannes
On Sat, Dec 06, 2025 at 03:55:37PM +0100, Johannes Berg wrote:
On Sat, 2025-12-06 at 09:02 -0500, Sasha Levin wrote:
### Conclusion
This commit fixes a legitimate bug but does **not** meet stable kernel criteria:
- The maintainer did not request stable backporting
- The affected code only exists in kernel 6.12+, making it only relevant to the most recent stable branch if any
- The bug severity (warnings, not crashes/corruption/security) does not warrant the backporting effort
- It cannot be cleanly applied to most stable trees due to structural code differences
**NO**
:)
To be fair, it's kind of a corner case that happened mostly during tests as far as I know, when two mesh peers getting radar detection happen to pick two incompatible channels and then give up, causing wpa_s to bring down the interface.
The thing that makes this interesting is that they both detect radar at *precisely* the same time because they're actually simulated on a single Linux system, and our regulatory code tells each and every radio if any of them detects radar.
Anyway, either way is reasonable, it's probably a much older issue than 6.12 (then we just shuffled things around due to MLO), but the issue would've been around before that, and nobody really seems to have noticed outside this specific test.
Commits still get a review after the LLM response, which something is (IMO) wrong :)
I'll keep it in, thanks!
linux-stable-mirror@lists.linaro.org