Message ID | 20220724040240.7842-1-code@siddh.me (mailing list archive) |
---|---|
State | Handled Elsewhere |
Headers | show |
Series | [v2] kernel/watch_queue: Make pipe NULL while clearing watch_queue | expand |
diff --git a/kernel/watch_queue.c b/kernel/watch_queue.c index bb9962b33f95..0357e5c6cf18 100644 --- a/kernel/watch_queue.c +++ b/kernel/watch_queue.c @@ -637,8 +637,15 @@ void watch_queue_clear(struct watch_queue *wqueue) spin_lock_bh(&wqueue->lock); } - spin_unlock_bh(&wqueue->lock); rcu_read_unlock(); + + /* Clearing the watch queue, so we should clean the associated pipe. */ + if (wqueue->pipe) { + wqueue->pipe->watch_queue = NULL; + wqueue->pipe = NULL; + } + + spin_unlock_bh(&wqueue->lock); } /**
If not done, a reference to a freed pipe remains in the watch_queue, as this function is called before freeing a pipe in free_pipe_info() (see line 834 of fs/pipe.c). This causes a UAF when post_one_notification tries to access the pipe on a key update, which is reported by syzbot. Bug report: https://syzkaller.appspot.com/bug?id=1870dd7791ba05f2ea7f47f7cbdde701173973fc Reported-and-tested-by: syzbot+c70d87ac1d001f29a058@syzkaller.appspotmail.com Signed-off-by: Siddh Raman Pant <code@siddh.me> --- Changes since v1: - Removed the superfluous ifdef guard. kernel/watch_queue.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)