From: David Howells <dhowells@xxxxxxxxxx> commit 2ed147f015af2b48f41c6f0b6746aa9ea85c19f3 upstream. There's nothing to synchronise post_one_notification() versus pipe_read(). Whilst posting is done under pipe->rd_wait.lock, the reader only takes pipe->mutex which cannot bar notification posting as that may need to be made from contexts that cannot sleep. Fix this by setting pipe->head with a barrier in post_one_notification() and reading pipe->head with a barrier in pipe_read(). If that's not sufficient, the rd_wait.lock will need to be taken, possibly in a ->confirm() op so that it only applies to notifications. The lock would, however, have to be dropped before copy_page_to_iter() is invoked. Fixes: c73be61cede5 ("pipe: Add general notification queue support") Reported-by: Jann Horn <jannh@xxxxxxxxxx> Signed-off-by: David Howells <dhowells@xxxxxxxxxx> Signed-off-by: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- fs/pipe.c | 3 ++- kernel/watch_queue.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) --- a/fs/pipe.c +++ b/fs/pipe.c @@ -252,7 +252,8 @@ pipe_read(struct kiocb *iocb, struct iov */ was_full = pipe_full(pipe->head, pipe->tail, pipe->max_usage); for (;;) { - unsigned int head = pipe->head; + /* Read ->head with a barrier vs post_one_notification() */ + unsigned int head = smp_load_acquire(&pipe->head); unsigned int tail = pipe->tail; unsigned int mask = pipe->ring_size - 1; --- a/kernel/watch_queue.c +++ b/kernel/watch_queue.c @@ -113,7 +113,7 @@ static bool post_one_notification(struct buf->offset = offset; buf->len = len; buf->flags = PIPE_BUF_FLAG_WHOLE; - pipe->head = head + 1; + smp_store_release(&pipe->head, head + 1); /* vs pipe_read() */ if (!test_and_clear_bit(note, wqueue->notes_bitmap)) { spin_unlock_irq(&pipe->rd_wait.lock); Patches currently in stable-queue which might be from dhowells@xxxxxxxxxx are queue-5.16/watch_queue-fix-lack-of-barrier-sync-lock-between-post-and-read.patch queue-5.16/watch_queue-pipe-free-watchqueue-state-after-clearing-pipe-ring.patch queue-5.16/watch_queue-make-comment-about-setting-defunct-more-accurate.patch queue-5.16/watch_queue-fix-the-alloc-bitmap-size-to-reflect-notes-allocated.patch queue-5.16/watch_queue-free-the-alloc-bitmap-when-the-watch_queue-is-torn-down.patch queue-5.16/watch_queue-fix-to-always-request-a-pow-of-2-pipe-ring-size.patch queue-5.16/watch_queue-fix-filter-limit-check.patch queue-5.16/watch_queue-fix-to-release-page-in-release.patch