Re: [syzbot] [exfat?] [ocfs2?] kernel BUG in link_path_walk

Mateusz Guzik
2025-12-04T08:40:15Z

On Thu, Dec 4, 2025 at 9:21 AM Al Viro <viro@zeniv.linux.org.uk> wrote:
>
> On Thu, Dec 04, 2025 at 08:45:08AM +0100, Mateusz Guzik wrote:
>
> > Or to put it differently, lookup got entered with a bogus state of a
> > dentry claiming it is a directory, with an inode which is not. Per the
> > i_mode reported in the opening mail it is a regular file instead.
> >
> > While I don't see how this can happen,
>
> ->i_op set to something with ->lookup != NULL, ->i_mode - to regular.
> Which is to say, bogus ->i_mode change somewhere.
>
> Theoretically it should bail out, having detected the type change
> (on inode_wrong_type()). I'd suggest slapping
> BUG_ON(inode_wrong_type(inode, new_i_mode_value));
> in front of all reassignments (ocfs2_populate_inode() is the initialization
> and thus exempt; all other stores to ->i_mode of struct inode in there
> are, in principle, suspect. Something like inode->i_mode &= ~S_ISUID
> doesn't need checking - we obviously can't change the type there.
> Unpleasant part is that struct ocfs2_dinode also has a member called
> i_mode (__le16, that one), so stores to that clutter the grep results...

Now that I wrote this I suspect there is at least one way, regardless
of whether ocfs2 is culprit.

Suppose you are in rcu-walk and someone continuously issues mkdir,
rmdir, creat, unlink on the same pathname. Affected dentry will keep
flipping between directory, negative entry and regular.

While such fuckery will be caught with seq changes, perhaps the
intermediate state can indeed result in finding such a mismatch but
only because of a race.

I'm going to have to chew on it, I don't know if I';ll have time today
to deal with it. Worst case the fix will be to check if this is a dir
in lookup_inode_permission_may_exec instead of merely asserting on it.