DF-2937 / sched_probe.c
/* * DF-2937 probe: map the unpriv attack surface of sys/kern/kern_p1003_1b.c * and demonstrate that ksched_setscheduler() returns success (0) for * invalid policies (POSIX requires EINVAL), while rejecting out-of-range * priorities only for SCHED_RR/FIFO. * * Build: cc -o sched_probe sched_probe.c * Run: ./sched_probe (as invoking user) */ #include <stdio.h> #include <errno.h> #include <unistd.h> #include <string.h> #include <sched.h> #include <time.h> static void r(const char *what, int rc) { if (rc == -1) printf("%-46s rc=-1 errno=%d (%s)\n", what, errno, strerror(errno)); else printf("%-46s rc=%d errno=0\n", what, rc); } int main(void) { struct sched_param sp; struct timespec ts; pid_t me = getpid(); printf("uid=%d euid=%d pid=%d " "SCHED_OTHER=%d SCHED_FIFO=%d SCHED_RR=%d\n", getuid(), geteuid(), me, SCHED_OTHER, SCHED_FIFO, SCHED_RR); memset(&sp, 0, sizeof(sp)); sp.sched_priority = 0; /* ---- self (pid 0 and own pid) ---- */ r("sched_setparam(0, {0})", sched_setparam(0, &sp)); errno = 0; r("sched_getparam(0, &sp)", sched_getparam(0, &sp)); errno = 0; r("sched_getscheduler(0)", sched_getscheduler(0)); errno = 0; r("sched_setscheduler(0, SCHED_RR, {0})", sched_setscheduler(0, SCHED_RR, &sp)); errno = 0; r("sched_rr_get_interval(0, &ts)", sched_rr_get_interval(0, &ts)); errno = 0; r("sched_setparam(self, {0})", sched_setparam(me, &sp)); errno = 0; r("sched_getscheduler(self)", sched_getscheduler(me)); /* ---- other proc (pid 1 = root proc) ---- */ errno = 0; r("sched_getscheduler(1)", sched_getscheduler(1)); errno = 0; r("sched_getparam(1, &sp)", sched_getparam(1, &sp)); /* ---- nonexistent / negative pids ---- */ errno = 0; r("sched_getscheduler(999999)", sched_getscheduler(999999)); errno = 0; r("sched_getscheduler(-1)", sched_getscheduler(-1)); errno = 0; r("sched_setparam(-1, {0})", sched_setparam(-1, &sp)); errno = 0; r("sched_getscheduler(-99999999)", sched_getscheduler(-99999999)); /* ---- policy-free ops ---- */ errno = 0; r("sched_yield()", sched_yield()); errno = 0; r("sched_get_priority_max(SCHED_FIFO)", sched_get_priority_max(SCHED_FIFO)); errno = 0; r("sched_get_priority_min(SCHED_FIFO)", sched_get_priority_min(SCHED_FIFO)); errno = 0; r("sched_get_priority_max(SCHED_OTHER)", sched_get_priority_max(SCHED_OTHER)); errno = 0; r("sched_get_priority_max(4711)", sched_get_priority_max(4711)); /* ---- invalid policies: POSIX requires EINVAL ---- */ sp.sched_priority = 0; errno = 0; r("sched_setscheduler(0, 0 /*Linux SCHED_OTHER*/, {0})", sched_setscheduler(0, 0, &sp)); errno = 0; r("sched_setscheduler(0, 4711, {0})", sched_setscheduler(0, 4711, &sp)); errno = 0; r("sched_setscheduler(0, -1, {0})", sched_setscheduler(0, -1, &sp)); errno = 0; r("sched_setscheduler(0, INT_MAX, {0})", sched_setscheduler(0, 2147483647, &sp)); return 0; } |