Re: [PATCH 1/2] seccomp: don't leak memory when filter install races

From: Christian Brauner
Date: Wed Sep 02 2020 - 05:10:42 EST


On Tue, Sep 01, 2020 at 07:40:16PM -0600, Tycho Andersen wrote:
> In seccomp_set_mode_filter() with TSYNC | NEW_LISTENER, we first initialize
> the listener fd, then check to see if we can actually use it later in
> seccomp_may_assign_mode(), which can fail if anyone else in our thread
> group has installed a filter and caused some divergence. If we can't, we
> partially clean up the newly allocated file: we put the fd, put the file,
> but don't actually clean up the *memory* that was allocated at
> filter->notif. Let's clean that up too.
>
> To accomplish this, let's hoist the actual "detach a notifier from a
> filter" code to its own helper out of seccomp_notify_release(), so that in
> case anyone adds stuff to init_listener(), they only have to add the
> cleanup code in one spot. This does a bit of extra locking and such on the
> failure path when the filter is not attached, but it's a slow failure path
> anyway.
>
> Fixes: 51891498f2da ("seccomp: allow TSYNC and USER_NOTIF together")
> Reported-by: syzbot+3ad9614a12f80994c32e@xxxxxxxxxxxxxxxxxxxxxxxxx
> Signed-off-by: Tycho Andersen <tycho@tycho.pizza>
> ---

This looks sane to me!
Acked-by: Christian Brauner <christian.brauner@xxxxxxxxxx>

One thing I noticed when checking the failure paths. In init_listener we
allocate the notifier by directly storing it into filter->notif and if
anon_inode_getfile() fails we simply kfree(filter->notif) but don't NULL
it and leave filter->notif pointing to freed memory.
Since we have a few places where we check filter->notif whether it is
initialized or not maybe we should NULL filter->notif if init_listener()
fails or alloc the notifier into a tmp variable and only assign it to
filter->notif after we can't fail anymore in init_listener().

Just a thought since the error path in seccomp_set_mode_filter() is a
little more complex. :)

Thanks!
Christian