diff options
author | Paul Moore <paul@paul-moore.com> | 2019-05-02 19:29:59 -0400 |
---|---|---|
committer | Paul Moore <paul@paul-moore.com> | 2019-05-02 19:29:59 -0400 |
commit | dead12bc788b259b148cc4d93b970ef0bd602b1a (patch) | |
tree | 6fb37315e502e3c257ac6784afd802e0e2d1650d /src/api.c | |
parent | d390edad9a8540c2e2dd0b12732cc8dd3fe1cc69 (diff) | |
download | libseccomp-dead12bc788b259b148cc4d93b970ef0bd602b1a.tar.gz |
api: implement user notification in libseccomp
This patch is heavily based on an earlier patchset by Tycho
Andersen. I took Tycho's patch and incorporated the requested changes
from the review, fixed some corner case bugs, and simplified the API
a bit.
Kernel 5.0 includes the new user notification return code. Here's all the
infrastructure to handle that.
The idea behind the user notification return code is that the filter stops
the syscall, and forwards it to a "listener fd" that is created when
installing a filter. Then then some userspace task can listen and process
events accordingly by taking some (or no) action in userspace, and then
returning a value from the command.
Signed-off-by: Tycho Andersen <tycho@tycho.ws>
Signed-off-by: Paul Moore <paul@paul-moore.com>
Diffstat (limited to 'src/api.c')
-rw-r--r-- | src/api.c | 63 |
1 files changed, 63 insertions, 0 deletions
@@ -27,6 +27,7 @@ #include <stdlib.h> #include <string.h> #include <stdbool.h> +#include <sys/ioctl.h> #include <seccomp.h> @@ -34,6 +35,7 @@ #include "db.h" #include "gen_pfc.h" #include "gen_bpf.h" +#include "helper.h" #include "system.h" #define API __attribute__((visibility("default"))) @@ -112,6 +114,10 @@ static unsigned int _seccomp_api_update(void) sys_chk_seccomp_flag(SECCOMP_FILTER_FLAG_SPEC_ALLOW) == 1) level = 4; + if (level == 4 && + sys_chk_seccomp_flag(SECCOMP_FILTER_FLAG_NEW_LISTENER) == 1) + level = 5; + /* update the stored api level and return */ seccomp_api_level = level; return seccomp_api_level; @@ -163,6 +169,16 @@ API int seccomp_api_set(unsigned int level) sys_set_seccomp_action(SCMP_ACT_KILL_PROCESS, true); sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_SPEC_ALLOW, true); break; + case 5: + sys_set_seccomp_syscall(true); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC, true); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_LOG, true); + sys_set_seccomp_action(SCMP_ACT_LOG, true); + sys_set_seccomp_action(SCMP_ACT_KILL_PROCESS, true); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_SPEC_ALLOW, true); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_NEW_LISTENER, true); + sys_set_seccomp_action(SCMP_ACT_NOTIFY, true); + break; default: return -EINVAL; } @@ -511,6 +527,53 @@ API int seccomp_rule_add_exact(scmp_filter_ctx ctx, } /* NOTE - function header comment in include/seccomp.h */ +API int seccomp_notify_alloc(struct seccomp_notif **req, + struct seccomp_notif_resp **resp) +{ + return sys_notify_alloc(req, resp); +} + +/* NOTE - function header comment in include/seccomp.h */ +API void seccomp_notify_free(struct seccomp_notif *req, + struct seccomp_notif_resp *resp) +{ + if (req) + free(req); + if (resp) + free(resp); +} + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_notify_receive(int fd, struct seccomp_notif *req) +{ + return sys_notify_receive(fd, req); +} + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_notify_respond(int fd, struct seccomp_notif_resp *resp) +{ + return sys_notify_respond(fd, resp); +} + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_notify_id_valid(int fd, uint64_t id) +{ + return sys_notify_id_valid(fd, id); +} + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_notify_fd(const scmp_filter_ctx ctx) +{ + struct db_filter_col *col; + + if (_ctx_valid(ctx)) + return -EINVAL; + col = (struct db_filter_col *)ctx; + + return col->notify_fd; +} + +/* NOTE - function header comment in include/seccomp.h */ API int seccomp_export_pfc(const scmp_filter_ctx ctx, int fd) { if (_ctx_valid(ctx)) |