All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] fs/pipe: Fix lockdep false-positive in watchqueue pipe_write()
@ 2023-11-24 15:08 Jann Horn
  2023-11-24 15:19 ` Christian Brauner
  2023-11-24 15:53 ` David Howells
  0 siblings, 2 replies; 4+ messages in thread
From: Jann Horn @ 2023-11-24 15:08 UTC (permalink / raw)
  To: Alexander Viro, Christian Brauner, David Howells
  Cc: linux-fsdevel, linux-kernel, syzkaller-bugs

When you try to splice between a normal pipe and a notification pipe,
get_pipe_info(..., true) fails, so splice() falls back to treating the
notification pipe like a normal pipe - so we end up in
iter_file_splice_write(), which first locks the input pipe, then calls
vfs_iter_write(), which locks the output pipe.

Lockdep complains about that, because we're taking a pipe lock while
already holding another pipe lock.

I think this probably (?) can't actually lead to deadlocks, since you'd
need another way to nest locking a normal pipe into locking a
watch_queue pipe, but the lockdep annotations don't make that clear.

Bail out earlier in pipe_write() for notification pipes, before taking
the pipe lock.

Reported-and-tested-by: syzbot+011e4ea1da6692cf881c@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=011e4ea1da6692cf881c
Fixes: c73be61cede5 ("pipe: Add general notification queue support")
Signed-off-by: Jann Horn <jannh@google.com>
---
 fs/pipe.c | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/fs/pipe.c b/fs/pipe.c
index 804a7d789452..226e7f66b590 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -446,6 +446,18 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from)
 	bool was_empty = false;
 	bool wake_next_writer = false;
 
+	/*
+	 * Reject writing to watch queue pipes before the point where we lock
+	 * the pipe.
+	 * Otherwise, lockdep would be unhappy if the caller already has another
+	 * pipe locked.
+	 * If we had to support locking a normal pipe and a notification pipe at
+	 * the same time, we could set up lockdep annotations for that, but
+	 * since we don't actually need that, it's simpler to just bail here.
+	 */
+	if (pipe_has_watch_queue(pipe))
+		return -EXDEV;
+
 	/* Null write succeeds. */
 	if (unlikely(total_len == 0))
 		return 0;
@@ -458,11 +470,6 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from)
 		goto out;
 	}
 
