summaryrefslogtreecommitdiff
path: root/src/api.c
diff options
context:
space:
mode:
authorPaul Moore <paul@paul-moore.com>2019-05-02 19:29:59 -0400
committerPaul Moore <paul@paul-moore.com>2019-05-02 19:29:59 -0400
commitdead12bc788b259b148cc4d93b970ef0bd602b1a (patch)
tree6fb37315e502e3c257ac6784afd802e0e2d1650d /src/api.c
parentd390edad9a8540c2e2dd0b12732cc8dd3fe1cc69 (diff)
downloadlibseccomp-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.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/api.c b/src/api.c
index 34fd9c7..e2b6c00 100644
--- a/src/api.c
+++ b/src/api.c
@@ -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))