• Linus Torvalds's avatar
    vfs: fix subtle use-after-free of pipe_inode_info · b0d8d229
    Linus Torvalds authored
    The pipe code was trying (and failing) to be very careful about freeing
    the pipe info only after the last access, with a pattern like:
    
            spin_lock(&inode->i_lock);
            if (!--pipe->files) {
                    inode->i_pipe = NULL;
                    kill = 1;
            }
            spin_unlock(&inode->i_lock);
            __pipe_unlock(pipe);
            if (kill)
                    free_pipe_info(pipe);
    
    where the final freeing is done last.
    
    HOWEVER.  The above is actually broken, because while the freeing is
    done at the end, if we have two racing processes releasing the pipe
    inode info, the one that *doesn't* free it will decrement the ->files
    count, and unlock the inode i_lock, but then still use the
    "pipe_inode_info" afterwards when it does the "__pipe_unlock(pipe)".
    
    This is *very* hard to trigger in practice, since the race window is
    very small, and adding debug options seems to just hide it by slowing
    things down.
    
    Simon originally reported this way back in J...
    b0d8d229
pipe.c 29.2 KB