Re: [PATCH V2] fs: improve the check of whether i_link has been set

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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.




[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux