From: Sasha Levin <sashal@kernel.org>
To: patches@lists.linux.dev, stable@vger.kernel.org
Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>,
syzbot <syzbot+895c23f6917da440ed0d@syzkaller.appspotmail.com>,
Viacheslav Dubeyko <slava@dubeyko.com>,
Sasha Levin <sashal@kernel.org>,
frank.li@vivo.com, linux-fsdevel@vger.kernel.org
Subject: [PATCH AUTOSEL 6.19-5.10] hfsplus: pretend special inodes as regular files
Date: Tue, 10 Feb 2026 18:31:03 -0500 [thread overview]
Message-ID: <20260210233123.2905307-18-sashal@kernel.org> (raw)
In-Reply-To: <20260210233123.2905307-1-sashal@kernel.org>
From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
[ Upstream commit ed8889ca21b6ab37bc1435c4009ce37a79acb9e6 ]
Since commit af153bb63a33 ("vfs: catch invalid modes in may_open()")
requires any inode be one of S_IFDIR/S_IFLNK/S_IFREG/S_IFCHR/S_IFBLK/
S_IFIFO/S_IFSOCK type, use S_IFREG for special inodes.
Reported-by: syzbot <syzbot+895c23f6917da440ed0d@syzkaller.appspotmail.com>
Closes: https://syzkaller.appspot.com/bug?extid=895c23f6917da440ed0d
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/d0a07b1b-8b73-4002-8e29-e2bd56871262@I-love.SAKURA.ne.jp
Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Now I have a complete picture. Let me compile my analysis.
---
## Detailed Analysis
### 1. Commit Message Analysis
The commit message is clear: HFS+ special/system inodes (catalog, extent
overflow, allocation bitmap, startup, and attributes files) never have
`i_mode` set, leaving it at 0 after `iget_locked()`. This violates the
new VFS requirement (from `af153bb63a33`) that all inodes must have a
valid `S_IF*` type when opened via `may_open()`.
The commit is reported by syzbot with a concrete reproducer and a link
to the syzkaller bug tracker. It's reviewed and signed off by the HFS+
maintainer Viacheslav Dubeyko.
### 2. Code Change Analysis
The fix is a single statement added to `hfsplus_system_read_inode()` in
`fs/hfsplus/super.c`:
```c
inode->i_mode = S_IFREG;
```
This is placed after the switch statement that reads the fork data for
each special inode type (HFSPLUS_EXT_CNID, HFSPLUS_CAT_CNID,
HFSPLUS_ALLOC_CNID, HFSPLUS_START_CNID, HFSPLUS_ATTR_CNID).
**The bug mechanism**: When `hfsplus_iget()` is called for a system
inode (inode number < `HFSPLUS_FIRSTUSER_CNID` and !=
`HFSPLUS_ROOT_CNID`), it calls `hfsplus_system_read_inode()`. This
function sets up the fork data and address space operations but **never
sets `i_mode`**. The `i_mode` remains 0 (the default from
`iget_locked()` → `alloc_inode()`). Zero is not a valid file type - it
doesn't match any of S_IFDIR, S_IFLNK, S_IFREG, S_IFCHR, S_IFBLK,
S_IFIFO, or S_IFSOCK.
When this inode is later opened via a userspace `openat()` syscall
(triggered by syzbot with a crafted filesystem), `may_open()` is called:
```4175:4232:fs/namei.c
static int may_open(struct mnt_idmap *idmap, const struct path *path,
int acc_mode, int flag)
{
// ...
switch (inode->i_mode & S_IFMT) {
case S_IFLNK:
// ...
case S_IFREG:
// ...
default:
VFS_BUG_ON_INODE(!IS_ANON_FILE(inode), inode);
}
```
With `i_mode = 0`, the switch falls to the default case, and since HFS+
special inodes aren't anonymous files, `VFS_BUG_ON_INODE` triggers →
**kernel BUG** (crash). This is confirmed by the syzbot crash report
showing `kernel BUG at fs/namei.c:3474` with a full stack trace through
`may_open` → `do_open` → `path_openat` → `do_filp_open` →
`do_sys_openat2` → `__x64_sys_openat`.
### 3. Relationship to Other Fixes
This is **NOT a duplicate** of `005d4b0d33f6` ("hfsplus: Verify inode
mode when loading from disk"). That fix addresses a DIFFERENT code path:
- `005d4b0d33f6` fixes `hfsplus_get_perms()` in `fs/hfsplus/inode.c` -
validates mode for **user/root inodes** loaded from disk (corrupted
on-disk mode)
- The commit we're analyzing fixes `hfsplus_system_read_inode()` in
`fs/hfsplus/super.c` - sets mode for **special/system inodes** that
never go through `hfsplus_get_perms()` at all
In `hfsplus_iget()`, the two paths are clearly separated:
- `inode->i_ino >= HFSPLUS_FIRSTUSER_CNID || inode->i_ino ==
HFSPLUS_ROOT_CNID` → `hfsplus_cat_read_inode()` →
`hfsplus_get_perms()` (fixed by `005d4b0d33f6`)
- Otherwise → `hfsplus_system_read_inode()` (fixed by THIS commit)
Confirmed via grep: there is literally NO `i_mode` reference in
`fs/hfsplus/super.c` currently.
### 4. CONFIG_DEBUG_VFS Dependency
The `VFS_BUG_ON_INODE` macro is only active when `CONFIG_DEBUG_VFS` is
enabled. Without it, it's compiled to `BUILD_BUG_ON_INVALID(cond)` which
is a no-op at runtime. `CONFIG_DEBUG_VFS` was introduced alongside
`af153bb63a33` in v6.15 (commit `8b17e540969a`).
So the **crash** only occurs on kernels 6.15+ with `CONFIG_DEBUG_VFS`
enabled. However, having `i_mode = 0` is technically incorrect on ALL
kernel versions - any code checking inode type would get wrong results
for these inodes.
### 5. Scope and Risk Assessment
- **Lines changed**: 6 (including comment) - effectively 1 functional
line
- **Files touched**: 1 (`fs/hfsplus/super.c`)
- **Risk**: Essentially zero. Setting `S_IFREG` on internal filesystem
inodes that previously had no type is strictly an improvement. These
inodes are filesystem metadata (btrees, allocation bitmap) - they are
file-like data structures, so `S_IFREG` is appropriate.
- **No behavioral regression**: The fix doesn't change how the
filesystem operates; it only ensures the inode has a valid VFS-level
type.
### 6. User Impact
- **Who's affected**: Anyone mounting HFS+ filesystems on kernels 6.15+
with `CONFIG_DEBUG_VFS`
- **Severity**: Kernel BUG/crash - system goes down
- **Trigger**: syzbot demonstrated this with crafted filesystem images,
but it could potentially also be triggered with corrupted real HFS+
volumes
- **syzbot confirmed**: 17,716 crashes recorded, reproducible with C
reproducer
### 7. Stability Indicators
- Reviewed-by: Viacheslav Dubeyko (HFS+ maintainer)
- Signed-off-by: Viacheslav Dubeyko (maintainer)
- syzbot reported with concrete reproducer
- Part of a series of similar fixes across multiple filesystems (bfs,
cramfs, isofs, jfs, minixfs, nilfs2, ntfs3, squashfs) - the ntfs3
equivalent `4e8011ffec79` is already merged
### 8. Dependencies
The prerequisite VFS commit `af153bb63a33` exists in 6.15+. For older
stable trees (6.14 and below), the `VFS_BUG_ON_INODE` doesn't exist, so
the crash won't happen. However, the fix itself applies cleanly
regardless of version since `hfsplus_system_read_inode()` has been
stable for many years. Setting a proper i_mode is correct behavior
independently of the VFS debug check.
### Conclusion
This is a clear **YES** for stable backporting:
- Fixes a syzbot-reported kernel BUG (crash) - 17,716 crash instances
recorded
- The fix is one functional line: `inode->i_mode = S_IFREG;`
- Zero risk of regression
- Obviously correct - internal inodes should have a valid file type
- Reviewed and accepted by the subsystem maintainer
- Complements the already-merged `005d4b0d33f6` by covering a different
code path
- Part of a broader class of fixes across multiple filesystems for the
same VFS requirement
**YES**
fs/hfsplus/super.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index aaffa9e060a0a..7f327b777ece8 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -53,6 +53,12 @@ static int hfsplus_system_read_inode(struct inode *inode)
return -EIO;
}
+ /*
+ * Assign a dummy file type, for may_open() requires that
+ * an inode has a valid file type.
+ */
+ inode->i_mode = S_IFREG;
+
return 0;
}
--
2.51.0
next prev parent reply other threads:[~2026-02-10 23:31 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-10 23:30 [PATCH AUTOSEL 6.19-6.12] i3c: mipi-i3c-hci: Reset RING_OPERATION1 fields during init Sasha Levin
2026-02-10 23:30 ` [PATCH AUTOSEL 6.19-5.15] gfs2: fiemap page fault fix Sasha Levin
2026-02-10 23:30 ` [PATCH AUTOSEL 6.19-6.18] dlm: fix recovery pending middle conversion Sasha Levin
2026-02-10 23:30 ` [PATCH AUTOSEL 6.19-6.6] smb: client: prevent races in ->query_interfaces() Sasha Levin
2026-02-10 23:30 ` [PATCH AUTOSEL 6.19-6.12] i3c: mipi-i3c-hci: Ensure proper bus clean-up Sasha Levin
2026-02-11 7:56 ` Adrian Hunter
2026-02-10 23:30 ` [PATCH AUTOSEL 6.19-5.10] audit: add fchmodat2() to change attributes class Sasha Levin
2026-02-10 23:30 ` [PATCH AUTOSEL 6.19-6.12] btrfs: fallback to buffered IO if the data profile has duplication Sasha Levin
2026-02-10 23:30 ` [PATCH AUTOSEL 6.19] btrfs: don't BUG() on unexpected delayed ref type in run_one_delayed_ref() Sasha Levin
2026-02-10 23:30 ` [PATCH AUTOSEL 6.19-6.12] i3c: mipi-i3c-hci-pci: Add System Suspend support Sasha Levin
2026-02-11 7:57 ` Adrian Hunter
2026-02-10 23:30 ` [PATCH AUTOSEL 6.19-6.18] hfsplus: fix volume corruption issue for generic/480 Sasha Levin
2026-02-10 23:30 ` [PATCH AUTOSEL 6.19-6.18] kselftest/kublk: include message in _Static_assert for C11 compatibility Sasha Levin
2026-02-10 23:30 ` [PATCH AUTOSEL 6.19-6.12] dlm: validate length in dlm_search_rsb_tree Sasha Levin
2026-02-10 23:30 ` [PATCH AUTOSEL 6.19-6.18] i3c: mipi-i3c-hci: Stop reading Extended Capabilities if capability ID is 0 Sasha Levin
2026-02-10 23:30 ` [PATCH AUTOSEL 6.19-6.1] fs/buffer: add alert in try_to_free_buffers() for folios without buffers Sasha Levin
2026-02-10 23:31 ` [PATCH AUTOSEL 6.19-5.15] i3c: master: svc: Initialize 'dev' to NULL in svc_i3c_master_ibi_isr() Sasha Levin
2026-02-10 23:31 ` [PATCH AUTOSEL 6.19-6.12] statmount: permission check should return EPERM Sasha Levin
2026-02-10 23:31 ` [PATCH AUTOSEL 6.19-5.10] audit: add missing syscalls to read class Sasha Levin
2026-02-10 23:31 ` Sasha Levin [this message]
2026-02-10 23:31 ` [PATCH AUTOSEL 6.19-5.10] hfsplus: fix volume corruption issue for generic/498 Sasha Levin
2026-02-10 23:31 ` [PATCH AUTOSEL 6.19-6.18] netfs: when subreq is marked for retry, do not check if it faced an error Sasha Levin
2026-02-10 23:31 ` [PATCH AUTOSEL 6.19] hfs: Replace BUG_ON with error handling for CNID count checks Sasha Levin
2026-02-10 23:31 ` [PATCH AUTOSEL 6.19-6.1] smb: client: add proper locking around ses->iface_last_update Sasha Levin
2026-02-10 23:31 ` [PATCH AUTOSEL 6.19-6.6] btrfs: handle user interrupt properly in btrfs_trim_fs() Sasha Levin
2026-02-10 23:31 ` [PATCH AUTOSEL 6.19-5.10] minix: Add required sanity checking to minix_check_superblock() Sasha Levin
2026-02-11 7:56 ` [PATCH AUTOSEL 6.19-6.12] i3c: mipi-i3c-hci: Reset RING_OPERATION1 fields during init Adrian Hunter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260210233123.2905307-18-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=frank.li@vivo.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=patches@lists.linux.dev \
--cc=penguin-kernel@I-love.SAKURA.ne.jp \
--cc=slava@dubeyko.com \
--cc=stable@vger.kernel.org \
--cc=syzbot+895c23f6917da440ed0d@syzkaller.appspotmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox