Skip to content

Commit

Permalink
watch_queue, pipe: Free watchqueue state after clearing pipe ring
Browse files Browse the repository at this point in the history
In free_pipe_info(), free the watchqueue state after clearing the pipe
ring as each pipe ring descriptor has a release function, and in the
case of a notification message, this is watch_queue_pipe_buf_release()
which tries to mark the allocation bitmap that was previously released.

Fix this by moving the put of the pipe's ref on the watch queue to after
the ring has been cleared.  We still need to call watch_queue_clear()
before doing that to make sure that the pipe is disconnected from any
notification sources first.

Fixes: c73be61 ("pipe: Add general notification queue support")
Reported-by: Jann Horn <jannh@google.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
dhowells authored and torvalds committed Mar 11, 2022
1 parent c993ee0 commit db8facf
Showing 1 changed file with 5 additions and 3 deletions.
8 changes: 5 additions & 3 deletions fs/pipe.c
Original file line number Diff line number Diff line change
Expand Up @@ -831,10 +831,8 @@ void free_pipe_info(struct pipe_inode_info *pipe)
int i;

#ifdef CONFIG_WATCH_QUEUE
if (pipe->watch_queue) {
if (pipe->watch_queue)
watch_queue_clear(pipe->watch_queue);
put_watch_queue(pipe->watch_queue);
}
#endif

(void) account_pipe_buffers(pipe->user, pipe->nr_accounted, 0);
Expand All @@ -844,6 +842,10 @@ void free_pipe_info(struct pipe_inode_info *pipe)
if (buf->ops)
pipe_buf_release(pipe, buf);
}
#ifdef CONFIG_WATCH_QUEUE
if (pipe->watch_queue)
put_watch_queue(pipe->watch_queue);
#endif
if (pipe->tmp_page)
__free_page(pipe->tmp_page);
kfree(pipe->bufs);
Expand Down

0 comments on commit db8facf

Please sign in to comment.