mirror of
https://github.com/systemd/systemd.git
synced 2025-01-25 10:04:04 +03:00
test: add test case for restrict_suid_sgid()
This commit is contained in:
parent
3c27973b13
commit
167fc10cb3
@ -19,10 +19,12 @@
|
||||
#include "nulstr-util.h"
|
||||
#include "process-util.h"
|
||||
#include "raw-clone.h"
|
||||
#include "rm-rf.h"
|
||||
#include "seccomp-util.h"
|
||||
#include "set.h"
|
||||
#include "string-util.h"
|
||||
#include "tests.h"
|
||||
#include "tmpfile-util.h"
|
||||
#include "virt.h"
|
||||
|
||||
#if SCMP_SYS(socket) < 0 || defined(__i386__) || defined(__s390x__) || defined(__s390__)
|
||||
@ -759,6 +761,211 @@ static void test_lock_personality(void) {
|
||||
assert_se(wait_for_terminate_and_check("lockpersonalityseccomp", pid, WAIT_LOG) == EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
static int real_open(const char *path, int flags, mode_t mode) {
|
||||
/* glibc internally calls openat() when open() is requested. Let's hence define our own wrapper for
|
||||
* testing purposes that calls the real syscall. */
|
||||
|
||||
return (int) syscall(SYS_open, path, flags, mode);
|
||||
}
|
||||
|
||||
static void test_restrict_suid_sgid(void) {
|
||||
pid_t pid;
|
||||
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
if (!is_seccomp_available()) {
|
||||
log_notice("Seccomp not available, skipping %s", __func__);
|
||||
return;
|
||||
}
|
||||
if (geteuid() != 0) {
|
||||
log_notice("Not root, skipping %s", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
pid = fork();
|
||||
assert_se(pid >= 0);
|
||||
|
||||
if (pid == 0) {
|
||||
char path[] = "/tmp/suidsgidXXXXXX", dir[] = "/tmp/suidsgiddirXXXXXX";
|
||||
int fd = -1, k = -1;
|
||||
const char *z;
|
||||
|
||||
fd = mkostemp_safe(path);
|
||||
assert_se(fd >= 0);
|
||||
|
||||
assert_se(mkdtemp(dir));
|
||||
z = strjoina(dir, "/test");
|
||||
|
||||
assert_se(chmod(path, 0755 | S_ISUID) >= 0);
|
||||
assert_se(chmod(path, 0755 | S_ISGID) >= 0);
|
||||
assert_se(chmod(path, 0755 | S_ISGID | S_ISUID) >= 0);
|
||||
assert_se(chmod(path, 0755) >= 0);
|
||||
|
||||
assert_se(fchmod(fd, 0755 | S_ISUID) >= 0);
|
||||
assert_se(fchmod(fd, 0755 | S_ISGID) >= 0);
|
||||
assert_se(fchmod(fd, 0755 | S_ISGID | S_ISUID) >= 0);
|
||||
assert_se(fchmod(fd, 0755) >= 0);
|
||||
|
||||
assert_se(fchmodat(AT_FDCWD, path, 0755 | S_ISUID, 0) >= 0);
|
||||
assert_se(fchmodat(AT_FDCWD, path, 0755 | S_ISGID, 0) >= 0);
|
||||
assert_se(fchmodat(AT_FDCWD, path, 0755 | S_ISGID | S_ISUID, 0) >= 0);
|
||||
assert_se(fchmodat(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);
|
||||
|
||||
k = real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISGID);
|
||||
k = safe_close(k);
|
||||
assert_se(unlink(z) >= 0);
|
||||
|
||||
k = real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID | S_ISGID);
|
||||
k = safe_close(k);
|
||||
assert_se(unlink(z) >= 0);
|
||||
|
||||
k = real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644);
|
||||
k = safe_close(k);
|
||||
assert_se(unlink(z) >= 0);
|
||||
|
||||
k = creat(z, 0644 | S_ISUID);
|
||||
k = safe_close(k);
|
||||
assert_se(unlink(z) >= 0);
|
||||
|
||||
k = creat(z, 0644 | S_ISGID);
|
||||
k = safe_close(k);
|
||||
assert_se(unlink(z) >= 0);
|
||||
|
||||
k = creat(z, 0644 | S_ISUID | S_ISGID);
|
||||
k = safe_close(k);
|
||||
assert_se(unlink(z) >= 0);
|
||||
|
||||
k = creat(z, 0644);
|
||||
k = safe_close(k);
|
||||
assert_se(unlink(z) >= 0);
|
||||
|
||||
k = openat(AT_FDCWD, z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID);
|
||||
k = safe_close(k);
|
||||
assert_se(unlink(z) >= 0);
|
||||
|
||||
k = openat(AT_FDCWD, z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISGID);
|
||||
k = safe_close(k);
|
||||
assert_se(unlink(z) >= 0);
|
||||
|
||||
k = openat(AT_FDCWD, z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID | S_ISGID);
|
||||
k = safe_close(k);
|
||||
assert_se(unlink(z) >= 0);
|
||||
|
||||
k = openat(AT_FDCWD, z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644);
|
||||
k = safe_close(k);
|
||||
assert_se(unlink(z) >= 0);
|
||||
|
||||
assert_se(mkdir(z, 0755 | S_ISUID) >= 0);
|
||||
assert_se(rmdir(z) >= 0);
|
||||
assert_se(mkdir(z, 0755 | S_ISGID) >= 0);
|
||||
assert_se(rmdir(z) >= 0);
|
||||
assert_se(mkdir(z, 0755 | S_ISUID | S_ISGID) >= 0);
|
||||
assert_se(rmdir(z) >= 0);
|
||||
assert_se(mkdir(z, 0755) >= 0);
|
||||
assert_se(rmdir(z) >= 0);
|
||||
|
||||
assert_se(mkdirat(AT_FDCWD, z, 0755 | S_ISUID) >= 0);
|
||||
assert_se(rmdir(z) >= 0);
|
||||
assert_se(mkdirat(AT_FDCWD, z, 0755 | S_ISGID) >= 0);
|
||||
assert_se(rmdir(z) >= 0);
|
||||
assert_se(mkdirat(AT_FDCWD, z, 0755 | S_ISUID | S_ISGID) >= 0);
|
||||
assert_se(rmdir(z) >= 0);
|
||||
assert_se(mkdirat(AT_FDCWD, z, 0755) >= 0);
|
||||
assert_se(rmdir(z) >= 0);
|
||||
|
||||
assert_se(mknod(z, S_IFREG | 0755 | S_ISUID, 0) >= 0);
|
||||
assert_se(unlink(z) >= 0);
|
||||
assert_se(mknod(z, S_IFREG | 0755 | S_ISGID, 0) >= 0);
|
||||
assert_se(unlink(z) >= 0);
|
||||
assert_se(mknod(z, S_IFREG | 0755 | S_ISUID | S_ISGID, 0) >= 0);
|
||||
assert_se(unlink(z) >= 0);
|
||||
assert_se(mknod(z, S_IFREG | 0755, 0) >= 0);
|
||||
assert_se(unlink(z) >= 0);
|
||||
|
||||
assert_se(mknodat(AT_FDCWD, z, S_IFREG | 0755 | S_ISUID, 0) >= 0);
|
||||
assert_se(unlink(z) >= 0);
|
||||
assert_se(mknodat(AT_FDCWD, z, S_IFREG | 0755 | S_ISGID, 0) >= 0);
|
||||
assert_se(unlink(z) >= 0);
|
||||
assert_se(mknodat(AT_FDCWD, z, S_IFREG | 0755 | S_ISUID | S_ISGID, 0) >= 0);
|
||||
assert_se(unlink(z) >= 0);
|
||||
assert_se(mknodat(AT_FDCWD, z, S_IFREG | 0755, 0) >= 0);
|
||||
assert_se(unlink(z) >= 0);
|
||||
|
||||
assert_se(seccomp_restrict_suid_sgid() >= 0);
|
||||
|
||||
assert_se(chmod(path, 0775 | S_ISUID) < 0 && errno == EPERM);
|
||||
assert_se(chmod(path, 0775 | S_ISGID) < 0 && errno == EPERM);
|
||||
assert_se(chmod(path, 0775 | S_ISGID | S_ISUID) < 0 && errno == EPERM);
|
||||
assert_se(chmod(path, 0775) >= 0);
|
||||
|
||||
assert_se(fchmod(fd, 0775 | S_ISUID) < 0 && errno == EPERM);
|
||||
assert_se(fchmod(fd, 0775 | S_ISGID) < 0 && errno == EPERM);
|
||||
assert_se(fchmod(fd, 0775 | S_ISGID | S_ISUID) < 0 && errno == EPERM);
|
||||
assert_se(fchmod(fd, 0775) >= 0);
|
||||
|
||||
assert_se(fchmodat(AT_FDCWD, path, 0755 | S_ISUID, 0) < 0 && errno == EPERM);
|
||||
assert_se(fchmodat(AT_FDCWD, path, 0755 | S_ISGID, 0) < 0 && errno == EPERM);
|
||||
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(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);
|
||||
k = real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644);
|
||||
k = safe_close(k);
|
||||
assert_se(unlink(z) >= 0);
|
||||
|
||||
assert_se(creat(z, 0644 | S_ISUID) < 0 && errno == EPERM);
|
||||
assert_se(creat(z, 0644 | S_ISGID) < 0 && errno == EPERM);
|
||||
assert_se(creat(z, 0644 | S_ISUID | S_ISGID) < 0 && errno == EPERM);
|
||||
k = creat(z, 0644);
|
||||
k = safe_close(k);
|
||||
assert_se(unlink(z) >= 0);
|
||||
|
||||
assert_se(openat(AT_FDCWD, z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID) < 0 && errno == EPERM);
|
||||
assert_se(openat(AT_FDCWD, z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISGID) < 0 && errno == EPERM);
|
||||
assert_se(openat(AT_FDCWD, z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID | S_ISGID) < 0 && errno == EPERM);
|
||||
k = openat(AT_FDCWD, z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644);
|
||||
k = safe_close(k);
|
||||
assert_se(unlink(z) >= 0);
|
||||
|
||||
assert_se(mkdir(z, 0755 | S_ISUID) < 0 && errno == EPERM);
|
||||
assert_se(mkdir(z, 0755 | S_ISGID) < 0 && errno == EPERM);
|
||||
assert_se(mkdir(z, 0755 | S_ISUID | S_ISGID) < 0 && errno == EPERM);
|
||||
assert_se(mkdir(z, 0755) >= 0);
|
||||
assert_se(rmdir(z) >= 0);
|
||||
|
||||
assert_se(mkdirat(AT_FDCWD, z, 0755 | S_ISUID) < 0 && errno == EPERM);
|
||||
assert_se(mkdirat(AT_FDCWD, z, 0755 | S_ISGID) < 0 && errno == EPERM);
|
||||
assert_se(mkdirat(AT_FDCWD, z, 0755 | S_ISUID | S_ISGID) < 0 && errno == EPERM);
|
||||
assert_se(mkdirat(AT_FDCWD, z, 0755) >= 0);
|
||||
assert_se(rmdir(z) >= 0);
|
||||
|
||||
assert_se(mknod(z, S_IFREG | 0755 | S_ISUID, 0) < 0 && errno == EPERM);
|
||||
assert_se(mknod(z, S_IFREG | 0755 | S_ISGID, 0) < 0 && errno == EPERM);
|
||||
assert_se(mknod(z, S_IFREG | 0755 | S_ISUID | S_ISGID, 0) < 0 && errno == EPERM);
|
||||
assert_se(mknod(z, S_IFREG | 0755, 0) >= 0);
|
||||
assert_se(unlink(z) >= 0);
|
||||
|
||||
assert_se(mknodat(AT_FDCWD, z, S_IFREG | 0755 | S_ISUID, 0) < 0 && errno == EPERM);
|
||||
assert_se(mknodat(AT_FDCWD, z, S_IFREG | 0755 | S_ISGID, 0) < 0 && errno == EPERM);
|
||||
assert_se(mknodat(AT_FDCWD, z, S_IFREG | 0755 | S_ISUID | S_ISGID, 0) < 0 && errno == EPERM);
|
||||
assert_se(mknodat(AT_FDCWD, z, S_IFREG | 0755, 0) >= 0);
|
||||
assert_se(unlink(z) >= 0);
|
||||
|
||||
assert_se(unlink(path) >= 0);
|
||||
assert_se(rm_rf(dir, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
|
||||
|
||||
_exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
assert_se(wait_for_terminate_and_check("suidsgidseccomp", pid, WAIT_LOG) == EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
test_setup_logging(LOG_DEBUG);
|
||||
|
||||
@ -776,6 +983,7 @@ int main(int argc, char *argv[]) {
|
||||
test_restrict_archs();
|
||||
test_load_syscall_filter_set_raw();
|
||||
test_lock_personality();
|
||||
test_restrict_suid_sgid();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user