[lkml]   [2020]   [Sep]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
Patch in this message
Subject[PATCH 5.8 049/177] seccomp: dont leak memory when filter install races
From: Tycho Andersen <>

[ Upstream commit a566a9012acd7c9a4be7e30dc7acb7a811ec2260 ]

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

Fixes: 51891498f2da ("seccomp: allow TSYNC and USER_NOTIF together")
Signed-off-by: Tycho Andersen <>
Acked-by: Christian Brauner <>
Signed-off-by: Kees Cook <>
Signed-off-by: Sasha Levin <>
kernel/seccomp.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index c461ba9925136..54cf84bac3c9b 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -997,13 +997,12 @@ out:

-static int seccomp_notify_release(struct inode *inode, struct file *file)
+static void seccomp_notify_detach(struct seccomp_filter *filter)
- struct seccomp_filter *filter = file->private_data;
struct seccomp_knotif *knotif;

if (!filter)
- return 0;
+ return;


@@ -1025,6 +1024,13 @@ static int seccomp_notify_release(struct inode *inode, struct file *file)
filter->notif = NULL;
+static int seccomp_notify_release(struct inode *inode, struct file *file)
+ struct seccomp_filter *filter = file->private_data;
+ seccomp_notify_detach(filter);
return 0;
@@ -1358,6 +1364,7 @@ out_put_fd:
listener_f->private_data = NULL;
+ seccomp_notify_detach(prepared);
} else {
fd_install(listener, listener_f);
ret = listener;

 \ /
  Last update: 2020-09-16 01:38    [W:0.694 / U:0.108 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site