summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorPaul Moore <paul@paul-moore.com>2020-07-26 11:01:49 -0400
committerPaul Moore <paul@paul-moore.com>2020-08-18 11:44:44 -0400
commitce314fe4111887c593e3c6b17c60d93bc6ab66b9 (patch)
tree41c2c6b5bf4e9c1ead1e3f8122e5ff5ff6b5f465 /tests
parentbee43d3e884788569860a384e6a38357785a3995 (diff)
downloadlibseccomp-ce314fe4111887c593e3c6b17c60d93bc6ab66b9.tar.gz
all: only request the userspace notification fd once
It turns out that requesting the seccomp userspace notifcation fd more than once is a bad thing which causes the kernel to complain (rightfully so for a variety of reasons). Unfortunately as we were always requesting the notification fd whenever possible this results in problems at filter load time. Our solution is to move the notification fd out of the filter context and into the global task context, using a newly created task_state structure. This allows us to store, and retrieve the notification outside the scope of an individual filter context. It also provides some implementation improvements by giving us a convenient place to stash all of the API level related support variables. We also extend the seccomp_reset() API call to reset this internal global state when passed a NULL filter context. There is one potential case which we don't currently handle well: threads. At the moment libseccomp is thread ignorant, and that works well as the only global state up to this point was the currently supported API level information which was common to all threads in a process. Unfortunately, it appears that the notification fd need not be common to all threads in a process, yet this patch treats it as if it is common. I suspect this is a very unusual use case so I decided to keep this patch simple and ignore this case, but in the future if we need to support this properly we should be able to do so without API changes by keeping an internal list of notification fds indexed by gettid(2). This fixes the GitHub issue below: * https://github.com/seccomp/libseccomp/issues/273 Reported-by: Tobias Stoeckmann <tobias@stoeckmann.org> Acked-by: Tom Hromatka <tom.hromatka@oracle.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/11-basic-basic_errors.c9
-rw-r--r--tests/51-live-user_notification.c21
-rwxr-xr-xtests/51-live-user_notification.py4
3 files changed, 28 insertions, 6 deletions
diff --git a/tests/11-basic-basic_errors.c b/tests/11-basic-basic_errors.c
index d3b2256..da059df 100644
--- a/tests/11-basic-basic_errors.c
+++ b/tests/11-basic-basic_errors.c
@@ -41,12 +41,9 @@ int main(int argc, char *argv[])
seccomp_release(ctx);
ctx = NULL;
- /* seccomp_reset error */
- rc = seccomp_reset(ctx, SCMP_ACT_KILL + 1);
- if (rc != -EINVAL)
- return -1;
- rc = seccomp_reset(ctx, SCMP_ACT_KILL);
- if (rc != -EINVAL)
+ /* ensure that seccomp_reset(NULL, ...) is accepted */
+ rc = seccomp_reset(NULL, SCMP_ACT_ALLOW);
+ if (rc != 0)
return -1;
/* seccomp_load error */
diff --git a/tests/51-live-user_notification.c b/tests/51-live-user_notification.c
index 4340194..4847d8b 100644
--- a/tests/51-live-user_notification.c
+++ b/tests/51-live-user_notification.c
@@ -99,6 +99,27 @@ int main(int argc, char *argv[])
goto out;
}
+ rc = seccomp_reset(ctx, SCMP_ACT_ALLOW);
+ if (rc < 0)
+ goto out;
+
+ rc = seccomp_rule_add(ctx, SCMP_ACT_NOTIFY, SCMP_SYS(getppid), 0, NULL);
+ if (rc)
+ goto out;
+
+ rc = seccomp_load(ctx);
+ if (rc < 0)
+ goto out;
+
+ rc = seccomp_notify_fd(ctx);
+ if (rc < 0)
+ goto out;
+ if (rc != fd) {
+ rc = -EFAULT;
+ goto out;
+ } else
+ rc = 0;
+
out:
if (fd >= 0)
close(fd);
diff --git a/tests/51-live-user_notification.py b/tests/51-live-user_notification.py
index 0d81f5e..3449c44 100755
--- a/tests/51-live-user_notification.py
+++ b/tests/51-live-user_notification.py
@@ -52,6 +52,10 @@ def test():
raise RuntimeError("Child process error")
if os.WEXITSTATUS(rc) != 0:
raise RuntimeError("Child process error")
+ f.reset(ALLOW)
+ f.add_rule(NOTIFY, "getppid")
+ f.load()
+ # no easy way to check the notification fd here
quit(160)
test()