From: Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp
[ Upstream commit 4e8011ffec79717e5fdac43a7e79faf811a384b7 ]
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 $Extend records.
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 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:
YES
- Fixes a real bug triggered by VFS invariants: After vfs change af153bb63a33 (“vfs: catch invalid modes in may_open()”), inodes must have a valid S_IFMT type. ntfs3 could leave $Extend records with an invalid/zero mode, causing may_open() to reject or warn on opens. The patch makes these records appear as regular files, satisfying the VFS type check. - Small, local, and low-risk change: Only one code path is touched in a single file, with a one-line assignment in a narrow case. - In the $Extend-specific branch in `ntfs_read_mft()`, the code now sets a valid file type: `mode = S_IFREG;` immediately after identifying an $Extend record and setting inode ops (fs/ntfs3/inode.c:470-474). - The mode is then stored into the inode as usual (`inode->i_mode = mode;`, fs/ntfs3/inode.c:488), ensuring the inode passes VFS type checks. - Constrained to special metadata records: The branch only triggers when the filename references the $Extend MFT record (`fname->home.low == cpu_to_le32(MFT_REC_EXTEND)` and `fname->home.seq == cpu_to_le16(MFT_REC_EXTEND)`, fs/ntfs3/inode.c:470-471). Regular files/dirs/symlinks/special devices remain unaffected. - Preserves ntfs3 behavior while satisfying VFS: The $Extend branch still sets only `i_op = &ntfs_file_inode_operations` (fs/ntfs3/inode.c:473), unlike the normal regular-file branch which also sets `i_fop` and `a_ops` (fs/ntfs3/inode.c:456-465). So $Extend records won’t gain full file operations; they simply have a valid S_IFMT for VFS. This minimizes behavioral change while fixing the bug. - No architectural changes or cross-subsystem impact: The patch does not alter VFS or broader kernel APIs; it’s contained within ntfs3’s inode setup logic. - Aligns with stable rules: - Important bugfix reported by syzbot (Closes: the linked syzkaller bug). - Minimal change and clear rationale. - Low regression risk and limited scope (ntfs3 only). - Forward/backward compatibility: Even on trees without the may_open() enforcement, setting a valid type for these metadata inodes is harmless and arguably improves correctness. On trees with af153bb63a33, it avoids spurious failures/warnings.
Conclusion: This is a targeted bugfix to comply with VFS invariants and prevent failures when interacting with $Extend records. It’s safe and appropriate to backport to stable kernels that include ntfs3 and the may_open() invariant check.
fs/ntfs3/inode.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c index 37cbbee7fa580..b08b009121653 100644 --- a/fs/ntfs3/inode.c +++ b/fs/ntfs3/inode.c @@ -471,6 +471,7 @@ static struct inode *ntfs_read_mft(struct inode *inode, fname->home.seq == cpu_to_le16(MFT_REC_EXTEND)) { /* Records in $Extend are not a files or general directories. */ inode->i_op = &ntfs_file_inode_operations; + mode = S_IFREG; } else { err = -EINVAL; goto out;