-	if (pipe_has_watch_queue(pipe)) {
-		ret = -EXDEV;
-		goto out;
-	}
-
 	/*
 	 * If it wasn't empty we try to merge new data into
 	 * the last buffer.

base-commit: 98b1cc82c4affc16f5598d4fa14b1858671b2263
-- 
2.43.0.rc1.413.gea7ed67945-goog


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] fs/pipe: Fix lockdep false-positive in watchqueue pipe_write()
  2023-11-24 15:08 [PATCH] fs/pipe: Fix lockdep false-positive in watchqueue pipe_write() Jann Horn
@ 2023-11-24 15:19 ` Christian Brauner
  2023-11-24 15:53 ` David Howells
  1 sibling, 0 replies; 4+ messages in thread
From: Christian Brauner @ 2023-11-24 15:19 UTC (permalink / raw)
  To: Jann Horn
  Cc: Christian Brauner, linux-fsdevel, linux-kernel, syzkaller-bugs,
	Alexander Viro, David Howells

On Fri, 24 Nov 2023 16:08:22 +0100, Jann Horn wrote:
> When you try to splice between a normal pipe and a notification pipe,
> get_pipe_info(..., true) fails, so splice() falls back to treating the
> notification pipe like a normal pipe - so we end up in
> iter_file_splice_write(), which first locks the input pipe, then calls
> vfs_iter_write(), which locks the output pipe.
> 
> Lockdep complains about that, because we're taking a pipe lock while
> already holding another pipe lock.
> 
> [...]

Yeah, that looks to be a improvement in general, since you can't upgrade
a regular pipe to a O_NOTIFICATION pipe. IOW, peforming that check with
pipe_lock() isn't necessary.

(The check for watch queue in pipe_set_size() called from pipe_fcntl()
 also wouldn't need to be done with __pipe_lock() held fwiw.)

---

Applied to the vfs.misc branch of the vfs/vfs.git tree.
Patches in the vfs.misc branch should appear in linux-next soon.

Please report any outstanding bugs that were missed during review in a
new review to the original patch series allowing us to drop it.

It's encouraged to provide Acked-bys and Reviewed-bys even though the
patch has now been applied. If possible patch trailers will be updated.

Note that commit hashes shown below are subject to change due to rebase,
trailer updates or similar. If in doubt, please check the listed branch.

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git
branch: vfs.misc

[1/1] fs/pipe: Fix lockdep false-positive in watchqueue pipe_write()
      https://git.kernel.org/vfs/vfs/c/efb8f498327c

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] fs/pipe: Fix lockdep false-positive in watchqueue pipe_write()
  2023-11-24 15:08 [PATCH] fs/pipe: Fix lockdep false-positive in watchqueue pipe_write() Jann Horn
  2023-11-24 15:19 ` Christian Brauner
@ 2023-11-24 15:53 ` David Howells
  2023-11-24 16:02   ` Christian Brauner
  1 sibling, 1 reply; 4+ messages in thread
From: David Howells @ 2023-11-24 15:53 UTC (permalink / raw)
  To: Jann Horn
  Cc: dhowells, Alexander Viro, Christian Brauner, linux-fsdevel,
	linux-kernel, syzkaller-bugs

Jann Horn <jannh@google.com> wrote:

> +	/*
> +	 * Reject writing to watch queue pipes before the point where we lock
> +	 * the pipe.
> +	 * Otherwise, lockdep would be unhappy if the caller already has another
> +	 * pipe locked.
> +	 * If we had to support locking a normal pipe and a notification pipe at
> +	 * the same time, we could set up lockdep annotations for that, but
> +	 * since we don't actually need that, it's simpler to just bail here.
> +	 */
> +	if (pipe_has_watch_queue(pipe))
> +		return -EXDEV;
> +

Linus wanted it to be possible for the user to write to a notificaiton pipe.

David


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] fs/pipe: Fix lockdep false-positive in watchqueue pipe_write()
  2023-11-24 15:53 ` David Howells
@ 2023-11-24 16:02   ` Christian Brauner
  0 siblings, 0 replies; 4+ messages in thread
From: Christian Brauner @ 2023-11-24 16:02 UTC (permalink / raw)
  To: David Howells
  Cc: Jann Horn, Alexander Viro, linux-fsdevel, linux-kernel, syzkaller-bugs

On Fri, Nov 24, 2023 at 03:53:47PM +0000, David Howells wrote:
> Jann Horn <jannh@google.com> wrote:
> 
> > +	/*
> > +	 * Reject writing to watch queue pipes before the point where we lock
> > +	 * the pipe.
> > +	 * Otherwise, lockdep would be unhappy if the caller already has another
> > +	 * pipe locked.
> > +	 * If we had to support locking a normal pipe and a notification pipe at
> > +	 * the same time, we could set up lockdep annotations for that, but
> > +	 * since we don't actually need that, it's simpler to just bail here.
> > +	 */
> > +	if (pipe_has_watch_queue(pipe))
> > +		return -EXDEV;
> > +
> 
> Linus wanted it to be possible for the user to write to a notificaiton pipe.

Since it has been disabled from the start and nothing has ever actually
materialized we just don't need to care. If we start caring this needs
more work anyway iirc.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2023-11-24 16:02 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-24 15:08 [PATCH] fs/pipe: Fix lockdep false-positive in watchqueue pipe_write() Jann Horn
2023-11-24 15:19 ` Christian Brauner
2023-11-24 15:53 ` David Howells
2023-11-24 16:02   ` Christian Brauner

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.