summaryrefslogtreecommitdiffstats
path: root/src/test/test-seccomp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/test-seccomp.c')
-rw-r--r--src/test/test-seccomp.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/src/test/test-seccomp.c b/src/test/test-seccomp.c
index 4c704ba..874f08b 100644
--- a/src/test/test-seccomp.c
+++ b/src/test/test-seccomp.c
@@ -21,6 +21,7 @@
#include "macro.h"
#include "memory-util.h"
#include "missing_sched.h"
+#include "missing_syscall_def.h"
#include "nsflags.h"
#include "nulstr-util.h"
#include "process-util.h"
@@ -1003,6 +1004,23 @@ static int real_open(const char *path, int flags, mode_t mode) {
#endif
}
+static int try_fchmodat2(int dirfd, const char *path, int flags, mode_t mode) {
+ /* glibc does not provide a direct wrapper for fchmodat2(). Let's hence define our own wrapper for
+ * testing purposes that calls the real syscall, on architectures and in environments where
+ * SYS_fchmodat2 is defined. Otherwise, let's just fall back to the glibc fchmodat() call. */
+
+#if defined __NR_fchmodat2 && __NR_fchmodat2 >= 0
+ int r;
+ r = (int) syscall(__NR_fchmodat2, dirfd, path, flags, mode);
+ /* The syscall might still be unsupported by kernel or libseccomp. */
+ if (r < 0 && errno == ENOSYS)
+ return fchmodat(dirfd, path, flags, mode);
+ return r;
+#else
+ return fchmodat(dirfd, path, flags, mode);
+#endif
+}
+
TEST(restrict_suid_sgid) {
pid_t pid;
@@ -1044,6 +1062,11 @@ TEST(restrict_suid_sgid) {
assert_se(fchmodat(AT_FDCWD, path, 0755 | S_ISGID | S_ISUID, 0) >= 0);
assert_se(fchmodat(AT_FDCWD, path, 0755, 0) >= 0);
+ assert_se(try_fchmodat2(AT_FDCWD, path, 0755 | S_ISUID, 0) >= 0);
+ assert_se(try_fchmodat2(AT_FDCWD, path, 0755 | S_ISGID, 0) >= 0);
+ assert_se(try_fchmodat2(AT_FDCWD, path, 0755 | S_ISGID | S_ISUID, 0) >= 0);
+ assert_se(try_fchmodat2(AT_FDCWD, path, 0755, 0) >= 0);
+
k = real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID);
k = safe_close(k);
assert_se(unlink(z) >= 0);
@@ -1145,6 +1168,11 @@ TEST(restrict_suid_sgid) {
assert_se(fchmodat(AT_FDCWD, path, 0755 | S_ISGID | S_ISUID, 0) < 0 && errno == EPERM);
assert_se(fchmodat(AT_FDCWD, path, 0755, 0) >= 0);
+ assert_se(try_fchmodat2(AT_FDCWD, path, 0755 | S_ISUID, 0) < 0 && errno == EPERM);
+ assert_se(try_fchmodat2(AT_FDCWD, path, 0755 | S_ISGID, 0) < 0 && errno == EPERM);
+ assert_se(try_fchmodat2(AT_FDCWD, path, 0755 | S_ISGID | S_ISUID, 0) < 0 && errno == EPERM);
+ assert_se(try_fchmodat2(AT_FDCWD, path, 0755, 0) >= 0);
+
assert_se(real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID) < 0 && errno == EPERM);
assert_se(real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISGID) < 0 && errno == EPERM);
assert_se(real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID | S_ISGID) < 0 && errno == EPERM);