diff options
author | Paul Moore <paul@paul-moore.com> | 2020-08-04 10:52:08 -0400 |
---|---|---|
committer | Paul Moore <paul@paul-moore.com> | 2020-08-18 11:49:22 -0400 |
commit | 02812f99e8d1df2e671dac675b4af663d0266303 (patch) | |
tree | d47cbf1edbb9f20b5b69f61c01ad09124af739d6 /src | |
parent | ce314fe4111887c593e3c6b17c60d93bc6ab66b9 (diff) | |
download | libseccomp-02812f99e8d1df2e671dac675b4af663d0266303.tar.gz |
system: change our notification fd handling
This commit changes how we handle the notification fd by only
requesting it via _NEW_LISTENER if the filter has a _NOTIFY action
in it. We also augment the seccomp_reset(NULL, ...) behavior so
that it closes the notification fd before resetting the global
state; applications that need to keep their notification fd open
across a call to seccomp_reset(NULL, ...) can simply dup() it.
Although one would have to wonder why the application would be
calling seccomp_reset(NULL, ...) in that case.
Acked-by: Tom Hromatka <tom.hromatka@oracle.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/system.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/src/system.c b/src/system.c index 3b43b2a..c646c65 100644 --- a/src/system.c +++ b/src/system.c @@ -84,7 +84,11 @@ static struct task_state state = { void sys_reset_state(void) { state.nr_seccomp = -1; + + if (state.notify_fd > 0) + close(state.notify_fd); state.notify_fd = -1; + state.sup_syscall = -1; state.sup_flag_tsync = -1; state.sup_flag_log = -1; @@ -353,6 +357,7 @@ int sys_filter_load(struct db_filter_col *col, bool rawrc) { int rc; bool tsync_notify; + bool listener_req; struct bpf_program *prgm = NULL; rc = gen_bpf_generate(col, &prgm); @@ -367,6 +372,8 @@ int sys_filter_load(struct db_filter_col *col, bool rawrc) } tsync_notify = state.sup_flag_tsync_esrch > 0 && state.notify_fd == -1; + listener_req = state.sup_user_notif > 0 && \ + col->notify_used && state.notify_fd == -1; /* load the filter into the kernel */ if (sys_chk_seccomp_syscall() == 1) { @@ -375,11 +382,16 @@ int sys_filter_load(struct db_filter_col *col, bool rawrc) if (col->attr.tsync_enable) flgs |= SECCOMP_FILTER_FLAG_TSYNC | \ SECCOMP_FILTER_FLAG_TSYNC_ESRCH; - if (state.sup_user_notif > 0) + if (listener_req) flgs |= SECCOMP_FILTER_FLAG_NEW_LISTENER; - } else if (col->attr.tsync_enable) + } else if (col->attr.tsync_enable) { + if (listener_req) { + /* NOTE: we _should_ catch this in db.c */ + rc = -EFAULT; + goto filter_load_out; + } flgs |= SECCOMP_FILTER_FLAG_TSYNC; - else if (state.sup_user_notif > 0 && state.notify_fd == -1) + } else if (listener_req) flgs |= SECCOMP_FILTER_FLAG_NEW_LISTENER; if (col->attr.log_enable) flgs |= SECCOMP_FILTER_FLAG_LOG; |