return 0;
}
-int seccomp_restrict_realtime(void) {
+int seccomp_restrict_realtime_full(int error_code) {
static const int permitted_policies[] = {
SCHED_OTHER,
SCHED_BATCH,
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)
/* 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));
* 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));
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);
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);
}