[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <d79cb8dd-7dc3-49da-8fb1-793fa7e2a7e0@I-love.SAKURA.ne.jp>
Date: Sat, 20 Sep 2025 18:42:43 +0900
From: Tetsuo Handa <penguin-kernel@...ove.SAKURA.ne.jp>
To: almaz.alexandrovich@...agon-software.com, ntfs3@...ts.linux.dev,
Edward Adam Davis <eadavis@...com>
Cc: syzbot <syzbot+bdeb22a4b9a09ab9aa45@...kaller.appspotmail.com>,
linux-kernel@...r.kernel.org, syzkaller-bugs@...glegroups.com
Subject: Re: [syzbot] [ntfs3?] INFO: trying to register non-static key in
ntfs_set_size
On 2025/09/16 12:48, Tetsuo Handa wrote:
> Well, we need to also initialize ni->file.run_lock, for vfs_truncate() now
> passes the
>
> /* For directories it's -EISDIR, for other non-regulars - -EINVAL */
> if (S_ISDIR(inode->i_mode))
> return -EISDIR;
> if (!S_ISREG(inode->i_mode))
> return -EINVAL;
>
> check. But do we really want to pretend as if S_IFREG ?
>
> diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c
> index 37cbbee7fa58..ea2193ebf8fc 100644
> --- a/fs/ntfs3/inode.c
> +++ b/fs/ntfs3/inode.c
> @@ -471,6 +471,8 @@ 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;
> + init_rwsem(&ni->file.run_lock);
> } else {
> err = -EINVAL;
> goto out;
>
> Are records in $Extend expected to be truncated to arbitrary size? Should we
> prepend something other than S_IFREG (at least S_IFREG so that truncate()
pretend something other than S_IFREG (at least S_IFDIR so that truncate()
> will fail, or possibly S_IFSOCK so that open() will fail) ?
Well, ntfs_extend_init() verifies that the inode returned as the result of
looking up MFT_REC_EXTEND is S_IFDIR.
ref.low = cpu_to_le32(MFT_REC_EXTEND);
ref.high = 0;
ref.seq = cpu_to_le16(MFT_REC_EXTEND);
inode = ntfs_iget5(sb, &ref, &NAME_EXTEND);
if (IS_ERR(inode)) {
err = PTR_ERR(inode);
ntfs_err(sb, "Failed to load $Extend (%d).", err);
inode = NULL;
goto out;
}
/* If ntfs_iget5() reads from disk it never returns bad inode. */
if (!S_ISDIR(inode->i_mode)) {
err = -EINVAL;
goto out;
}
Then, should ntfs_read_mft() pretend as if S_IFDIR ? Also, are conditions
} else if (fname && fname->home.low == cpu_to_le32(MFT_REC_EXTEND) &&
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;
correct? These conditions do not check ref.high == 0 and name is "$Extend".
Don't we need to verify ref.high and name here?
Powered by blists - more mailing lists