[PATCH] jfs: reject negative symlink sizes in jfs_iget
From: YANXIN LI
Date: Sat Jul 18 2026 - 08:30:54 EST
copy_from_dinode() copies the untrusted on-disk di_size into i_size
without validating its signed lower bound. A negative size on a symlink
bypasses the existing IDATASIZE upper-bound test, after which jfs_iget()
uses it as an index and writes a NUL byte before i_inline.
A crafted JFS image therefore causes a one-byte slab-out-of-bounds write
while the root inode is read during mount. Generic KASAN reports:
BUG: KASAN: slab-out-of-bounds in jfs_iget+0x44a/0x4a0
Write of size 1 ... by task busybox
...
jfs_iget
jfs_fill_super
get_tree_bdev_flags
path_mount
__x64_sys_mount
JFS requires a privileged mount path, so a relevant boundary is a
privileged automounter processing an attacker-supplied block image.
Reject negative symlink sizes before selecting the inline or page-backed
symlink operations. The same image is rejected with EIO after this
change, with no KASAN report during the test.
Source inspection confirms the same unchecked write in the
released
v7.1.3 stable kernel and the v6.18.38 and v6.12.95 longterm kernels. It
is also present in v7.2-rc3 and upstream master at 1229e2e57a5c. The
affected upstream range starts with the commit named by the Fixes tag
below and extends through that master revision when JFS is enabled,
unless a downstream fix is present.
The issue was dynamically reproduced in an x86-64 QEMU guest running
v7.2-rc3 with generic KASAN. The fix was also built and tested with the
same image on upstream master at 1229e2e57a5c; the image was rejected
with EIO and no KASAN report.
Fixes: d69e83d99cf8 ("jfs: ensure symlinks are NUL-terminated")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: YANXIN LI <fadouse@xxxxx>
---
fs/jfs/inode.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
index c7914dbc9..c53985ee2 100644
--- a/fs/jfs/inode.c
+++ b/fs/jfs/inode.c
@@ -46,6 +46,10 @@ struct inode *jfs_iget(struct super_block *sb, unsigned long ino)
inod
e->i_op = &jfs_dir_inode_operations;
inode->i_fop = &jfs_dir_operations;
} else if (S_ISLNK(inode->i_mode)) {
+ if (inode->i_size < 0) {
+ iget_failed(inode);
+ return ERR_PTR(-EIO);
+ }
if (inode->i_size >= IDATASIZE) {
inode->i_op = &page_symlink_inode_operations;
inode_nohighmem(inode);
base-commit: 1229e2e57a5c2980ccd457b9b53ea0eed5a22ab3
--
2.54.0
Attachment:
publickey - fadouse@pm.me - 0x99485AA3.asc
Description: application/pgp-keys
Attachment:
signature.asc
Description: OpenPGP digital signature