Re: inode_permission NULL pointer dereference in 3.13-rc1

Dave Chinner
2013-11-29T01:47:18Z

On Thu, Nov 28, 2013 at 11:44:41PM +0000, Al Viro wrote:
> On Fri, Nov 29, 2013 at 09:51:02AM +1100, Dave Chinner wrote:
>
> > > Looks like adding if (!nd->inode) { a bunch of printks } in the end of
> > > path_init() makes the sucker disappear (so far 2 times out of 2, and
> > > with a test run taking a bit under two hours, well...) The plain
> > > WARN_ON(!nd->inode) in that place triggers just fine.
> >
> > I usually find that when printk() makes race conditions go away,
> > switching to tracepoints works better. It's still not as good as
> > reliable as when the debug is not there, but it seems to perturb
> > race conditions a lot less.
>
> Actually, I've just got the output from this run, and it's really interesting.
> We get path_init() setting NULL nd->inode for open() of "/dev/ptmx" (from
> /sbin/startpar). And what we have at the time we get to link_path_walk() is
> * LOOKUP_RCU | LOOKUP_FOLLOW | LOOKUP_PARENT | LOOKUP_JUMPED in
> nd->flags (as expected)
> * current->fs->root, current->fs->pwd and nd->path being the same
> vfsmount/dentry pair.
> * dentry in question has ->d_sb->s_id containing "sda1", as expected
> for root fs.
> * ->mnt_root of that vfsmount being equal to dentry
> So far, so good, right?
> * d_count(dentry) is -128

void lockref_mark_dead(struct lockref *lockref)
{
assert_spin_locked(&lockref->lock);
lockref->count = -128;
}
EXPORT_SYMBOL(lockref_mark_dead);

Cheers,

Dave.
--
Dave Chinner
david@fromorbit.com