summaryrefslogtreecommitdiff
path: root/fs/isofs
AgeCommit message (Collapse)Author
2026-10-20Merge tag 'fs_for_v7.4-rc1' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs Pull ext2, isofs, udf and quota updates from Jan Kara: - ext2 changes to support clang context tracking - multiple isofs hardenings and cleanups - several udf hardening fixes - block use of fs-specific quota formats with incorrect filesystem * tag 'fs_for_v7.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: (26 commits) udf: fix return value for non-recorded-allocated extents in udf_map_block() isofs: shrink the name conversion buffer isofs: pass the name buffer size to get_rock_ridge_filename() isofs: report the Joliet name length in statfs isofs: return long Joliet names whole isofs: Simplify isofs_read_level3_size() isofs: bound empty directory blocks in isofs_read_level3_size() quota: fix shrinker scan budget accounting in dqcache_shrink_scan() ext2: drain in-flight DIO before buffered write fallback isofs: validate directory records in isofs_read_level3_size() once_lite: Simplify condition handling and fix context analysis isofs: convert the zisofs read path to use folios isofs: fix Rock Ridge CE extent validation on multisession media shmem: Refuse to enable tmpfs format for another filesystem ocfs2: Refuse to enable ocfs2 format for another filesystem ext2: enable context analysis support for ext2 filesystem ext2: annotate s_rsv_window_root as requiring s_rsv_window_lock ext2: annotate block-mapping helpers as requiring truncate_mutex ext2: annotate ext2_init_block_alloc_info() as requiring truncate_mutex ext2: mark s_mount_state as guarded by s_lock ...
2026-10-02isofs: shrink the name conversion bufferMatthias Goergens
isofs_readdir() and isofs_lookup() allocate 1024 bytes for the name converters. Now that get_rock_ridge_filename() and get_joliet_filename() are told the buffer size, nothing writes beyond JOLIET_NAME_MAX + 1 bytes: get_joliet_filename() is passed that size, get_rock_ridge_filename() is passed NAME_MAX + 1, isofs_name_translate() copies at most the 222 bytes of name a directory record can hold, and get_acorn_filename() appends at most five bytes to that. Allocate JOLIET_NAME_MAX + 1 bytes, matching what the Joliet callers pass. No functional change. Signed-off-by: Matthias Goergens <matthias.goergens@gmail.com> Link: https://patch.msgid.link/20260926042916.3277409-5-matthias.goergens@gmail.com Signed-off-by: Jan Kara <jack@suse.cz>
2026-10-02isofs: pass the name buffer size to get_rock_ridge_filename()Matthias Goergens
get_rock_ridge_filename() assembles a name from one or more NM entries into a buffer allocated by its caller. It is not told how big that buffer is, and instead stops adding NM entries once the name would exceed NAME_MAX, relying on the callers' buffer being larger. Pass the size in and check against it. Both callers pass NAME_MAX + 1, so the behaviour is unchanged: an NM entry that would take the name past 255 bytes is dropped, together with any that follow, and the entries before it are returned. Signed-off-by: Matthias Goergens <matthias.goergens@gmail.com> Link: https://patch.msgid.link/20260926042916.3277409-4-matthias.goergens@gmail.com Signed-off-by: Jan Kara <jack@suse.cz>
2026-10-02isofs: report the Joliet name length in statfsMatthias Goergens
isofs_statfs() reports NAME_MAX as the longest name, but a Joliet name can now be up to JOLIET_NAME_MAX bytes long. glibc answers pathconf(_PC_NAME_MAX) from f_namelen, so a program sizing a buffer from it should get room for every name readdir returns. vfat has reported 255 times NLS_MAX_CHARSET_SIZE, 1530, since commit f68e542f3478 ("fat: Fix statfs->f_namelen"), which followed a report of readdir_r() overflowing a buffer sized that way, and exfat reports the same. Windows reports a maximum component length of 110 for CDFS. Report JOLIET_NAME_MAX on Joliet mounts. Rock Ridge and plain ISO 9660 mounts keep NAME_MAX. Signed-off-by: Matthias Goergens <matthias.goergens@gmail.com> Link: https://patch.msgid.link/20260926042916.3277409-3-matthias.goergens@gmail.com Signed-off-by: Jan Kara <jack@suse.cz>
2026-10-02isofs: return long Joliet names wholeMatthias Goergens
get_joliet_filename() writes into a buffer allocated by its caller but is not told how big that buffer is. It hardcodes PAGE_SIZE as the output limit for utf16s_to_utf8s() and gives uni16_to_x8() no limit at all. PAGE_SIZE was never the right bound. Before commit b2eb2e288604 ("isofs: Drop support of directory entries straddling blocks") both callers allocated a page, but only its first 1024 bytes were for the name, the rest holding a copy of a directory record that straddled a block. It could not overflow only because a directory record holds at most 222 bytes of name (255 bytes, 33 of them fixed), which no converter expands beyond 1024 bytes. It also keeps the converted length in an unsigned char. 222 bytes of name are 111 UTF-16 units, and the UTF-8 converter, used for iocharset=utf8 and when CONFIG_NLS_DEFAULT is "utf8", needs three bytes for each CJK, Thai or Devanagari character, so such a name can take up to 333 bytes. Past 255 the length wraps. readdir then reports a short name that usually ends in the middle of a UTF-8 sequence, and lookup finds the file only under that name, never under its real one; a name that wraps to exactly 0 bytes is not listed at all. Such names are out of spec, since Joliet allows 64 units, but common tools write them: PowerISO 9.5 and UltraISO 9.76 both keep up to 110 units by default. Windows, for which Joliet was made, returns them whole, including 111-unit names in records that leave out the padding byte. Return them whole here too. Pass the buffer size down and have both converters respect it. utf16s_to_utf8s() stops before a character that does not fit, and uni16_to_x8() now hands uni2char() the space that actually remains and stops on -ENAMETOOLONG, as fs/hfsplus/unicode.c does. Both callers pass JOLIET_NAME_MAX + 1, room for 111 units at three bytes each plus the terminator; no character set needs more than three bytes for a UTF-16 unit, and isofs_dir_record_valid() already rejects a record whose name_len claims more than the record holds, so no name is cut. Make the length an int, which is what both converters return. These names are longer than NAME_MAX. POSIX lets the limit vary by filesystem, reported by pathconf(_PC_NAME_MAX), and the VFS limits a name only by PATH_MAX (verify_dirent_name() in fs/readdir.c). vfat, exfat, hfsplus and ntfs3 already return names of up to 255 UTF-16 units, 765 bytes of UTF-8, and such names break the same things there: copying the file to a filesystem with a 255-byte limit, such as ext4 or tmpfs, fails with ENAMETOOLONG, and cp, tar, rsync and Python's shutil report that file and carry on with the rest, so the copy is incomplete but says so. glibc's readdir() returns the names, but the deprecated readdir_r() skips them and fails with ENAMETOOLONG, and an inotify reader with the buffer size inotify(7) suggests gets EINVAL. In the kernel, fanotify reports events on such a file without its name and warns once in fanotify_info_copy_name(), and a directory with such a name cannot be reconnected from a file handle, because the generic get_name() in fs/exportfs, which isofs uses, skips names longer than NAME_MAX. Cutting at NAME_MAX would avoid these, but would list names that Windows does not show and that can coincide within a directory. Every name of at most 255 bytes is returned exactly as before. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Matthias Goergens <matthias.goergens@gmail.com> Link: https://patch.msgid.link/20260926042916.3277409-2-matthias.goergens@gmail.com Signed-off-by: Jan Kara <jack@suse.cz>
2026-10-02isofs: Simplify isofs_read_level3_size()Jan Kara
After recent changes it is possible to further simplify isofs_read_level3_size() by reorganizing the loop a bit and removing empty_blocks, block_saved, offset_saved variables. Reviewed-by: Matthias Goergens <matthias.goergens@gmail.com> Tested-by: Matthias Goergens <matthias.goergens@gmail.com> Signed-off-by: Jan Kara <jack@suse.cz>
2026-09-30isofs: bound empty directory blocks in isofs_read_level3_size()Matthias Goergens
isofs_read_level3_size() walks the sections of a level-3 (multi-extent) directory record and, on a zero length byte, moves on to the next block with no limit. A crafted image can put a long run of empty blocks between two sections of a multi-extent file, and the walk reads every one of them before it gives up, all the way to the end of the device if it has to. Real discs do have trailing empty directory blocks, written by tools such as Easy CD Creator and Nero, but always at the end of the directory, never between two sections of a multi-extent record, so they do not exercise this path [1]. Jan Kara suggested treating an empty block like a section: count it towards the existing 100-section limit rather than adding a separate one [2]. Do that: both the section count and the empty-block count are checked against their combined total, so neither one alone can reach 100 while the other keeps growing. Only a zero length byte at the start of a block counts as an empty block; the same byte later in a block still just ends that block's records, as it does today, and is not counted. Hui Peng's earlier patch for this function added its own, separate limit on the number of empty blocks [3]; this uses the combined limit Jan suggested instead. Suggested-by: Jan Kara <jack@suse.cz> Signed-off-by: Matthias Goergens <matthias.goergens@gmail.com> [1] https://lore.kernel.org/all/20260925043804.2091174-1-matthias.goergens@gmail.com/ [2] https://lore.kernel.org/all/cmlro2xzle2aa7ebflvxhbcv74mea7p6qvxhin6egpdvyzyuxh@s45tpgxdal3n/ [3] https://lore.kernel.org/all/20260919222553.3792320-1-benquike@gmail.com/ Link: https://patch.msgid.link/20260926083517.556576-1-matthias.goergens@gmail.com Signed-off-by: Jan Kara <jack@suse.cz>
2026-09-23isofs: validate directory records in isofs_read_level3_size()Matthias Goergens
isofs_read_level3_size() walks the multi-extent directory records of a file and dereferences de->size and de->flags for each one without ever checking the record's length byte. A record with a short length placed near the end of a block makes those fixed-field reads run past the record, and for a record at the end of the last block of a page, past the buffer. readdir, lookup and the NFS get_parent path have validated every record with isofs_dir_record_valid() since commit e2ee4078ec58 ("isofs: validate directory records consistently"). Do the same here, after moving on to the next block when the previous record ended exactly at the end of the block or the rest of the block is zero padding, as commit 3c01d9263683 ("isofs: Fix handling of directories with tight blocks") does for the other two walkers. The check rejects a record that would run past its block, so the code that reassembled such a record from two blocks can no longer run. ECMA-119 does not allow directory records to straddle sector boundaries, which is what commit b2eb2e288604 ("isofs: Drop support of directory entries straddling blocks") relied on when it removed the same code from readdir and lookup. Remove it here too, along with its temporary record buffer. Found by fuzzing fs/isofs in a userspace harness with ASan (heap-buffer-overflow reads in de->flags). Signed-off-by: Matthias Goergens <matthias.goergens@gmail.com> Link: https://patch.msgid.link/20260923153220.777907-1-matthias.goergens@gmail.com Signed-off-by: Jan Kara <jack@suse.cz>
2026-09-23isofs: Fix handling of directories with tight blocksJan Kara
Thomas has reported that after commit b2eb2e288604 ("isofs: Drop support of directory entries straddling blocks") some isofs images of Fedora miss some entries in some directories. The problem is triggered when directory entries are packed in a block in such a way that they exactly fit the block (which BTW mkisofs doesn't do so I didn't catch this bug when testing with my images). Fix readdir and lookup code to properly transition to the next block when directory block is tightly packed. Link: https://bugzilla.redhat.com/show_bug.cgi?id=2535353 Reported-by: Thomas Schmitt <scdbackup@gmx.net> Reported-by: Matthias Goergens <matthias.goergens@gmail.com> Fixes: b2eb2e288604 ("isofs: Drop support of directory entries straddling blocks") Reviewed-by: Thomas Schmitt <scdbackup@gmx.net> Signed-off-by: Jan Kara <jack@suse.cz>
2026-09-08isofs: convert the zisofs read path to use foliosTal Zussman
Store folios in the array that zisofs_read_folio() passes to zisofs_fill_pages() and zisofs_uncompress_block(), use the folio APIs on them, and grab the folios with __filemap_get_folio() instead of grab_cache_page_nowait(). This removes six compound_head() calls, from page_offset(), the three SetPageUptodate() calls, unlock_page() and put_page(), and the last struct page usage in isofs. isofs only uses order-0 folios, so folio_size() is PAGE_SIZE and the logic is unchanged. grab_cache_page_nowait() passed FGP_NOFS as well, but FGP_NOWAIT already prevents reclaim entirely, so leave it out, as FGP_NOFS is on its way out [1]. Change poffset to be unsigned int rather than just unsigned while at it. [1] https://lore.kernel.org/linux-mm/20260830041901.2668-9-willy@infradead.org/ Signed-off-by: Tal Zussman <tz2294@columbia.edu> Link: https://patch.msgid.link/20260907-isofs-zisofs-folio-v2-1-c2e430abfcbc@columbia.edu Signed-off-by: Jan Kara <jack@suse.cz>
2026-09-07isofs: fix Rock Ridge CE extent validation on multisession mediaBaolin Liu
Commit a36d990f5913 ("isofs: validate Rock Ridge CE continuation extent against volume size") compares the CE extent directly with s_nzones. The extent is an absolute block number, while s_nzones is the number of blocks relative to the selected ISO session. The comparison is therefore wrong when a multisession disc starts at a non-zero block. isofs_get_last_session() selects the last session on multisession media, and its volume descriptors describe a volume beginning at that session's LBA. For example, a session beginning at LBA 45447 with 64 blocks can contain a valid CE at absolute LBA 45467. The existing check rejects that CE, so the ER continuation record is not read, Rock Ridge is disabled, and the mount falls back to Joliet names. Save the selected session start in filesystem-block units and validate the CE extent against the half-open interval [session_start, session_end). Scale the session length to the same block units and retain a separate block-device limit. The lower bound is intentional: accepting arbitrary blocks before the selected session could make a CE read data from a previous session or another filesystem on the device. Only apply the bounds check when cont_extent is non-zero. A zero extent is the in-memory sentinel indicating that no CE continuation was found, rather than a request to read block zero. For a single-session image, session_start is zero and the effective volume boundary remains unchanged. Build-tested with: make CONFIG_RUST= CONFIG_RUST_DRIVERS= fs/isofs/ Fixes: a36d990f5913 ("isofs: validate Rock Ridge CE continuation extent against volume size") Cc: stable@vger.kernel.org Signed-off-by: Baolin Liu <liubaolin@kylinos.cn> Link: https://patch.msgid.link/20260907082602.3777551-1-liubaolin12138@163.com Signed-off-by: Jan Kara <jack@suse.cz>
2026-07-29isofs: Drop support of directory entries straddling blocksJan Kara
Based on isofs standard (ECMA-119) directory entries are not allowed to straddle sector boundaries. Isofs images I have available seem to follow this. Now that we have code verifying validity of directory entries (and so we'd properly refuse such entries), let's just drop the code merging directory entries straddling sector boundaries. Acked-by: Christian Brauner <brauner@kernel.org> Signed-off-by: Jan Kara <jack@suse.cz>
2026-07-28isofs: validate directory records consistentlyYichong Chen
isofs_export_get_parent() assumes that the first two directory records are valid "." and ".." entries. A malformed image can provide an invalid length for the first entry, causing the computed ".." offset to point outside the received block. Add a shared directory record validator and use it in NFS get_parent, readdir and lookup. This keeps the basic directory record length checks consistent across all directory users before they consume the name field or use one record length to find the next entry. Signed-off-by: Yichong Chen <chenyichong@uniontech.com> Link: https://patch.msgid.link/20260728074349.417508-1-chenyichong@uniontech.com Signed-off-by: Jan Kara <jack@suse.cz>
2026-07-27isofs: release zisofs block pointer buffer headYichong Chen
zisofs_fill_pages() reads the compressed block pointer table. The error paths release the current buffer_head, the loop also releases the old buffer_head when it advances. However, the success path leaves the last buffer_head referenced. Release it before returning success. Fixes: 59bc055211b8 ("zisofs: Implement reading of compressed files when PAGE_CACHE_SIZE > compress block size") Signed-off-by: Yichong Chen <chenyichong@uniontech.com> Link: https://patch.msgid.link/20260721091152.1450622-1-chenyichong@uniontech.com Signed-off-by: Jan Kara <jack@suse.cz>
2026-07-13isofs: fix out-of-bounds page array access on empty zisofs blockXiang Mei
zisofs_uncompress_block()'s empty-block fast path returns pcount << PAGE_SHIFT, ignoring the incoming poffset, unlike the decompression path which returns bytes produced relative to poffset. zisofs_fill_pages() uses that return to advance its page cursor, so when the zisofs block size is below PAGE_SIZE and a sub-page block leaves poffset partway into a page, a following empty block over-counts and advances pages[] one element past its end, after which "if (poffset && *pages)" reads pages[1] out of bounds. rock.c only rejects a block-size shift > 17, so a crafted "ZF" Rock Ridge record can set it below PAGE_SHIFT; the bug is reached by an ordinary read() of a compressed file on such a mounted ISO9660 image. Return the byte count relative to poffset and zero only [poffset, PAGE_SIZE) of the first page, matching the decompression path. The page-aligned case (poffset == 0) is unaffected. BUG: KASAN: slab-out-of-bounds in zisofs_read_folio (fs/isofs/compress.c:290) Read of size 8 at addr ffff88800f5eac48 by task exploit/142 zisofs_read_folio (fs/isofs/compress.c:290) read_pages (mm/readahead.c:184) ... filemap_read (mm/filemap.c:2814) vfs_read (fs/read_write.c:574) __x64_sys_pread64 (fs/read_write.c:769) do_syscall_64 (arch/x86/entry/syscall_64.c:94) entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121) The buggy address is located 0 bytes to the right of the allocated 8-byte region in the kmalloc-8 cache Fixes: 59bc055211b8 ("zisofs: Implement reading of compressed files when PAGE_CACHE_SIZE > compress block size") Reported-by: Weiming Shi <bestswngs@gmail.com> Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Xiang Mei <xmei5@asu.edu> Link: https://patch.msgid.link/20260712234150.3213467-1-xmei5@asu.edu Signed-off-by: Jan Kara <jack@suse.cz>
2026-06-16Merge tag 'fs_for_v7.2-rc1' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs Pull udf, isofs, ext2, and quota updates from Jan Kara: - Assorted udf & isofs fixes for maliciously formatted devices - Cleanups to use kmalloc() instead of __get_free_page() - Removal of deprecated DAX code from ext2 * tag 'fs_for_v7.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: udf: validate VAT inode size for old VAT format udf: validate VAT header length against the VAT inode size udf: validate sparing table length as an entry count, not a byte count isofs: bound Rock Ridge symlink components to the SL record ext2: fix ignored return value of generic_write_sync() ext2: Remove deprecated DAX support isofs: replace __get_free_page() with kmalloc() quota: allocate dquot_hash with kmalloc() udf: validate free block extents against the partition length
2026-06-15Merge tag 'vfs-7.2-rc1.misc' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull misc vfs updates from Christian Brauner: "Features: - Reduce pipe->mutex contention by pre-allocating pages outside the lock in anon_pipe_write(). anon_pipe_write() called alloc_page() once per page while holding pipe->mutex. The allocation can sleep doing direct reclaim and runs memcg charging, which extends the critical section and stalls any concurrent reader on the same mutex. Now up to 8 pages are pre-allocated before the mutex is taken, leftovers are recycled into the per-pipe tmp_page[] cache before unlock, and any remainder is released after unlock, keeping the allocator out of the critical section on both sides. On a writers x readers sweep with 64KB writes against a 1 MB pipe throughput improves 6-28% and average write latency drops 5-22%; under memory pressure - when the cost of holding the mutex across reclaim is highest - throughput improves 21-48% and latency drops 17-33%. The microbenchmark is added to selftests. - uaccess/sockptr: fix the ignored_trailing logic in copy_struct_to_user() to behave as documented and the usize check in copy_struct_from_sockptr() for user pointers, and add copy_struct_{from,to}_bounce_buffer() and copy_struct_to_sockptr() helpers for upcoming users (IPPROTO_SMBDIRECT, IPPROTO_QUIC). - bpf: add a sleepable bpf_real_inode() kfunc that resolves the real inode backing a dentry via d_real_inode(). On overlayfs the inode attached to the dentry doesn't carry the underlying device information; this is used by the filesystem restriction BPF program that was merged into systemd. - docs: add guidelines for submitting new filesystems, motivated by the maintenance burden abandoned and untestable filesystems impose on VFS developers, blocking infrastructure work like folio conversions and iomap migration. Fixes: - libfs: set SB_I_NOEXEC and SB_I_NODEV by default in init_pseudo() and drop the now-redundant assignments in callers. This began as a one-line dma-buf fix for a path_noexec() warning; a pseudo filesystem has no reason not to set SB_I_NOEXEC. All init_pseudo() callers were audited: the only visible effect is on dma-buf where SB_I_NOEXEC silences the warning. - Handle set_blocksize() failures in legacy filesystems (bfs, hpfs, qnx4, jfs, befs, affs, isofs, minix, ntfs3, omfs). Mounting a device with a sector size > PAGE_SIZE crashed roughly half of them; the rest had the same missing error handling pattern. Plus a follow-up releasing the superblock buffer_head when setting the minix v3 block size fails. - mount: honour SB_NOUSER in the new mount API. - fs/fcntl: fix a SOFTIRQ-unsafe lock order in fasync signaling by switching the process-group paths of send_sigio() and send_sigurg() from read_lock(&tasklist_lock) to RCU, matching the single-PID path. - vfs: add an FS_USERNS_DELEGATABLE flag and set it for NFS, fixing delegated NFS mounts (fsopen() in a container with the mount performed by a privileged daemon) that broke when non-init s_user_ns was tied to FS_USERNS_MOUNT. - selftests/namespaces: fix a hang in nsid_test where an unreaped grandchild kept the TAP pipe write-end open, a waitpid(-1) race in listns_efault_test, and a false FAIL on kernels without listns() where the tests should SKIP. - filelock: fix the break_lease() stub signature for CONFIG_FILE_LOCKING=n. - init/initramfs_test: wait for the async initramfs unpacking before running; the test and do_populate_rootfs() share the parser state. - fs/coredump: reduce redundant log noise in validate_coredump_safety(). - iomap: pass the correct length to fserror_report_io() in __iomap_write_begin(). - backing-file: fix the backing_file_open() kerneldoc. Cleanups: - initramfs: refactor the cpio hex header parsing to use hex2bin() instead of the hand-rolled simple_strntoul() which is reverted, and extend the initramfs KUnit tests to cover header fields with 0x prefixes. - Replace __get_free_pages() and friends with kmalloc()/kzalloc() across quota, proc, ocfs2/dlm, nilfs2, nfs, nfsd, libfs, jfs, jbd2, isofs, fuse, select, namespace, configfs, binfmt_misc, bfs, and the do_mounts init code - part of the larger work of replacing page allocator calls with kmalloc(). - Use clear_and_wake_up_bit() in unlock_buffer() and journal_end_buffer_io_sync() instead of open-coding the sequence. - Drop unused VFS exports: unexport drop_super_exclusive(), remove start_removing_user_path_at(), and fold __start_removing_path() into start_removing_path(). - fs/read_write: narrow the __kernel_write() export with EXPORT_SYMBOL_FOR_MODULES(). - vfs: uapi: retire octal and hex constants in favor of (1 << n) for the O_ flags. Finding a free bit for a new flag across the architectures was needlessly hard with the mixed bases. - dcache: add extra sanity checks of dead dentries in dentry_free() via a new DENTRY_WARN_ONCE() that also prints d_flags. - iov_iter: use kmemdup_array() in dup_iter() to harden the allocation against multiplication overflow. - fs/pipe: write to ->poll_usage only once. - vfs: remove an always-taken if-branch in find_next_fd(). - dcache: use kmalloc_flex() for struct external_name in __d_alloc(). - namei: use QSTR() instead of QSTR_INIT() in path_pts(). - sync_file_range: delete dead S_ISLNK code. - Comment fixes: retire a stale comment in fget_task_next() and fix assorted spelling mistakes" * tag 'vfs-7.2-rc1.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (73 commits) backing-file: fix backing_file_open() kerneldoc parameter iomap: pass the correct len to fserror_report_io in __iomap_write_begin vfs: add FS_USERNS_DELEGATABLE flag and set it for NFS filelock: fix break_lease() stub signature for CONFIG_FILE_LOCKING=n vfs: uapi: retire octal and hex numbers in favor of (1 << n) for O_ flags bpf: add bpf_real_inode() kfunc fs/read_write: Do not export __kernel_write() to the entire world libfs: drop redundant SB_I_NOEXEC/SB_I_NODEV in init_pseudo() callers libfs: set SB_I_NOEXEC and SB_I_NODEV by default in init_pseudo() mount: honour SB_NOUSER in the new mount API fs/fcntl: fix SOFTIRQ-unsafe lock order in fasync signaling selftests/pipe: add pipe_bench microbenchmark fs/pipe: pre-allocate pages outside pipe->mutex in anon_pipe_write fs: retire stale comment in fget_task_next() fs: fix spelling mistakes in comment bfs: replace get_zeroed_page() with kzalloc() binfmt_misc: replace __get_free_page() with kmalloc() configfs: replace __get_free_pages() with kzalloc() fs/namespace: use __getname() to allocate mntpath buffer fs/select: replace __get_free_page() with kmalloc() ...
2026-06-15Merge tag 'vfs-7.2-rc1.casefold' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull vfs casefolding updates from Christian Brauner: "This exposes the case folding behavior of local filesystems so that file servers - nfsd, ksmbd, and user space file servers - can report the actual behavior to clients instead of guessing. Filesystems report case-insensitive and case-nonpreserving behavior via new file_kattr flags in their fileattr_get implementations. fat, exfat, ntfs3, hfs, hfsplus, xfs, cifs, nfs, vboxsf, and isofs are wired up. Local filesystems that are not explicitly handled default to the usual POSIX behavior of case-sensitive and case-preserving. nfsd uses this to report case folding via NFSv3 PATHCONF and to implement the NFSv4 FATTR4_CASE_INSENSITIVE and FATTR4_CASE_PRESERVING attributes - both have been part of the NFS protocols for decades to support clients on non-POSIX systems - and ksmbd reports it via FS_ATTRIBUTE_INFORMATION. Exposing the information through the fileattr uapi covers user space file servers. The immediate motivation is interoperability: Windows NFS clients hard-require servers to report case-insensitivity for Win32 applications to work correctly, and a client that knows the server is case-insensitive can avoid issuing multiple LOOKUP/READDIR requests searching for case variants. The Linux NFS client already grew support for case-insensitive shares years ago in support of the Hammerspace NFS server - negative dentry caching must be disabled (a lookup for "FILE.TXT" failing must not cache a negative entry when "file.txt" exists) and directory change invalidation must drop cached case-folded name variants. Such servers often operate in multi-protocol environments where a single file service instance caters to both NFS and SMB clients, and nfsd needs to report case folding properly to participate as a first-class citizen there. A follow-up series brings fixes for the initial work: the nfsd case-info probe now uses kernel credentials, maps -ESTALE to NFS3ERR_STALE, and has its cost capped across READDIR entries; the nfs client avoids transiently zeroed case capability bits during the probe and skips the pathconf probe when neither field is consumed; the FS_CASEFOLD_FL semantics are clarified in the UAPI header; and the tools UAPI headers are synced" * tag 'vfs-7.2-rc1.casefold' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (22 commits) nfsd: Cap case-folding probe cost across READDIR entries nfsd: Map -ESTALE from case probe to NFS3ERR_STALE nfsd: Use kernel credentials for case-info probe fs: Clarify FS_CASEFOLD_FL semantics in UAPI header nfs: Skip pathconf probe when neither field is consumed nfs: Avoid transient zeroed case capability bits during probe tools headers UAPI: Sync case-sensitivity flags from linux/fs.h ksmbd: Report filesystem case sensitivity via FS_ATTRIBUTE_INFORMATION nfsd: Implement NFSv4 FATTR4_CASE_INSENSITIVE and FATTR4_CASE_PRESERVING nfsd: Report export case-folding via NFSv3 PATHCONF isofs: Implement fileattr_get for case sensitivity vboxsf: Implement fileattr_get for case sensitivity nfs: Implement fileattr_get for case sensitivity cifs: Implement fileattr_get for case sensitivity xfs: Report case sensitivity in fileattr_get hfsplus: Report case sensitivity in fileattr_get hfs: Implement fileattr_get for case sensitivity ntfs3: Implement fileattr_get for case sensitivity exfat: Implement fileattr_get for case sensitivity fat: Implement fileattr_get for case sensitivity ...
2026-06-09isofs: bound Rock Ridge symlink components to the SL recordBryam Vargas
get_symlink_chunk() and the SL handling in parse_rock_ridge_inode_internal() walk the variable-length components of a Rock Ridge "SL" (symbolic link) record. Each component is a two-byte header (flags, len) followed by len bytes of text, so it occupies slp->len + 2 bytes. Both loops read slp->len and advance to the next component, and get_symlink_chunk() additionally does memcpy(rpnt, slp->text, slp->len), but neither checks that the component lies within the SL record before dereferencing it. A crafted SL record whose component declares a len that runs past the record (rr->len) therefore triggers an out-of-bounds read of up to 255 bytes. When the record sits at the tail of its backing buffer - for example a small kmalloc()ed continuation block reached through a CE record - the read crosses the allocation; get_symlink_chunk() then copies the out-of-bounds bytes into the symlink body returned to user space by readlink(), disclosing adjacent kernel memory. ISO 9660 images are routinely mounted from untrusted removable media - desktop environments auto-mount them (e.g. via udisks2) without CAP_SYS_ADMIN - so the record contents are attacker-controlled. Reject any component that does not fit in the remaining record bytes before using it. In get_symlink_chunk() return NULL, like the existing output-buffer (plimit) checks, so a malformed record makes readlink() fail with -EIO rather than silently returning a truncated target; in parse_rock_ridge_inode_internal() stop the inode-size walk. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Suggested-by: Michael Bommarito <michael.bommarito@gmail.com> Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me> Link: https://patch.msgid.link/20260607011823.217748-1-hexlabsecurity@proton.me Signed-off-by: Jan Kara <jack@suse.cz>
2026-05-27isofs: replace __get_free_page() with kmalloc()Mike Rapoport (Microsoft)
isofs_readdir() allocates a temporary buffer with __get_free_page(). kmalloc() is a better API for such use and it also provides better scalability and more debugging possibilities. Replace use of __get_free_page() with kmalloc(). Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Link: https://patch.msgid.link/20260523-b4-fs-v1-11-275e36a83f0e@kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-25isofs: replace __get_free_page() with kmalloc()Mike Rapoport (Microsoft)
isofs_readdir() allocates a temporary buffer with __get_free_page(). kmalloc() is a better API for such use and it also provides better scalability and more debugging possibilities. Replace use of __get_free_page() with kmalloc(). Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Link: https://patch.msgid.link/20260523-b4-fs-v1-11-275e36a83f0e@kernel.org Signed-off-by: Jan Kara <jack@suse.cz>
2026-05-21isofs: handle set_blocksize failuresChristoph Hellwig
isofs uses buffer_heads, which don't handle block size > PAGE_SIZE well. Without this, mounting we will hit the BUG_ON(offset >= folio_size(folio)); in folio_set_bh on the first __bread_gfp call. Signed-off-by: Christoph Hellwig <hch@lst.de> Link: https://patch.msgid.link/20260511071701.2456211-8-hch@lst.de Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-11isofs: Implement fileattr_get for case sensitivityChuck Lever
Upper layers such as NFSD need a way to query whether a filesystem handles filenames in a case-sensitive manner so they can provide correct semantics to remote clients. Without this information, NFS exports of ISO 9660 filesystems cannot advertise their filename case behavior. Implement isofs_fileattr_get() to report ISO 9660 case handling behavior. The 'check=r' (relaxed) mount option enables case-insensitive lookups and is reported via FS_XFLAG_CASEFOLD. By default, Joliet extensions operate in relaxed mode while plain ISO 9660 uses strict (case-sensitive) mode. Plain ISO 9660 names on the medium are uppercase. When neither Rock Ridge nor Joliet is in effect, the default 'map=n' option (and 'map=a') routes lookup and readdir through isofs_name_translate(), which forces A-Z to a-z. The names visible to userspace then differ in case from the on-disc form, so report FS_XFLAG_CASENONPRESERVING in that configuration. Rock Ridge and Joliet both deliver names as authored, and 'map=o' emits the raw on-disc name unchanged, so those configurations remain case-preserving. Casefolding is a directory property, and the in-tree consumers (NFSD, ksmbd) issue the query against a directory: NFSD walks to the parent for non-directory dentries before calling vfs_fileattr_get(), and ksmbd reports per-share attributes from the share root. Wire .fileattr_get only on isofs_dir_inode_operations. The CASEFOLD flag is set in both fa->fsx_xflags and fa->flags so FS_IOC_FSGETXATTR and FS_IOC_GETFLAGS agree. Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: Roland Mainz <roland.mainz@nrubsig.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Link: https://patch.msgid.link/20260507-case-sensitivity-v14-12-e62cc8200435@oracle.com Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-04-20isofs: use QSTR_LEN() in isofs_cmpThorsten Blum
Use QSTR_LEN() and inline the code in isofs_cmp(). Remove the stale function comment while at it. Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev> Link: https://patch.msgid.link/20260420102544.8924-3-thorsten.blum@linux.dev Signed-off-by: Jan Kara <jack@suse.cz>
2026-04-20isofs: validate block number from NFS file handle in isofs_export_igetMichael Bommarito
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>
2026-04-20isofs: validate Rock Ridge CE continuation extent against volume sizeMichael Bommarito
rock_continue() reads rs->cont_extent verbatim from the Rock Ridge CE record and passes it to sb_bread() without checking that the block number is within the mounted ISO 9660 volume. commit e595447e177b ("[PATCH] rock.c: handle corrupted directories") added cont_offset and cont_size rejection for the CE continuation but did not validate the extent block number itself. commit f54e18f1b831 ("isofs: Fix infinite looping over CE entries") later capped the CE chain length at RR_MAX_CE_ENTRIES = 32 but again left the block number unchecked. With a crafted ISO mounted via udisks2 (desktop optical auto-mount) or via CAP_SYS_ADMIN mount, rs->cont_extent can therefore point at an out-of-range block or at blocks belonging to an adjacent filesystem on the same block device. sb_bread() on an out-of-range block returns NULL cleanly via the block layer EIO path, so there is no memory-safety violation. For in-range reads of adjacent- filesystem data, the CE buffer is parsed as Rock Ridge records and only the text of SL sub-records reaches userspace through readlink(), which makes the info-leak channel narrow and difficult to exploit; still, rejecting the malformed CE outright matches the rejection shape already present in the same function for cont_offset and cont_size. Add an ISOFS_SB(sb)->s_nzones bounds check to rock_continue() next to the existing offset/size rejection, printing the same corrupted-directory-entry notice. Fixes: f54e18f1b831 ("isofs: Fix infinite looping over CE entries") 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-2-michael.bommarito@gmail.com Signed-off-by: Jan Kara <jack@suse.cz>
2026-03-06treewide: fix missed i_ino format specifier conversionsChristian Brauner
Fix three format strings that were missed in the treewide i_ino unsigned long to u64 conversion: - fs/binfmt_elf_fdpic.c: %lu -> %llu - fs/ext2/xattr.c: %ld -> %llu (debug macro, also fixes signedness) - fs/isofs/inode.c: %ld -> %llu (debug block, also fixes signedness) Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-03-06treewide: change inode->i_ino from unsigned long to u64Jeff Layton
On 32-bit architectures, unsigned long is only 32 bits wide, which causes 64-bit inode numbers to be silently truncated. Several filesystems (NFS, XFS, BTRFS, etc.) can generate inode numbers that exceed 32 bits, and this truncation can lead to inode number collisions and other subtle bugs on 32-bit systems. Change the type of inode->i_ino from unsigned long to u64 to ensure that inode numbers are always represented as 64-bit values regardless of architecture. Update all format specifiers treewide from %lu/%lx to %llu/%llx to match the new type, along with corresponding local variable types. This is the bulk treewide conversion. Earlier patches in this series handled trace events separately to allow trace field reordering for better struct packing on 32-bit. Signed-off-by: Jeff Layton <jlayton@kernel.org> Link: https://patch.msgid.link/20260304-iino-u64-v3-12-2257ad83d372@kernel.org Acked-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-02-22Convert remaining multi-line kmalloc_obj/flex GFP_KERNEL usesKees Cook
Conversion performed via this Coccinelle script: // SPDX-License-Identifier: GPL-2.0-only // Options: --include-headers-for-types --all-includes --include-headers --keep-comments virtual patch @gfp depends on patch && !(file in "tools") && !(file in "samples")@ identifier ALLOC = {kmalloc_obj,kmalloc_objs,kmalloc_flex, kzalloc_obj,kzalloc_objs,kzalloc_flex, kvmalloc_obj,kvmalloc_objs,kvmalloc_flex, kvzalloc_obj,kvzalloc_objs,kvzalloc_flex}; @@ ALLOC(... - , GFP_KERNEL ) $ make coccicheck MODE=patch COCCI=gfp.cocci Build and boot tested x86_64 with Fedora 42's GCC and Clang: Linux version 6.19.0+ (user@host) (gcc (GCC) 15.2.1 20260123 (Red Hat 15.2.1-7), GNU ld version 2.44-12.fc42) #1 SMP PREEMPT_DYNAMIC 1970-01-01 Linux version 6.19.0+ (user@host) (clang version 20.1.8 (Fedora 20.1.8-4.fc42), LLD 20.1.8) #1 SMP PREEMPT_DYNAMIC 1970-01-01 Signed-off-by: Kees Cook <kees@kernel.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2026-02-21Convert 'alloc_obj' family to use the new default GFP_KERNEL argumentLinus Torvalds
This was done entirely with mindless brute force, using git grep -l '\<k[vmz]*alloc_objs*(.*, GFP_KERNEL)' | xargs sed -i 's/\(alloc_objs*(.*\), GFP_KERNEL)/\1)/' to convert the new alloc_obj() users that had a simple GFP_KERNEL argument to just drop that argument. Note that due to the extreme simplicity of the scripting, any slightly more complex cases spread over multiple lines would not be triggered: they definitely exist, but this covers the vast bulk of the cases, and the resulting diff is also then easier to check automatically. For the same reason the 'flex' versions will be done as a separate conversion. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2026-02-21treewide: Replace kmalloc with kmalloc_obj for non-scalar typesKees Cook
This is the result of running the Coccinelle script from scripts/coccinelle/api/kmalloc_objs.cocci. The script is designed to avoid scalar types (which need careful case-by-case checking), and instead replace kmalloc-family calls that allocate struct or union object instances: Single allocations: kmalloc(sizeof(TYPE), ...) are replaced with: kmalloc_obj(TYPE, ...) Array allocations: kmalloc_array(COUNT, sizeof(TYPE), ...) are replaced with: kmalloc_objs(TYPE, COUNT, ...) Flex array allocations: kmalloc(struct_size(PTR, FAM, COUNT), ...) are replaced with: kmalloc_flex(*PTR, FAM, COUNT, ...) (where TYPE may also be *VAR) The resulting allocations no longer return "void *", instead returning "TYPE *". Signed-off-by: Kees Cook <kees@kernel.org>
2026-02-12Merge tag 'fs_for_v6.20-rc1' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs Pull quota and isofs updates from Jan Kara: - a fix for quotactl livelock during filesystem freezing - a small improvement for isofs - a documentation fix for ext2 * tag 'fs_for_v6.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: isofs: support full length file names (255 instead of 253) quota: fix livelock between quotactl and freeze_super doc : fix a broken link in ext2.rst
2026-01-28isofs: support full length file names (255 instead of 253)Shawn Landden
Linux file names are in principle limited only to PATH_MAX (which is 4096) but the code in get_rock_ridge_filename() limits them to 253 characters. As mentioned by Jan Kara, the Rockridge standard to ECMA119/ISO9660 has no limit of file name length, but this limits file names to the traditional 255 NAME_MAX value. Signed-off-by: Shawn Landden <slandden@gmail.com> Link: https://patch.msgid.link/CA+49okq0ouJvAx0=txR_gyNKtZj55p3Zw4MB8jXZsGr4bEGjRA@mail.gmail.com Signed-off-by: Jan Kara <jack@suse.cz>
2026-01-12fs: add setlease to generic_ro_fops and read-only filesystem directory ↵Jeff Layton
operations Add the setlease file_operation to generic_ro_fops, which covers file operations for several read-only filesystems (BEFS, EFS, ISOFS, QNX4, QNX6, CRAMFS, FREEVXFS). Also add setlease to the directory file_operations for these filesystems. A future patch will change the default behavior to reject lease attempts with -EINVAL when there is no setlease file operation defined. Add generic_setlease to retain the ability to set leases on these filesystems. Signed-off-by: Jeff Layton <jlayton@kernel.org> Link: https://patch.msgid.link/20260108-setlease-6-20-v1-1-ea4dec9b67fa@kernel.org Acked-by: Al Viro <viro@zeniv.linux.org.uk> Acked-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Jan Kara <jack@suse.cz> Signed-off-by: Christian Brauner <brauner@kernel.org>
2025-12-01Merge tag 'vfs-6.19-rc1.inode' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull vfs inode updates from Christian Brauner: "Features: - Hide inode->i_state behind accessors. Open-coded accesses prevent asserting they are done correctly. One obvious aspect is locking, but significantly more can be checked. For example it can be detected when the code is clearing flags which are already missing, or is setting flags when it is illegal (e.g., I_FREEING when ->i_count > 0) - Provide accessors for ->i_state, converts all filesystems using coccinelle and manual conversions (btrfs, ceph, smb, f2fs, gfs2, overlayfs, nilfs2, xfs), and makes plain ->i_state access fail to compile - Rework I_NEW handling to operate without fences, simplifying the code after the accessor infrastructure is in place Cleanups: - Move wait_on_inode() from writeback.h to fs.h - Spell out fenced ->i_state accesses with explicit smp_wmb/smp_rmb for clarity - Cosmetic fixes to LRU handling - Push list presence check into inode_io_list_del() - Touch up predicts in __d_lookup_rcu() - ocfs2: retire ocfs2_drop_inode() and I_WILL_FREE usage - Assert on ->i_count in iput_final() - Assert ->i_lock held in __iget() Fixes: - Add missing fences to I_NEW handling" * tag 'vfs-6.19-rc1.inode' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (22 commits) dcache: touch up predicts in __d_lookup_rcu() fs: push list presence check into inode_io_list_del() fs: cosmetic fixes to lru handling fs: rework I_NEW handling to operate without fences fs: make plain ->i_state access fail to compile xfs: use the new ->i_state accessors nilfs2: use the new ->i_state accessors overlayfs: use the new ->i_state accessors gfs2: use the new ->i_state accessors f2fs: use the new ->i_state accessors smb: use the new ->i_state accessors ceph: use the new ->i_state accessors btrfs: use the new ->i_state accessors Manual conversion to use ->i_state accessors of all places not covered by coccinelle Coccinelle-based conversion to use ->i_state accessors fs: provide accessors for ->i_state fs: spell out fenced ->i_state accesses with explicit smp_wmb/smp_rmb fs: move wait_on_inode() from writeback.h to fs.h fs: add missing fences to I_NEW handling ocfs2: retire ocfs2_drop_inode() and I_WILL_FREE usage ...
2025-11-05isofs: check the return value of sb_min_blocksize() in isofs_fill_superYongpeng Yang
sb_min_blocksize() may return 0. Check its return value to avoid opt->blocksize and sb->s_blocksize is 0. Cc: stable@vger.kernel.org # v6.15 Fixes: 1b17a46c9243e9 ("isofs: convert isofs to use the new mount API") Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com> Link: https://patch.msgid.link/20251104125009.2111925-4-yangyongpeng.storage@gmail.com Signed-off-by: Christian Brauner <brauner@kernel.org>
2025-10-20Coccinelle-based conversion to use ->i_state accessorsMateusz Guzik
All places were patched by coccinelle with the default expecting that ->i_lock is held, afterwards entries got fixed up by hand to use unlocked variants as needed. The script: @@ expression inode, flags; @@ - inode->i_state & flags + inode_state_read(inode) & flags @@ expression inode, flags; @@ - inode->i_state &= ~flags + inode_state_clear(inode, flags) @@ expression inode, flag1, flag2; @@ - inode->i_state &= ~flag1 & ~flag2 + inode_state_clear(inode, flag1 | flag2) @@ expression inode, flags; @@ - inode->i_state |= flags + inode_state_set(inode, flags) @@ expression inode, flags; @@ - inode->i_state = flags + inode_state_assign(inode, flags) @@ expression inode, flags; @@ - flags = inode->i_state + flags = inode_state_read(inode) @@ expression inode, flags; @@ - READ_ONCE(inode->i_state) & flags + inode_state_read(inode) & flags Signed-off-by: Mateusz Guzik <mjguzik@gmail.com> Signed-off-by: Christian Brauner <brauner@kernel.org>
2025-07-28Merge tag 'pull-dcache' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs Pull dentry d_flags updates from Al Viro: "The current exclusion rules for dentry->d_flags stores are rather unpleasant. The basic rules are simple: - stores to dentry->d_flags are OK under dentry->d_lock - stores to dentry->d_flags are OK in the dentry constructor, before becomes potentially visible to other threads Unfortunately, there's a couple of exceptions to that, and that's where the headache comes from. The main PITA comes from d_set_d_op(); that primitive sets ->d_op of dentry and adjusts the flags that correspond to presence of individual methods. It's very easy to misuse; existing uses _are_ safe, but proof of correctness is brittle. Use in __d_alloc() is safe (we are within a constructor), but we might as well precalculate the initial value of 'd_flags' when we set the default ->d_op for given superblock and set 'd_flags' directly instead of messing with that helper. The reasons why other uses are safe are bloody convoluted; I'm not going to reproduce it here. See [1] for gory details, if you care. The critical part is using d_set_d_op() only just prior to d_splice_alias(), which makes a combination of d_splice_alias() with setting ->d_op, etc a natural replacement primitive. Better yet, if we go that way, it's easy to take setting ->d_op and modifying 'd_flags' under ->d_lock, which eliminates the headache as far as 'd_flags' exclusion rules are concerned. Other exceptions are minor and easy to deal with. What this series does: - d_set_d_op() is no longer available; instead a new primitive (d_splice_alias_ops()) is provided, equivalent to combination of d_set_d_op() and d_splice_alias(). - new field of struct super_block - 's_d_flags'. This sets the default value of 'd_flags' to be used when allocating dentries on this filesystem. - new primitive for setting 's_d_op': set_default_d_op(). This replaces stores to 's_d_op' at mount time. All in-tree filesystems converted; out-of-tree ones will get caught by the compiler ('s_d_op' is renamed, so stores to it will be caught). 's_d_flags' is set by the same primitive to match the 's_d_op'. - a lot of filesystems had sb->s_d_op->d_delete equal to always_delete_dentry; that is equivalent to setting DCACHE_DONTCACHE in 'd_flags', so such filesystems can bloody well set that bit in 's_d_flags' and drop 'd_delete()' from dentry_operations. In quite a few cases that results in empty dentry_operations, which means that we can get rid of those. - kill simple_dentry_operations - not needed anymore - massage d_alloc_parallel() to get rid of the other exception wrt 'd_flags' stores - we can set DCACHE_PAR_LOOKUP as soon as we allocate the new dentry; no need to delay that until we commit to using the sucker. As the result, 'd_flags' stores are all either under ->d_lock or done before the dentry becomes visible in any shared data structures" Link: https://lore.kernel.org/all/20250224010624.GT1977892@ZenIV/ [1] * tag 'pull-dcache' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (21 commits) configfs: use DCACHE_DONTCACHE debugfs: use DCACHE_DONTCACHE efivarfs: use DCACHE_DONTCACHE instead of always_delete_dentry() 9p: don't bother with always_delete_dentry ramfs, hugetlbfs, mqueue: set DCACHE_DONTCACHE kill simple_dentry_operations devpts, sunrpc, hostfs: don't bother with ->d_op shmem: no dentry retention past the refcount reaching zero d_alloc_parallel(): set DCACHE_PAR_LOOKUP earlier make d_set_d_op() static simple_lookup(): just set DCACHE_DONTCACHE tracefs: Add d_delete to remove negative dentries set_default_d_op(): calculate the matching value for ->d_flags correct the set of flags forbidden at d_set_d_op() time split d_flags calculation out of d_set_d_op() new helper: set_default_d_op() fuse: no need for special dentry_operations for root dentry switch procfs from d_set_d_op() to d_splice_alias_ops() new helper: d_splice_alias_ops() procfs: kill ->proc_dops ...
2025-07-11isofs: Verify inode mode when loading from diskJan Kara
Verify that the inode mode is sane when loading it from the disk to avoid complaints from VFS about setting up invalid inodes. Reported-by: syzbot+895c23f6917da440ed0d@syzkaller.appspotmail.com CC: stable@vger.kernel.org Signed-off-by: Jan Kara <jack@suse.cz> Link: https://lore.kernel.org/20250709095545.31062-2-jack@suse.cz Acked-by: Christian Brauner <brauner@kernel.org> Signed-off-by: Christian Brauner <brauner@kernel.org>
2025-06-10new helper: set_default_d_op()Al Viro
... to be used instead of manually assigning to ->s_d_op. All in-tree filesystem converted (and field itself is renamed, so any out-of-tree ones in need of conversion will be caught by compiler). Reviewed-by: Christian Brauner <brauner@kernel.org> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2025-04-15isofs: fix Y2038 and Y2156 issues in Rock Ridge TF entryJonas 'Sortie' Termansen
This change implements the Rock Ridge TF entry LONG_FORM bit, which uses the ISO 9660 17-byte date format (up to year 9999, with 10ms precision) instead of the 7-byte date format (up to year 2155, with 1s precision). Previously the LONG_FORM bit was ignored; and isofs would entirely misinterpret the date as the wrong format, resulting in garbage timestamps on the filesystem. The Y2038 issue in iso_date() is fixed by returning a struct timespec64 instead of an int. parse_rock_ridge_inode_internal() is fixed so it does proper bounds checks of the TF entry timestamps. Signed-off-by: Jonas 'Sortie' Termansen <sortie@maxsi.org> Signed-off-by: Jan Kara <jack@suse.cz> Link: https://patch.msgid.link/20250411145022.2292255-1-sortie@maxsi.org
2025-04-04isofs: Prevent the use of too small fidEdward Adam Davis
syzbot reported a slab-out-of-bounds Read in isofs_fh_to_parent. [1] The handle_bytes value passed in by the reproducing program is equal to 12. In handle_to_path(), only 12 bytes of memory are allocated for the structure file_handle->f_handle member, which causes an out-of-bounds access when accessing the member parent_block of the structure isofs_fid in isofs, because accessing parent_block requires at least 16 bytes of f_handle. Here, fh_len is used to indirectly confirm that the value of handle_bytes is greater than 3 before accessing parent_block. [1] BUG: KASAN: slab-out-of-bounds in isofs_fh_to_parent+0x1b8/0x210 fs/isofs/export.c:183 Read of size 4 at addr ffff0000cc030d94 by task syz-executor215/6466 CPU: 1 UID: 0 PID: 6466 Comm: syz-executor215 Not tainted 6.14.0-rc7-syzkaller-ga2392f333575 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2025 Call trace: show_stack+0x2c/0x3c arch/arm64/kernel/stacktrace.c:466 (C) __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0xe4/0x150 lib/dump_stack.c:120 print_address_description mm/kasan/report.c:408 [inline] print_report+0x198/0x550 mm/kasan/report.c:521 kasan_report+0xd8/0x138 mm/kasan/report.c:634 __asan_report_load4_noabort+0x20/0x2c mm/kasan/report_generic.c:380 isofs_fh_to_parent+0x1b8/0x210 fs/isofs/export.c:183 exportfs_decode_fh_raw+0x2dc/0x608 fs/exportfs/expfs.c:523 do_handle_to_path+0xa0/0x198 fs/fhandle.c:257 handle_to_path fs/fhandle.c:385 [inline] do_handle_open+0x8cc/0xb8c fs/fhandle.c:403 __do_sys_open_by_handle_at fs/fhandle.c:443 [inline] __se_sys_open_by_handle_at fs/fhandle.c:434 [inline] __arm64_sys_open_by_handle_at+0x80/0x94 fs/fhandle.c:434 __invoke_syscall arch/arm64/kernel/syscall.c:35 [inline] invoke_syscall+0x98/0x2b8 arch/arm64/kernel/syscall.c:49 el0_svc_common+0x130/0x23c arch/arm64/kernel/syscall.c:132 do_el0_svc+0x48/0x58 arch/arm64/kernel/syscall.c:151 el0_svc+0x54/0x168 arch/arm64/kernel/entry-common.c:744 el0t_64_sync_handler+0x84/0x108 arch/arm64/kernel/entry-common.c:762 el0t_64_sync+0x198/0x19c arch/arm64/kernel/entry.S:600 Allocated by task 6466: kasan_save_stack mm/kasan/common.c:47 [inline] kasan_save_track+0x40/0x78 mm/kasan/common.c:68 kasan_save_alloc_info+0x40/0x50 mm/kasan/generic.c:562 poison_kmalloc_redzone mm/kasan/common.c:377 [inline] __kasan_kmalloc+0xac/0xc4 mm/kasan/common.c:394 kasan_kmalloc include/linux/kasan.h:260 [inline] __do_kmalloc_node mm/slub.c:4294 [inline] __kmalloc_noprof+0x32c/0x54c mm/slub.c:4306 kmalloc_noprof include/linux/slab.h:905 [inline] handle_to_path fs/fhandle.c:357 [inline] do_handle_open+0x5a4/0xb8c fs/fhandle.c:403 __do_sys_open_by_handle_at fs/fhandle.c:443 [inline] __se_sys_open_by_handle_at fs/fhandle.c:434 [inline] __arm64_sys_open_by_handle_at+0x80/0x94 fs/fhandle.c:434 __invoke_syscall arch/arm64/kernel/syscall.c:35 [inline] invoke_syscall+0x98/0x2b8 arch/arm64/kernel/syscall.c:49 el0_svc_common+0x130/0x23c arch/arm64/kernel/syscall.c:132 do_el0_svc+0x48/0x58 arch/arm64/kernel/syscall.c:151 el0_svc+0x54/0x168 arch/arm64/kernel/entry-common.c:744 el0t_64_sync_handler+0x84/0x108 arch/arm64/kernel/entry-common.c:762 el0t_64_sync+0x198/0x19c arch/arm64/kernel/entry.S:600 Reported-by: syzbot+4d7cd7dd0ce1aa8d5c65@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=4d7cd7dd0ce1aa8d5c65 Tested-by: syzbot+4d7cd7dd0ce1aa8d5c65@syzkaller.appspotmail.com CC: stable@vger.kernel.org Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Edward Adam Davis <eadavis@qq.com> Signed-off-by: Jan Kara <jack@suse.cz> Link: https://patch.msgid.link/tencent_9C8CB8A7E7C6C512C7065DC98B6EDF6EC606@qq.com
2025-02-12isofs: fix KMSAN uninit-value bug in do_isofs_readdir()Qasim Ijaz
In do_isofs_readdir() when assigning the variable "struct iso_directory_record *de" the b_data field of the buffer_head is accessed and an offset is added to it, the size of b_data is 2048 and the offset size is 2047, meaning "de = (struct iso_directory_record *) (bh->b_data + offset);" yields the final byte of the 2048 sized b_data block. The first byte of the directory record (de_len) is then read and found to be 31, meaning the directory record size is 31 bytes long. The directory record is defined by the structure: struct iso_directory_record { __u8 length; // 1 byte __u8 ext_attr_length; // 1 byte __u8 extent[8]; // 8 bytes __u8 size[8]; // 8 bytes __u8 date[7]; // 7 bytes __u8 flags; // 1 byte __u8 file_unit_size; // 1 byte __u8 interleave; // 1 byte __u8 volume_sequence_number[4]; // 4 bytes __u8 name_len; // 1 byte char name[]; // variable size } __attribute__((packed)); The fixed portion of this structure occupies 33 bytes. Therefore, a valid directory record must be at least 33 bytes long (even without considering the variable-length name field). Since de_len is only 31, it is insufficient to contain the complete fixed header. The code later hits the following sanity check that compares de_len against the sum of de->name_len and sizeof(struct iso_directory_record): if (de_len < de->name_len[0] + sizeof(struct iso_directory_record)) { ... } Since the fixed portion of the structure is 33 bytes (up to and including name_len member), a valid record should have de_len of at least 33 bytes; here, however, de_len is too short, and the field de->name_len (located at offset 32) is accessed even though it lies beyond the available 31 bytes. This access on the corrupted isofs data triggers a KASAN uninitialized memory warning. The fix would be to first verify that de_len is at least sizeof(struct iso_directory_record) before accessing any fields like de->name_len. Reported-by: syzbot <syzbot+812641c6c3d7586a1613@syzkaller.appspotmail.com> Tested-by: syzbot <syzbot+812641c6c3d7586a1613@syzkaller.appspotmail.com> Closes: https://syzkaller.appspot.com/bug?extid=812641c6c3d7586a1613 Fixes: 2deb1acc653c ("isofs: fix access to unallocated memory when reading corrupted filesystem") Signed-off-by: Qasim Ijaz <qasdev00@gmail.com> Signed-off-by: Jan Kara <jack@suse.cz> Link: https://patch.msgid.link/20250211195900.42406-1-qasdev00@gmail.com
2024-12-05isofs: Partially convert zisofs_read_folio to use a folioMatthew Wilcox (Oracle)
Remove several hidden calls to compound_head() and references to page->index. More needs to be done to use folios throughout the zisofs code. Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> Signed-off-by: Jan Kara <jack@suse.cz> Link: https://patch.msgid.link/20241125180117.2914311-1-willy@infradead.org
2024-11-06isofs: avoid memory leak in iocharsetHao Ge
A memleak was found as below: unreferenced object 0xffff0000d10164d8 (size 8): comm "pool-udisksd", pid 108217, jiffies 4295408555 hex dump (first 8 bytes): 75 74 66 38 00 cc cc cc utf8.... backtrace (crc de430d31): [<ffff800081046e6c>] kmemleak_alloc+0xb8/0xc8 [<ffff8000803e6c3c>] __kmalloc_node_track_caller_noprof+0x380/0x474 [<ffff800080363b74>] kstrdup+0x70/0xfc [<ffff80007bb3c6a4>] isofs_parse_param+0x228/0x2c0 [isofs] [<ffff8000804d7f68>] vfs_parse_fs_param+0xf4/0x164 [<ffff8000804d8064>] vfs_parse_fs_string+0x8c/0xd4 [<ffff8000804d815c>] vfs_parse_monolithic_sep+0xb0/0xfc [<ffff8000804d81d8>] generic_parse_monolithic+0x30/0x3c [<ffff8000804d8bfc>] parse_monolithic_mount_data+0x40/0x4c [<ffff8000804b6a64>] path_mount+0x6c4/0x9ec [<ffff8000804b6e38>] do_mount+0xac/0xc4 [<ffff8000804b7494>] __arm64_sys_mount+0x16c/0x2b0 [<ffff80008002b8dc>] invoke_syscall+0x7c/0x104 [<ffff80008002ba44>] el0_svc_common.constprop.1+0xe0/0x104 [<ffff80008002ba94>] do_el0_svc+0x2c/0x38 [<ffff800081041108>] el0_svc+0x3c/0x1b8 The opt->iocharset is freed inside the isofs_fill_super function, But there may be situations where it's not possible to enter this function. For example, in the get_tree_bdev_flags function,when encountering the situation where "Can't mount, would change RO state," In such a case, isofs_fill_super will not have the opportunity to be called,which means that opt->iocharset will not have the chance to be freed,ultimately leading to a memory leak. Let's move the memory freeing of opt->iocharset into isofs_free_fc function. Fixes: 1b17a46c9243 ("isofs: convert isofs to use the new mount API") Signed-off-by: Hao Ge <gehao@kylinos.cn> Reviewed-by: Eric Sandeen <sandeen@redhat.com> Signed-off-by: Jan Kara <jack@suse.cz> Link: https://patch.msgid.link/20241106082841.51773-1-hao.ge@linux.dev
2024-10-02move asm/unaligned.h to linux/unaligned.hAl Viro
asm/unaligned.h is always an include of asm-generic/unaligned.h; might as well move that thing to linux/unaligned.h and include that - there's nothing arch-specific in that header. auto-generated by the following: for i in `git grep -l -w asm/unaligned.h`; do sed -i -e "s/asm\/unaligned.h/linux\/unaligned.h/" $i done for i in `git grep -l -w asm-generic/unaligned.h`; do sed -i -e "s/asm-generic\/unaligned.h/linux\/unaligned.h/" $i done git mv include/asm-generic/unaligned.h include/linux/unaligned.h git mv tools/include/asm-generic/unaligned.h tools/include/linux/unaligned.h sed -i -e "/unaligned.h/d" include/asm-generic/Kbuild sed -i -e "s/__ASM_GENERIC/__LINUX/" include/linux/unaligned.h tools/include/linux/unaligned.h
2024-09-02isofs: Annotate struct SL_component with __counted_by()Thorsten Blum
Add the __counted_by compiler attribute to the flexible array member text to improve access bounds-checking via CONFIG_UBSAN_BOUNDS and CONFIG_FORTIFY_SOURCE. Signed-off-by: Thorsten Blum <thorsten.blum@toblux.com> Signed-off-by: Jan Kara <jack@suse.cz> Link: https://patch.msgid.link/20240830164902.112682-2-thorsten.blum@toblux.com
2024-07-17Merge tag 'fs_for_v6.11-rc1' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs Pull udf, ext2, isofs fixes and cleanups from Jan Kara: - A few UDF cleanups and fixes for handling corrupted filesystems - ext2 fix for handling of corrupted filesystem - isofs module description - jbd2 module description * tag 'fs_for_v6.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: ext2: Verify bitmap and itable block numbers before using them udf: prevent integer overflow in udf_bitmap_free_blocks() udf: Avoid excessive partition lengths udf: Drop load_block_bitmap() wrapper udf: Avoid using corrupted block bitmap buffer udf: Fix bogus checksum computation in udf_rename() udf: Fix lock ordering in udf_evict_inode() udf: Drop pointless IS_IMMUTABLE and IS_APPEND check isofs: add missing MODULE_DESCRIPTION() jbd2: add missing MODULE_DESCRIPTION()
2024-07-15Merge tag 'vfs-6.11.mount.api' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull vfs mount API updates from Christian Brauner: - Add a generic helper to parse uid and gid mount options. Currently we open-code the same logic in various filesystems which is error prone, especially since the verification of uid and gid mount options is a sensitive operation in the face of idmappings. Add a generic helper and convert all filesystems over to it. Make sure that filesystems that are mountable in unprivileged containers verify that the specified uid and gid can be represented in the owning namespace of the filesystem. - Convert hostfs to the new mount api. * tag 'vfs-6.11.mount.api' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: fuse: Convert to new uid/gid option parsing helpers fuse: verify {g,u}id mount options correctly fat: Convert to new uid/gid option parsing helpers fat: Convert to new mount api fat: move debug into fat_mount_options vboxsf: Convert to new uid/gid option parsing helpers tracefs: Convert to new uid/gid option parsing helpers smb: client: Convert to new uid/gid option parsing helpers tmpfs: Convert to new uid/gid option parsing helpers ntfs3: Convert to new uid/gid option parsing helpers isofs: Convert to new uid/gid option parsing helpers hugetlbfs: Convert to new uid/gid option parsing helpers ext4: Convert to new uid/gid option parsing helpers exfat: Convert to new uid/gid option parsing helpers efivarfs: Convert to new uid/gid option parsing helpers debugfs: Convert to new uid/gid option parsing helpers autofs: Convert to new uid/gid option parsing helpers fs_parse: add uid & gid option option parsing helpers hostfs: Add const qualifier to host_root in hostfs_fill_super() hostfs: convert hostfs to use the new mount API
2024-07-02isofs: Convert to new uid/gid option parsing helpersEric Sandeen
Convert to new uid/gid option parsing helpers Signed-off-by: Eric Sandeen <sandeen@redhat.com> Link: https://lore.kernel.org/r/3e57caa1-33e0-4456-8e07-60922439e479@redhat.com Signed-off-by: Christian Brauner <brauner@kernel.org>