]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
isofs: validate block number from NFS file handle in isofs_export_iget
authorMichael Bommarito <michael.bommarito@gmail.com>
Sun, 19 Apr 2026 21:21:55 +0000 (17:21 -0400)
committerJan Kara <jack@suse.cz>
Mon, 20 Apr 2026 14:54:25 +0000 (16:54 +0200)
isofs_fh_to_dentry() and isofs_fh_to_parent() pass an attacker-
controlled block number (ifid->block or ifid->parent_block) from
the NFS file handle to isofs_export_iget(), which only rejects
block == 0 before calling isofs_iget() and ultimately sb_bread().
A crafted file handle with fh_len sufficient to pass the check
added by commit 0405d4b63d08 ("isofs: Prevent the use of too small
fid") can still drive the server to read any in-range block on the
backing device as if it were an iso_directory_record.  That earlier
fix was assigned CVE-2025-37780.

sb_bread() on an out-of-range block returns NULL cleanly via the
EIO path, so there is no memory-safety violation.  For in-range
reads of adjacent-partition data on the same block device, the
unrelated bytes end up in iso_inode_info fields that reach the NFS
client as dentry metadata.  The deployment surface (isofs exported
over NFS from loop-mounted images) is narrow and requires an
authenticated NFS peer, but the malformed-file-handle class is
reportable as hardening next to the existing CVE-2025-37780 fix.

Reject block >= ISOFS_SB(sb)->s_nzones in isofs_export_iget() so
the check covers both isofs_fh_to_dentry() and isofs_fh_to_parent()
call sites with a single line.

Fixes: 0405d4b63d08 ("isofs: Prevent the use of too small fid")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-7
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Link: https://patch.msgid.link/20260419212155.2169382-3-michael.bommarito@gmail.com
Signed-off-by: Jan Kara <jack@suse.cz>
fs/isofs/export.c

index 421d247fae52301b778f0589b27fcf48f2372832..78f80c1a5c54a0a475825507e724ca5492406154 100644 (file)
@@ -24,7 +24,7 @@ isofs_export_iget(struct super_block *sb,
 {
        struct inode *inode;
 
-       if (block == 0)
+       if (block == 0 || block >= ISOFS_SB(sb)->s_nzones)
                return ERR_PTR(-ESTALE);
        inode = isofs_iget(sb, block, offset);
        if (IS_ERR(inode))