Re: Kernel crash in free_pipe_info()

From: Al Viro
Date: Tue Oct 31 2017 - 01:00:08 EST


On Mon, Oct 30, 2017 at 08:06:23PM -0700, Linus Torvalds wrote:

> We do that "free_pipe_info(inode->i_pipe);", but we never actually
> clear inode->i_pipe, so now we have an inode that looks like a pipe
> inode, and has a stale pointer to a pipe_inode_info.
>
> It all looks technically correct. It's fine to use put_filp(), because
> the file pointer has never really been used. And the inode should
> never get re-used anyway without going through the whole reinit in
> inode_init_always().
>
> So I don't see anything *wrong*, but I see a lot that is just unusual,

FWIW, it's really brittle - consider
if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
i_readcount_inc(path->dentry->d_inode);
in alloc_file(). It's not the source of trouble in this case, but only
because it's the second call that gets FMODE_READ; reorder them in
create_pipe_files() and you've got a bug.

I considered using fput() there, but that would've required manually
decrementing pipe->files first, which made it rather unappealing...

I don't see anything relevant there, but that's not saying much - flu
and debugging do not mix well, and lack of sleep also doesn't help ;-/