From ab8187850ff29ab92464b7f2d8d99a5bd2c45e37 Mon Sep 17 00:00:00 2001 From: Michael Neumann Date: Mon, 5 Jan 2009 15:02:50 +0100 Subject: [PATCH] Start privilege testing framework --- tools/regression/priv/Makefile | 13 ++++ tools/regression/priv/README | 1 + tools/regression/priv/test.c | 151 ++++++++++++++++++++++++++++++++++++++ tools/regression/priv/test.h | 5 ++ tools/regression/priv/test_acct.c | 44 +++++++++++ 5 files changed, 214 insertions(+) create mode 100644 tools/regression/priv/Makefile create mode 100644 tools/regression/priv/README create mode 100644 tools/regression/priv/test.c create mode 100644 tools/regression/priv/test.h create mode 100644 tools/regression/priv/test_acct.c diff --git a/tools/regression/priv/Makefile b/tools/regression/priv/Makefile new file mode 100644 index 0000000000..71c7b666e4 --- /dev/null +++ b/tools/regression/priv/Makefile @@ -0,0 +1,13 @@ +compile: test_acct + +run: compile + ./test_acct + +clean: + rm *.o test_acct + +test.o: test.c + ${CC} -c test.c + +test_acct: test_acct.c test.o test.h + ${CC} -o test_acct test.o test_acct.c diff --git a/tools/regression/priv/README b/tools/regression/priv/README new file mode 100644 index 0000000000..d5847fe535 --- /dev/null +++ b/tools/regression/priv/README @@ -0,0 +1 @@ +Checks for correct priv(9) behaviour. diff --git a/tools/regression/priv/test.c b/tools/regression/priv/test.c new file mode 100644 index 0000000000..3749c21d34 --- /dev/null +++ b/tools/regression/priv/test.c @@ -0,0 +1,151 @@ +#include +#include +#include +#include +#include +#include + +void setup(); +void teardown(); + +uid_t unpriv_uid = 5000; +gid_t unpriv_gid = 5000; + +void +test(int (*fn)(), int expected, char *msg, char *msg2) +{ + int retval; + + setup(); + retval = fn(); + teardown(); + + printf("%s (%s): ", msg, msg2); + + if (retval == expected) { + printf("OK\n"); + } else { + printf("FAILED (was: %d, expected: %d)\n", retval, expected); + } + fflush(stdout); +} + +void +test_as_root(int (*fn)(), int expected, char *msg) +{ + if (getuid() != 0) { + fprintf(stderr, "must be run as root\n"); + exit(-1); + } + + test(fn, expected, msg, "as root"); +} + +void +test_as_jailed_root(int (*fn)(), int expected, char *msg) +{ + if (getuid() != 0) { + fprintf(stderr, "must be run as root\n"); + exit(-1); + } + + int child = fork(); + + if (child == -1) { + fprintf(stderr, "fork failed\n"); + exit(-2); + } + + if (child) { + struct jail j; + j.version = 1; + j.path = "/"; + j.hostname = "jail"; + j.n_ips = 0; + + int jid = jail(&j); + if (jid < 0) { + fprintf(stderr, "jail failed\n"); + exit(-1); // TODO + } + test(fn, expected, msg, "as jailed root"); + exit(0); + } + else { + waitpid(child, NULL, 0); + } +} + +void +test_as_unpriv(int (*fn)(), int expected, char *msg) +{ + if (getuid() != 0) { + fprintf(stderr, "must be run as root\n"); + exit(-1); + } + + int child = fork(); + + if (child == -1) { + fprintf(stderr, "fork failed\n"); + exit(-2); + } + + if (child) { + setgid(unpriv_gid); + setuid(unpriv_uid); + + if (getuid() != unpriv_uid || getgid() != unpriv_gid) { + fprintf(stderr, "setuid/gid failed\n"); + exit(-1); // TODO + } + test(fn, expected, msg, "as unpriv"); + exit(0); + } + else { + waitpid(child, NULL, 0); + } +} + +void +test_as_jailed_unpriv(int (*fn)(), int expected, char *msg) +{ + if (getuid() != 0) { + fprintf(stderr, "must be run as root\n"); + exit(-1); + } + + int child = fork(); + + if (child == -1) { + fprintf(stderr, "fork failed\n"); + exit(-2); + } + + if (child) { + struct jail j; + j.version = 1; + j.path = "/"; + j.hostname = "jail"; + j.n_ips = 0; + + int jid = jail(&j); + if (jid < 0) { + fprintf(stderr, "jail failed\n"); + exit(-1); // TODO + } + + setgid(unpriv_gid); + setuid(unpriv_uid); + + if (getuid() != unpriv_uid || getgid() != unpriv_gid) { + fprintf(stderr, "setuid/gid failed\n"); + exit(-1); // TODO + } + test(fn, expected, msg, "as jailed unpriv"); + exit(0); + } + else { + waitpid(child, NULL, 0); + } +} diff --git a/tools/regression/priv/test.h b/tools/regression/priv/test.h new file mode 100644 index 0000000000..29b75a2f11 --- /dev/null +++ b/tools/regression/priv/test.h @@ -0,0 +1,5 @@ +void test(int (*fn)(), int expected, char *msg, char *msg2); +void test_as_root(int (*fn)(), int expected, char *msg); +void test_as_jailed_root(int (*fn)(), int expected, char *msg); +void test_as_unpriv(int (*fn)(), int expected, char *msg); +void test_as_jailed_unpriv(int (*fn)(), int expected, char *msg); diff --git a/tools/regression/priv/test_acct.c b/tools/regression/priv/test_acct.c new file mode 100644 index 0000000000..7bae90f43a --- /dev/null +++ b/tools/regression/priv/test_acct.c @@ -0,0 +1,44 @@ +#include +#include +#include +#include +#include "test.h" + +static char *tmp_file; + +void +setup() { + tmp_file = "./tmpfile"; + int fh = open(tmp_file, O_CREAT | O_TRUNC | O_WRONLY, 0666); + close(fh); +} + +void +teardown() { + unlink(tmp_file); +} + +int +test_acct() { + int error; + + error = acct(tmp_file); + if (error == -1) + return errno; + + error = acct(NULL); + if (error == -1) + return errno; + + return 0; +} + +int main() +{ + test_as_root (test_acct, 0, "acct"); + test_as_jailed_root (test_acct, EPERM, "acct"); + test_as_unpriv (test_acct, EPERM, "acct"); + test_as_jailed_unpriv (test_acct, EPERM, "acct"); + + return 0; +} -- 2.11.4.GIT