void test_syscall(int syscall) { //clear_log(); do_intercept(syscall, 0); do_intercept(syscall, -EBUSY); do_as_guest("./test_intercept nonroot %d", syscall, 0); do_release(syscall, 0); }
int main(int argc, char **argv) { srand(time(NULL)); if (argc>1 && strcmp(argv[1], "intercept") == 0) return do_intercept(atoi(argv[2]), atoi(argv[3])); if (argc>1 && strcmp(argv[1], "release") == 0) return do_release(atoi(argv[2]), atoi(argv[3])); if (argc>1 && strcmp(argv[1], "nonroot") == 0) return do_nonroot(atoi(argv[2])); test("insmod interceptor.ko %s", "", system("insmod interceptor.ko") == 0); test("bad MY_CUSTOM_SYSCALL args%s", "", vsyscall_arg(MY_CUSTOM_SYSCALL, 3, 100, 0, 0) == -EINVAL); do_intercept(MY_CUSTOM_SYSCALL, -EINVAL); do_release(MY_CUSTOM_SYSCALL, -EINVAL); do_intercept(-1, -EINVAL); do_release(-1, -EINVAL); do_intercept(__NR_exit, 0); do_release(__NR_exit, 0); test_syscall(SYS_open); /* The above line of code tests SYS_open. * Feel free to add more tests here for other system calls, * once you get everything to work; check Linux documentation * for other syscall number definitions. */ test("rmmod interceptor.ko %s", "", system("rmmod interceptor") == 0); return 0; }
int main(int argc, char **argv) { srand(time(NULL)); if (argc > 1 && strcmp(argv[1], "intercept") == 0) return do_intercept(atoi(argv[2]), atoi(argv[3])); if (argc > 1 && strcmp(argv[1], "release") == 0) return do_release(atoi(argv[2]), atoi(argv[3])); if (argc > 1 && strcmp(argv[1], "start") == 0) return do_start(atoi(argv[2]), atoi(argv[3]), atoi(argv[4])); if (argc > 1 && strcmp(argv[1], "stop") == 0) return do_stop(atoi(argv[2]), atoi(argv[3]), atoi(argv[4])); if (argc > 1 && strcmp(argv[1], "monitor") == 0) return test_monitor(atoi(argv[2]), TRUE); if (argc > 1 && strcmp(argv[1], "nonroot") == 0) return do_nonroot(atoi(argv[2])); struct sigaction sa; sa.sa_flags = SA_SIGINFO; sigemptyset(&sa.sa_mask); sa.sa_sigaction = on_quit; if (sigaction(SIGQUIT, &sa, NULL) == -1) perror("Cannot register signal handler"); test("insmod interceptor.ko %s", "", system("insmod interceptor.ko") == 0); test("bad MY_SYSCALL args%s", "", vsyscall_arg(MY_CUSTOM_SYSCALL, 3, 100, 0, 0) == -EINVAL); do_intercept(MY_CUSTOM_SYSCALL, -EINVAL); do_release(MY_CUSTOM_SYSCALL, -EINVAL); do_intercept(-1, -EINVAL); do_release(-1, -EINVAL); do_intercept(__NR_exit, 0); do_release(__NR_exit, 0); test_syscall(SYS_open); /* The above line of code tests SYS_open. Feel free to add more tests here for other system calls, once you get everything to work; check Linux documentation for other syscall number definitions. */ do_intercept(SYS_open, 0); do_start(SYS_open, -1, 0); test_monitor(SYS_open, TRUE); test("rmmod interceptor.ko %s", "", system("rmmod interceptor") == 0); test_monitor(SYS_open, FALSE); return 0; }
void test_syscall(int syscall) { //clear_log(); do_intercept(syscall, 0); do_as_guest("./test_full nonroot %d", syscall, 0); do_start(syscall, -2, -EINVAL); do_start(syscall, 0, 0); do_stop(syscall, 0, 0); do_start(syscall, 1, 0); do_as_guest("./test_full stop %d 1 %d", syscall, -EPERM); do_stop(syscall, 1, 0); do_as_guest("./test_full start %d -1 %d", syscall, 0); do_stop(syscall, last_child, -EINVAL); do_release(syscall, 0); puts("----- START OF test_PASS -----"); test_PASS(syscall); puts("----- END OF test_PASS -----"); puts("----- START OF test_A -----"); test_A(syscall); puts("----- END OF test_A -----"); puts("----- START OF test_B -----"); test_B(syscall, TRUE); puts("----- END OF test_B -----"); puts("----- START OF test_CDE ----"); test_CDE(syscall); puts("----- END OF test_CDE ----"); }
void test_syscall(int syscall) { //clear_log(); do_intercept(syscall, 0); do_intercept(syscall, -EBUSY); do_as_guest("./test_full nonroot %d", syscall, 0); do_start(syscall, -2, -EINVAL); do_start(syscall, 0, 0); do_stop(syscall, 0, 0); do_start(syscall, 1, 0); do_as_guest("./test_full stop %d 1 %d", syscall, -EPERM); do_stop(syscall, 1, 0); do_as_guest("./test_full start %d -1 %d", syscall, 0); do_stop(syscall, last_child, -EINVAL); do_release(syscall, 0); }
void test_A(int syscall) { // test negative syscall number do_intercept(-1, -EINVAL); do_release(-1, -EINVAL); do_start(-1, -1, -EINVAL); do_stop(-1, -1, -EINVAL); // test the last syscall do_intercept(MAX_SYSCALLS - 1, 0); do_start(MAX_SYSCALLS - 1, -1, 0); do_stop(MAX_SYSCALLS - 1, -1, 0); do_release(MAX_SYSCALLS - 1, 0); // test greater than NR_syscalls do_intercept(MAX_SYSCALLS, -EINVAL); do_release(MAX_SYSCALLS, -EINVAL); do_start(MAX_SYSCALLS, -1, -EINVAL); do_stop(MAX_SYSCALLS, -1, -EINVAL); do_intercept(MAX_SYSCALLS + 1, -EINVAL); do_release(MAX_SYSCALLS + 1, -EINVAL); do_start(MAX_SYSCALLS + 1, -1, -EINVAL); do_stop(MAX_SYSCALLS + 1, -1, -EINVAL); // test MY_CUSTOM_SYSCALL do_intercept(MY_CUSTOM_SYSCALL, -EINVAL); do_release(MY_CUSTOM_SYSCALL, -EINVAL); do_start(MY_CUSTOM_SYSCALL, -1, -EINVAL); do_stop(MY_CUSTOM_SYSCALL, -1, -EINVAL); // test on pids do_intercept(syscall, 0); do_start(syscall, -2, -EINVAL); do_stop(syscall, -2, -EINVAL); do_release(syscall, 0); }
int do_nonroot(int syscall) { do_intercept(syscall, -EPERM); do_release(syscall, -EPERM); do_start(syscall, 0, -EPERM); do_stop(syscall, 0, -EPERM); do_start(syscall, 1, -EPERM); do_stop(syscall, 1, -EPERM); do_start(syscall, getpid(), 0); do_start(syscall, getpid(), -EBUSY); do_monitor(syscall); do_stop(syscall, getpid(), 0); do_stop(syscall, getpid(), -EINVAL); return 0; }
void test_B(int syscall, int iamroot) { #define subtestroot(s) printf((s" as %s\n"), (iamroot)?"root":"nonroot") subtestroot("EPERM: intercept"); do_intercept(syscall, iamroot ? 0 : -EPERM); subtestroot("EPERM: monitor self"); do_start(syscall, -1, 0); do_stop(syscall, -1, 0); subtestroot("EPERM: monitor all processes"); do_start(syscall, 0, iamroot ? 0 : -EPERM); do_stop(syscall, 0, iamroot ? 0 : -EPERM); subtestroot("EPERM: monitor init process"); do_start(syscall, 1, iamroot ? 0 : -EPERM); do_stop(syscall, 1, iamroot ? 0 : -EPERM); subtestroot("EPERM: release"); do_release(syscall, iamroot ? 0 : -EPERM); #undef subtestroot }
/* note this test is run after all processes have been intercepted*/ int do_nonroot(int syscall) { do_intercept(syscall, -EPERM); do_release(syscall, -EPERM); do_start(syscall, 0, -EPERM); do_stop(syscall, 0, -EPERM); do_start(syscall, 1, -EPERM); do_stop(syscall, 1, -EPERM); do_start(syscall, getpid(), 0); do_start(syscall, getpid(), -EBUSY); test_monitor(syscall, TRUE); do_stop(syscall, getpid(), 0); do_stop(syscall, getpid(), -EINVAL); puts("----- START OF test_B -----"); test_B(syscall, FALSE); puts("----- END OF test_B -----"); return 0; }
void test_PASS(int syscall) { int child; subtest("intercept"); do_intercept(syscall, 0); do_release(syscall, 0); subtest("monitor"); do_intercept(syscall, 0); test_monitor(syscall, FALSE); do_start(syscall, -1, 0); test_monitor(syscall, TRUE); do_stop(syscall, -1, 0); test_monitor(syscall, FALSE); do_release(syscall, 0); subtest("monitor & kill monitored process"); do_intercept(syscall, 0); switch (child = fork()) { case -1: assert(0); case 0: // monitor the child process then exit do_start(syscall, -1, 0); test_monitor(syscall, TRUE); exit(0); default: waitpid(child, NULL, 0); // child should have been unmonitored automatically // there is no way to start process with specific pid... do_start(syscall, child, -EINVAL); do_stop(syscall, child, -EINVAL); } do_release(syscall, 0); subtest("monitor all pids"); do_intercept(syscall, 0); test_monitor2(syscall, FALSE, FALSE); do_start(syscall, 0, 0); test_monitor2(syscall, TRUE, TRUE); subtest("stop monitor current pid"); do_stop(syscall, -1, 0); test_monitor2(syscall, FALSE, TRUE); subtest("monitor all -> stop one -> monitor all"); do_start(syscall, 0, 0); do_stop(syscall, -1, 0); do_start(syscall, 0, 0); do_stop(syscall, 0, 0); subtest("monitor one -> stop all"); do_start(syscall, -1, 0); do_stop(syscall, 0, 0); subtest("monitor all -> stop one -> stop all"); do_start(syscall, 0, 0); do_stop(syscall, -1, 0); do_stop(syscall, 0, 0); subtest("reset"); do_start(syscall, -1, 0); test_monitor2(syscall, TRUE, FALSE); do_stop(syscall, 0, 0); test_monitor2(syscall, FALSE, FALSE); do_release(syscall, 0); }
void test_CDE(int syscall) { //C -EINVAL subtest("Cannot de-intercept a system call that has not been intercepted yet."); do_release(syscall, -EINVAL); subtest("Cannot stop monitoring a pid for a syscall that has not been intercepted."); do_stop(syscall, -1, -EINVAL); do_stop(syscall, 0, -EINVAL); subtest("Cannot start monitoring a pid for that has not been intercepted yet."); do_start(syscall, -1, -EINVAL); do_start(syscall, 0, -EINVAL); do_intercept(syscall, 0); subtest("Cannot start monitoring a pid that is invalid."); do_start(syscall, 1234567, -EINVAL); do_start(syscall, -2, -EINVAL); subtest("Cannot stop monitoring for a pid that is not being monitored."); do_stop(syscall, 0, -EINVAL); do_stop(syscall, -1, -EINVAL); subtest("Cannot stop monitoring for a pid that is blacklisted."); do_start(syscall, 0, 0); do_stop(syscall, -1, 0); do_stop(syscall, -1, -EINVAL); do_stop(syscall, 0, 0); subtest("EINVAL: stop all -> stop all"); do_start(syscall, 0, 0); do_stop(syscall, 0, 0); do_stop(syscall, 0, -EINVAL); subtest("EINVAL: start one pid -> stop the same pid -> stop all"); do_start(syscall, -1, 0); do_stop(syscall, -1, 0); do_stop(syscall, 0, -EINVAL); do_release(syscall, 0); //D -EBUSY do_intercept(syscall, 0); subtest("EBUSY: intercepting a system call that is already intercepted"); do_intercept(syscall, -EBUSY); subtest("EBUSY: monitoring a pid that is being whitelisted"); do_start(syscall, -1, 0); do_start(syscall, -1, -EBUSY); do_stop(syscall, -1, 0); subtest("EBUSY: monitoring a pid that is being monitored globally"); do_start(syscall, 0, 0); do_start(syscall, -1, -EBUSY); do_stop(syscall, 0, 0); subtest("EBUSY: monitoring all pids when all pids are being monitored"); do_start(syscall, 0, 0); do_start(syscall, 0, -EBUSY); do_stop(syscall, 0, 0); subtest("OK: monitoring all pids when some pids are being monitored"); do_start(syscall, -1, 0); do_start(syscall, 0, 0); do_stop(syscall, -1, 0); do_stop(syscall, 0, 0); //E -ENOMEM //If a pid cannot be added to a monitored list, due to no memory being available, an -ENOMEM error code should be returned. // int child; // int res = 0; // while (!res) { // switch (child = fork()) { // case -1://error // assert(0); // case 0: //child // pause(); // default: //parent // res = vsyscall_arg(MY_CUSTOM_SYSCALL, 3, REQUEST_START_MONITORING, syscall, child); // // printf("start monitoring %d: %d\n", child, res); // break; // } // } // test("%d no memory", syscall, res == -ENOMEM); // signal(SIGQUIT, SIG_IGN); // kill(-getpid(), SIGQUIT); do_release(syscall, 0); }
int do_nonroot(int syscall) { do_intercept(syscall, -EPERM); do_release(syscall, -EPERM); return 0; }