diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-09-12 05:13:30 +0900 |
---|---|---|
committer | Luca Boccassi <luca.boccassi@gmail.com> | 2022-09-15 13:47:17 +0100 |
commit | a900274915dfeffe22f23fb6f5bb880844088e6c (patch) | |
tree | c415a9bab8bd04621225567699750b47ae0c946b | |
parent | 132c73b57ad1d363e97e1f4720f0e920826f34e1 (diff) | |
download | systemd-a900274915dfeffe22f23fb6f5bb880844088e6c.tar.gz |
test-seccomp: support systems that sched_setscheduler() is already limited
Fixes #17078.
-rw-r--r-- | src/shared/seccomp-util.c | 8 | ||||
-rw-r--r-- | src/shared/seccomp-util.h | 5 | ||||
-rw-r--r-- | src/test/test-seccomp.c | 20 |
3 files changed, 24 insertions, 9 deletions
diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c index 882547d655..cd0915e2b2 100644 --- a/src/shared/seccomp-util.c +++ b/src/shared/seccomp-util.c @@ -1602,7 +1602,7 @@ int seccomp_restrict_address_families(Set *address_families, bool allow_list) { return 0; } -int seccomp_restrict_realtime(void) { +int seccomp_restrict_realtime_full(int error_code) { static const int permitted_policies[] = { SCHED_OTHER, SCHED_BATCH, @@ -1613,6 +1613,8 @@ int seccomp_restrict_realtime(void) { uint32_t arch; unsigned i; + assert(error_code > 0); + /* Determine the highest policy constant we want to allow */ for (i = 0; i < ELEMENTSOF(permitted_policies); i++) if (permitted_policies[i] > max_policy) @@ -1646,7 +1648,7 @@ int seccomp_restrict_realtime(void) { /* Deny this policy */ r = seccomp_rule_add_exact( seccomp, - SCMP_ACT_ERRNO(EPERM), + SCMP_ACT_ERRNO(error_code), SCMP_SYS(sched_setscheduler), 1, SCMP_A1(SCMP_CMP_EQ, p)); @@ -1660,7 +1662,7 @@ int seccomp_restrict_realtime(void) { * are unsigned here, hence no need no check for < 0 values. */ r = seccomp_rule_add_exact( seccomp, - SCMP_ACT_ERRNO(EPERM), + SCMP_ACT_ERRNO(error_code), SCMP_SYS(sched_setscheduler), 1, SCMP_A1(SCMP_CMP_GT, max_policy)); diff --git a/src/shared/seccomp-util.h b/src/shared/seccomp-util.h index aa249539f3..3f1a993e11 100644 --- a/src/shared/seccomp-util.h +++ b/src/shared/seccomp-util.h @@ -96,7 +96,10 @@ int seccomp_restrict_namespaces(unsigned long retain); int seccomp_protect_sysctl(void); int seccomp_protect_syslog(void); int seccomp_restrict_address_families(Set *address_families, bool allow_list); -int seccomp_restrict_realtime(void); +int seccomp_restrict_realtime_full(int error_code); /* This is mostly for testing code. */ +static inline int seccomp_restrict_realtime(void) { + return seccomp_restrict_realtime_full(EPERM); +} int seccomp_memory_deny_write_execute(void); int seccomp_lock_personality(unsigned long personality); int seccomp_protect_hostname(void); diff --git a/src/test/test-seccomp.c b/src/test/test-seccomp.c index 3aaeb7147e..4c704badbd 100644 --- a/src/test/test-seccomp.c +++ b/src/test/test-seccomp.c @@ -559,22 +559,32 @@ TEST(restrict_realtime) { assert_se(pid >= 0); if (pid == 0) { - assert_se(sched_setscheduler(0, SCHED_FIFO, &(struct sched_param) { .sched_priority = 1 }) >= 0); - assert_se(sched_setscheduler(0, SCHED_RR, &(struct sched_param) { .sched_priority = 1 }) >= 0); + /* On some CI environments, the restriction may be already enabled. */ + if (sched_setscheduler(0, SCHED_FIFO, &(struct sched_param) { .sched_priority = 1 }) < 0) { + log_full_errno(errno == EPERM ? LOG_DEBUG : LOG_WARNING, errno, + "Failed to set scheduler parameter for FIFO: %m"); + assert(errno == EPERM); + } + if (sched_setscheduler(0, SCHED_RR, &(struct sched_param) { .sched_priority = 1 }) < 0) { + log_full_errno(errno == EPERM ? LOG_DEBUG : LOG_WARNING, errno, + "Failed to set scheduler parameter for RR: %m"); + assert(errno == EPERM); + } + assert_se(sched_setscheduler(0, SCHED_IDLE, &(struct sched_param) { .sched_priority = 0 }) >= 0); assert_se(sched_setscheduler(0, SCHED_BATCH, &(struct sched_param) { .sched_priority = 0 }) >= 0); assert_se(sched_setscheduler(0, SCHED_OTHER, &(struct sched_param) {}) >= 0); - assert_se(seccomp_restrict_realtime() >= 0); + assert_se(seccomp_restrict_realtime_full(ENOANO) >= 0); assert_se(sched_setscheduler(0, SCHED_IDLE, &(struct sched_param) { .sched_priority = 0 }) >= 0); assert_se(sched_setscheduler(0, SCHED_BATCH, &(struct sched_param) { .sched_priority = 0 }) >= 0); assert_se(sched_setscheduler(0, SCHED_OTHER, &(struct sched_param) {}) >= 0); assert_se(sched_setscheduler(0, SCHED_FIFO, &(struct sched_param) { .sched_priority = 1 }) < 0); - assert_se(errno == EPERM); + assert_se(errno == ENOANO); assert_se(sched_setscheduler(0, SCHED_RR, &(struct sched_param) { .sched_priority = 1 }) < 0); - assert_se(errno == EPERM); + assert_se(errno == ENOANO); _exit(EXIT_SUCCESS); } |