[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20241119163647.GJ3387508@ZenIV>
Date: Tue, 19 Nov 2024 16:36:47 +0000
From: Al Viro <viro@...iv.linux.org.uk>
To: Lizhi Xu <lizhi.xu@...driver.com>
Cc: almaz.alexandrovich@...agon-software.com, brauner@...nel.org,
jack@...e.cz, linux-fsdevel@...r.kernel.org,
linux-kernel@...r.kernel.org, ntfs3@...ts.linux.dev,
syzbot+73d8fc29ec7cba8286fa@...kaller.appspotmail.com,
syzkaller-bugs@...glegroups.com
Subject: Re: [PATCH V2] fs: improve the check of whether i_link has been set
On Tue, Nov 19, 2024 at 07:29:45PM +0800, Lizhi Xu wrote:
> syzbot reported a null-ptr-deref in pick_link. [1]
>
> First, i_link and i_dir_seq are in the same union, they share the same memory
> address, and i_dir_seq will be updated during the execution of walk_component,
> which makes the value of i_link equal to i_dir_seq.
> In this case, setting i_dir_seq is triggered by move_mount, and the calltrace
> is as follows:
> move_mount()->
> user_path_at()->
> filename_lookup()->
> path_lookupat()->
> lookup_last()->
> walk_component()->
> __lookup_slow()->
> ntfs_lookup()->
> d_splice_alias()->
> __d_add()->
> end_dir_add()
>
> In pick_link(), the simple "if (!i_link)" is used to determine whether i_link
> has been set, which is not rigorous enough.
>
> On the other hand, the mode value of the symlink inode becomes REG because
> attr_set_size() fails to set the attribute and calls ntfs_bad_inode().
> By confirming that the i_link pointer value is valid, the null-ptr-deref
> problem in pick_link can be avoided.
So basically your theory is that make_bad_inode() is called on a live directory
inode (already reachable from dcache and remaining there), whereas the sucker
somehow gets a new dentry alias which looks like a symlink. Right?
NAK on the "mitigation", just in case anyone decides to pick that - no matter
how we deal with the problem, sprinkling virt_addr_valid() is *NOT* a solution.
Powered by blists - more mailing lists