diff options
Diffstat (limited to 'tools/regression/priv/priv_sched_rtprio.c')
-rw-r--r-- | tools/regression/priv/priv_sched_rtprio.c | 353 |
1 files changed, 224 insertions, 129 deletions
diff --git a/tools/regression/priv/priv_sched_rtprio.c b/tools/regression/priv/priv_sched_rtprio.c index 72d1756..2498f3f 100644 --- a/tools/regression/priv/priv_sched_rtprio.c +++ b/tools/regression/priv/priv_sched_rtprio.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 2006 nCircle Network Security, Inc. + * Copyright (c) 2007 Robert N. M. Watson * All rights reserved. * * This software was developed by Robert N. M. Watson for the TrustedBSD @@ -54,181 +55,275 @@ #include "main.h" -static void -dummy(void) -{ - - while (1) - sleep(1); -} +static int childproc_running; +static pid_t childproc; -static void -collect(pid_t test_pid, pid_t dummy_pid) +int +priv_sched_rtprio_setup(int asroot, int injail, struct test *test) { - pid_t pid; + int another_uid, need_child; /* - * First, collect the main test process. When it has exited, then - * kill off the dummy process. + * Some tests require a second process with specific credentials. + * Set that up here, and kill in cleanup. */ - if (test_pid > 0) { - while (1) { - pid = waitpid(test_pid, NULL, 0); - if (pid == -1) - warn("waitpid(%d (test), NULL, 0)", test_pid); - if (pid == test_pid) - break; - } + need_child = 0; + if (test->t_test_func == priv_sched_rtprio_aproc_normal || + test->t_test_func == priv_sched_rtprio_aproc_idle || + test->t_test_func == priv_sched_rtprio_aproc_realtime) { + need_child = 1; + another_uid = 1; + } + if (test->t_test_func == priv_sched_rtprio_myproc_normal || + test->t_test_func == priv_sched_rtprio_myproc_idle || + test->t_test_func == priv_sched_rtprio_myproc_realtime) { + need_child = 1; } - if (kill(dummy_pid, SIGKILL) < 0) - err(-1, "kill(%d, SIGKILL)", dummy_pid); - - while (1) { - pid = waitpid(dummy_pid, NULL, 0); - if (pid == -1) - warn("waitpid(%d, NULL, 0)", dummy_pid); - if (pid == dummy_pid) - return; + if (need_child) { + childproc = fork(); + if (childproc < 0) { + warn("priv_sched_setup: fork"); + return (-1); + } + if (childproc == 0) { + if (another_uid) { + if (setresuid(UID_THIRD, UID_THIRD, + UID_THIRD) < 0) + err(-1, "setresuid(%d)", UID_THIRD); + } + while (1) + sleep(1); + } + childproc_running = 1; + sleep(1); /* Allow dummy thread to change uids. */ } + return (0); } -static void -test(pid_t dummy_pid) +void +priv_sched_rtprio_curproc_normal(int asroot, int injail, struct test *test) { struct rtprio rtp; int error; - /* - * Tests first as root. Test that we can set normal, realtime, and - * idle priorities on the current thread and on the dummy thread. - */ - rtp.type = RTP_PRIO_REALTIME; + rtp.type = RTP_PRIO_NORMAL; rtp.prio = 0; - if (rtprio(RTP_SET, 0, &rtp) < 0) - err(-1, "rtprio(RTP_SET, 0, {REALTIME, 0}) as root"); + error = rtprio(RTP_SET, 0, &rtp); + if (asroot && injail) + expect("priv_sched_rtprio_curproc_normal(asroot, injail)", + error, 0, 0); + if (asroot && !injail) + expect("priv_sched_rtprio_curproc_normal(asroot, !injail)", + error, 0, 0); + if (!asroot && injail) + expect("priv_sched_rtprio_curproc_normal(!asroot, injail)", + error, 0, 0); + if (!asroot && !injail) + expect("priv_sched_rtprio_curproc_normal(!asroot, !injail)", + error, 0, 0); +} + +void +priv_sched_rtprio_curproc_idle(int asroot, int injail, struct test *test) +{ + struct rtprio rtp; + int error; rtp.type = RTP_PRIO_IDLE; rtp.prio = 0; - if (rtprio(RTP_SET, 0, &rtp) < 0) - err(-1, "rtprio(RTP_SET, 0, {IDLE, 0}) as root"); + error = rtprio(RTP_SET, 0, &rtp); + if (asroot && injail) + expect("priv_sched_rtprio_curproc_idle(asroot, injail)", + error, -1, EPERM); + if (asroot && !injail) + expect("priv_sched_rtprio_curproc_idle(asroot, !injail)", + error, 0, 0); + if (!asroot && injail) + expect("priv_sched_rtprio_curproc_idle(!asroot, injail)", + error, -1, EPERM); + if (!asroot && !injail) + expect("priv_sched_rtprio_curproc_idle(!asroot, !injail)", + error, -1, EPERM); +} - rtp.type = RTP_PRIO_NORMAL; - rtp.prio = 0; - if (rtprio(RTP_SET, 0, &rtp) < 0) - err(-1, "rtprio(RTP_SET, 0, {NORMAL, 0) as root"); +void +priv_sched_rtprio_curproc_realtime(int asroot, int injail, struct test *test) +{ + struct rtprio rtp; + int error; rtp.type = RTP_PRIO_REALTIME; rtp.prio = 0; - if (rtprio(RTP_SET, dummy_pid, &rtp) < 0) - err(-1, "rtprio(RTP_SET, %d, {REALTIME, 0}) as root", - dummy_pid); + error = rtprio(RTP_SET, 0, &rtp); + if (asroot && injail) + expect("priv_sched_rtprio_curproc_realtime(asroot, injail)", + error, -1, EPERM); + if (asroot && !injail) + expect("priv_sched_rtprio_curproc_realtime(asroot, !injail)", + error, 0, 0); + if (!asroot && injail) + expect("priv_sched_rtprio_curproc_realtime(!asroot, injail)", + error, -1, EPERM); + if (!asroot && !injail) + expect("priv_sched_rtprio_curproc_realtime(!asroot, !injail)", + error, -1, EPERM); +} - rtp.type = RTP_PRIO_IDLE; - rtp.prio = 0; - if (rtprio(RTP_SET, dummy_pid, &rtp) < 0) - err(-1, "rtprio(RTP_SET, %d, {IDLE, 0}) as root", dummy_pid); +void +priv_sched_rtprio_myproc_normal(int asroot, int injail, struct test *test) +{ + struct rtprio rtp; + int error; rtp.type = RTP_PRIO_NORMAL; rtp.prio = 0; - if (rtprio(RTP_SET, dummy_pid, &rtp) < 0) - err(-1, "rtprio(RTP_SET, %d, {NORMAL, 0) as root", - dummy_pid); + error = rtprio(RTP_SET, 0, &rtp); + if (asroot && injail) + expect("priv_sched_rtprio_myproc_normal(asroot, injail)", + error, 0, 0); + if (asroot && !injail) + expect("priv_sched_rtprio_myproc_normal(asroot, !injail)", + error, 0, 0); + if (!asroot && injail) + expect("priv_sched_rtprio_myproc_normal(!asroot, injail)", + error, 0, 0); + if (!asroot && !injail) + expect("priv_sched_rtprio_myproc_normal(!asroot, !injail)", + error, 0, 0); +} - /* - * Then test again as a different credential. - */ - if (setresuid(UID_OTHER, UID_OTHER, UID_OTHER) < 0) - err(-1, "setresuid(%d)", UID_OTHER); +void +priv_sched_rtprio_myproc_idle(int asroot, int injail, struct test *test) +{ + struct rtprio rtp; + int error; - rtp.type = RTP_PRIO_REALTIME; + rtp.type = RTP_PRIO_IDLE; rtp.prio = 0; error = rtprio(RTP_SET, 0, &rtp); - if (error == 0) - errx(-1, - "rtprio(RTP_SET, 0, {REALTIME, 0}) succeeded as !root"); - if (errno != EPERM) - err(-1, "rtprio(RTP_SET, 0, {REALTIME, 0}) wrong errno %d as" - " !root", errno); + if (asroot && injail) + expect("priv_sched_rtprio_myproc_idle(asroot, injail)", + error, -1, EPERM); + if (asroot && !injail) + expect("priv_sched_rtprio_myproc_idle(asroot, !injail)", + error, 0, 0); + if (!asroot && injail) + expect("priv_sched_rtprio_myproc_idle(!asroot, injail)", + error, -1, EPERM); + if (!asroot && !injail) + expect("priv_sched_rtprio_myproc_idle(!asroot, !injail)", + error, -1, EPERM); +} - rtp.type = RTP_PRIO_IDLE; +void +priv_sched_rtprio_myproc_realtime(int asroot, int injail, struct test *test) +{ + struct rtprio rtp; + int error; + + rtp.type = RTP_PRIO_REALTIME; rtp.prio = 0; error = rtprio(RTP_SET, 0, &rtp); - if (error == 0) - errx(-1, "rtprio(RTP_SET, 0, {IDLE, 0}) succeeded as !root"); - if (errno != EPERM) - err(-1, "rtprio(RTP_SET, 0, {IDLE, 0}) wrong errno %d as " - "!root", errno); + if (asroot && injail) + expect("priv_sched_rtprio_myproc_realtime(asroot, injail)", + error, -1, EPERM); + if (asroot && !injail) + expect("priv_sched_rtprio_myproc_realtime(asroot, !injail)", + error, 0, 0); + if (!asroot && injail) + expect("priv_sched_rtprio_myproc_realtime(!asroot, injail)", + error, -1, EPERM); + if (!asroot && !injail) + expect("priv_sched_rtprio_myproc_realtime(!asroot, !injail)", + error, -1, EPERM); +} + +void +priv_sched_rtprio_aproc_normal(int asroot, int injail, struct test *test) +{ + struct rtprio rtp; + int error; rtp.type = RTP_PRIO_NORMAL; rtp.prio = 0; - if (rtprio(RTP_SET, 0, &rtp) < 0) - err(-1, "rtprio(RTP_SET, 0, {NORMAL, 0}) as !root"); + error = rtprio(RTP_SET, childproc, &rtp); + if (asroot && injail) + expect("priv_sched_rtprio_aproc_normal(asroot, injail)", + error, -1, ESRCH); + if (asroot && !injail) + expect("priv_sched_rtprio_aproc_normal(asroot, !injail)", + error, 0, 0); + if (!asroot && injail) + expect("priv_sched_rtprio_aproc_normal(!asroot, injail)", + error, -1, ESRCH); + if (!asroot && !injail) + expect("priv_sched_rtprio_aproc_normal(!asroot, !injail)", + error, -1, EPERM); +} - rtp.type = RTP_PRIO_REALTIME; - rtp.prio = 0; - error = rtprio(RTP_SET, dummy_pid, &rtp); - if (error == 0) - errx(-1, - "rtprio(RTP_SET, %d, {REALTIME, 0}) succeeded as !root", - dummy_pid); - if (errno != EPERM) - err(-1, "rtprio(RTP_SET, %d, {REALTIME, 0}) wrong errno %d as" - " !root", dummy_pid, errno); +void +priv_sched_rtprio_aproc_idle(int asroot, int injail, struct test *test) +{ + struct rtprio rtp; + int error; rtp.type = RTP_PRIO_IDLE; rtp.prio = 0; - error = rtprio(RTP_SET, dummy_pid, &rtp); - if (error == 0) - errx(-1, "rtprio(RTP_SET, %d, {IDLE, 0}) succeeded as !root", - dummy_pid); - if (errno != EPERM) - err(-1, - "rtprio(RTP_SET, %d, {IDLE, 0}) wrong errno %d as !root", - dummy_pid, errno); - - rtp.type = RTP_PRIO_NORMAL; - rtp.prio = 0; - error = rtprio(RTP_SET, dummy_pid, &rtp); - if (error == 0) - errx(-1, - "rtprio(RTP_SET, %d, {NORMAL, 0) succeeded as !root", - dummy_pid); - if (errno != EPERM) - err(-1, "rtprio(RTP_SET, %d, {NORMAL, 0}) wrong errno %d as " - "!root", dummy_pid, errno); - - exit(0); + error = rtprio(RTP_SET, childproc, &rtp); + if (asroot && injail) + expect("priv_sched_rtprio_aproc_idle(asroot, injail)", + error, -1, ESRCH); + if (asroot && !injail) + expect("priv_sched_rtprio_aproc_idle(asroot, !injail)", + error, 0, 0); + if (!asroot && injail) + expect("priv_sched_rtprio_aproc_idle(!asroot, injail)", + error, -1, ESRCH); + if (!asroot && !injail) + expect("priv_sched_rtprio_aroc_idle(!asroot, !injail)", + error, -1, EPERM); } void -priv_sched_rtprio(void) +priv_sched_rtprio_aproc_realtime(int asroot, int injail, struct test *test) { - pid_t dummy_pid, test_pid; + struct rtprio rtp; + int error; - assert_root(); + rtp.type = RTP_PRIO_REALTIME; + rtp.prio = 0; + error = rtprio(RTP_SET, childproc, &rtp); + if (asroot && injail) + expect("priv_sched_rtprio_aproc_realtime(asroot, injail)", + error, -1, ESRCH); + if (asroot && !injail) + expect("priv_sched_rtprio_aproc_realtime(asroot, !injail)", + error, 0, 0); + if (!asroot && injail) + expect("priv_sched_rtprio_aproc_realtime(!asroot, injail)", + error, -1, ESRCH); + if (!asroot && !injail) + expect("priv_sched_rtprio_aproc_realtime(!asroot, !injail)", + error, -1, EPERM); +} - /* - * Set up dummy process, which we will kill before exiting. - */ - dummy_pid = fork(); - if (dummy_pid < 0) - err(-1, "fork - dummy"); - if (dummy_pid == 0) { - if (setresuid(UID_THIRD, UID_THIRD, UID_THIRD) < 0) - err(-1, "setresuid(%d)", UID_THIRD); - dummy(); - } - sleep(1); /* Allow dummy thread to change uids. */ +void +priv_sched_rtprio_cleanup(int asroot, int injail, struct test *test) +{ + pid_t pid; - test_pid = fork(); - if (test_pid < 0) { - warn("fork - test"); - collect(-1, dummy_pid); - return; + if (childproc_running) { + (void)kill(childproc, SIGKILL); + while (1) { + pid = waitpid(childproc, NULL, 0); + if (pid == -1) + warn("waitpid(%d (test), NULL, 0)", + childproc); + if (pid == childproc) + break; + } + childproc_running = 0; + childproc = -1; } - if (test_pid == 0) - test(dummy_pid); - - collect(test_pid, dummy_pid); } |