2022-07-23 14:12:23

by Greg Kroah-Hartman

[permalink] [raw]
Subject: Re: [PATCH] kernel/watch_queue: Make pipe NULL while clearing watch_queue

On Sat, Jul 23, 2022 at 07:24:47PM +0530, Siddh Raman Pant via Linux-kernel-mentees wrote:
> 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: [email protected]
>
> Signed-off-by: Siddh Raman Pant <[email protected]>
> ---
> kernel/watch_queue.c | 11 ++++++++++-
> 1 file changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/kernel/watch_queue.c b/kernel/watch_queue.c
> index bb9962b33f95..bab9e09c74cf 100644
> --- a/kernel/watch_queue.c
> +++ b/kernel/watch_queue.c
> @@ -637,8 +637,17 @@ 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. */
> +#ifdef CONFIG_WATCH_QUEUE

You should not use #ifdef in .c files, it's unmaintainable over time.

thanks,

greg k-h


2022-07-23 15:03:56

by Siddh Raman Pant

[permalink] [raw]
Subject: Re: [PATCH] kernel/watch_queue: Make pipe NULL while clearing watch_queue

On Sat, 23 Jul 2022 19:33:33 +0530 Greg KH <[email protected]> wrote:
> You should not use #ifdef in .c files, it's unmaintainable over time.
>
> thanks,
>
> greg k-h
>

I used it because it is used in the same way in fs/pipe.c too (please check the
stated line number).

That, in turn, is because `watch_queue` member in the `pipe_inode_info` struct
is defined that way (see line 80 of include/linux/pipe_fs_i.h), so I am forced
to use the ifdef guard.

Thanks,
Siddh

2022-07-24 03:48:07

by Khalid Masum

[permalink] [raw]
Subject: Re: [PATCH] kernel/watch_queue: Make pipe NULL while clearing watch_queue

On Sat, Jul 23, 2022 at 8:29 PM Siddh Raman Pant via
Linux-kernel-mentees <[email protected]>
wrote:
>
> On Sat, 23 Jul 2022 19:33:33 +0530 Greg KH <[email protected]> wrote:
> > You should not use #ifdef in .c files, it's unmaintainable over time.
> >
> > thanks,
> >
> > greg k-h
> >
>
> I used it because it is used in the same way in fs/pipe.c too (please check the
> stated line number).
>
> That, in turn, is because `watch_queue` member in the `pipe_inode_info` struct
> is defined that way (see line 80 of include/linux/pipe_fs_i.h), so I am forced
> to use the ifdef guard.
>
Maybe, we can use the IS_ENABLED macro here to avoid ifdef in the .c file as
suggested here:
https://www.kernel.org/doc/html/v4.10/process/coding-style.html#conditional-compilation

if(IS_ENABLED(CONFIG_WATCH_QUEUE)){
...
}

> Thanks,
> Siddh

Thanks,
-- Khalid Masum

2022-07-24 04:05:58

by Siddh Raman Pant

[permalink] [raw]
Subject: Re: [PATCH] kernel/watch_queue: Make pipe NULL while clearing watch_queue

On Sun, 24 Jul 2022 09:15:27 +0530 Khalid Masum <[email protected]> wrote:
> On Sat, Jul 23, 2022 at 8:29 PM Siddh Raman Pant via
> Linux-kernel-mentees <[email protected]>
> wrote:
> >
> > On Sat, 23 Jul 2022 19:33:33 +0530 Greg KH <[email protected]> wrote:
> > > You should not use #ifdef in .c files, it's unmaintainable over time.
> > >
> > > thanks,
> > >
> > > greg k-h
> > >
> >
> > I used it because it is used in the same way in fs/pipe.c too (please check the
> > stated line number).
> >
> > That, in turn, is because `watch_queue` member in the `pipe_inode_info` struct
> > is defined that way (see line 80 of include/linux/pipe_fs_i.h), so I am forced
> > to use the ifdef guard.
> >
> Maybe, we can use the IS_ENABLED macro here to avoid ifdef in the .c file as
> suggested here:
> https://www.kernel.org/doc/html/v4.10/process/coding-style.html#conditional-compilation
>
> if(IS_ENABLED(CONFIG_WATCH_QUEUE)){
> ...
> }
>
> > Thanks,
> > Siddh
>
> Thanks,
> -- Khalid Masum

I have looked at it again. The guard is superfluous in watch_queue.c (don't
need it since we are already in watch queue), hence I am sending v2 with it
removed.

Thanks,
Siddh