From 4c5788af37b810e8c1c3aba8295310db331b1419 Mon Sep 17 00:00:00 2001 From: Jake Hillion Date: Tue, 25 Jan 2022 18:06:39 +0000 Subject: [PATCH] privilege separated fib function --- examples/fib/.gitignore | 1 + examples/fib/Makefile | 10 +++++ examples/fib/fib_priv_sep.c | 76 +++++++++++++++++++++++++++++++++++++ include/clone3.h | 3 ++ lib/clone3.c | 7 ++++ 5 files changed, 97 insertions(+) create mode 100644 examples/fib/.gitignore create mode 100644 examples/fib/Makefile create mode 100644 examples/fib/fib_priv_sep.c create mode 100644 include/clone3.h create mode 100644 lib/clone3.c diff --git a/examples/fib/.gitignore b/examples/fib/.gitignore new file mode 100644 index 0000000..774cfd6 --- /dev/null +++ b/examples/fib/.gitignore @@ -0,0 +1 @@ +fib_priv_sep diff --git a/examples/fib/Makefile b/examples/fib/Makefile new file mode 100644 index 0000000..b7fbd26 --- /dev/null +++ b/examples/fib/Makefile @@ -0,0 +1,10 @@ +C=clang -Wall + +all: fib_priv_sep + +clean: + rm -f fib_priv_sep + +fib_priv_sep: fib_priv_sep.c ../../lib/clone3.c ../../include/clone3.h + ${C} -I../../include -o fib_priv_sep fib_priv_sep.c ../../lib/clone3.c + sudo setcap CAP_SYS_ADMIN+eip ./fib_priv_sep diff --git a/examples/fib/fib_priv_sep.c b/examples/fib/fib_priv_sep.c new file mode 100644 index 0000000..aba1f79 --- /dev/null +++ b/examples/fib/fib_priv_sep.c @@ -0,0 +1,76 @@ +// For privilege separation +#include + +#include +#include +#include +#include + +// This program +#include +#include + +uint64_t fib(uint64_t i) { + uint64_t a = 0; + uint64_t b = 1; + + for (; i > 0; i--) { + uint64_t old_b = b; + b = b + a; + a = old_b; + } + + return a; +} + +int real_main(int argc, char **argv); + +int main(int argc, char **argv) { + int pid_fd; + + struct clone_args cl_args = { + .flags = CLONE_NEWIPC | CLONE_NEWNET | CLONE_NEWNS | CLONE_NEWPID | + CLONE_NEWUSER | CLONE_NEWUTS | CLONE_PIDFD, + .pidfd = (uint64_t)&pid_fd, + .child_tid = (uint64_t)NULL, + .parent_tid = (uint64_t)NULL, + .exit_signal = SIGCHLD, + .stack = (uint64_t)NULL, + .stack_size = 0, + .tls = (uint64_t)NULL, + }; + + pid_t child = clone3(&cl_args); + if (child < 0) { + perror("clone3"); + exit(-1); + } else if (child == 0) { + int code = real_main(argc, argv); + exit(code); + } else { + siginfo_t status; + if (waitid(P_PIDFD, pid_fd, &status, WEXITED) == -1) { + perror("waitid"); + return -1; + } + + exit(status.si_status); + } +} + +int real_main(int argc, char **argv) { + if (argc != 2) { + fprintf(stderr, "expected 1 argument\n"); + return -1; + } + + uint64_t i = 0; + if (sscanf(argv[1], "%lu", &i) != 1) { + fprintf(stderr, "sscanf failed\n"); + return -1; + } + + uint64_t fib_result = fib(i); + printf("fib(%lu) = %lu\n", i, fib_result); + return 0; +} diff --git a/include/clone3.h b/include/clone3.h new file mode 100644 index 0000000..12c217c --- /dev/null +++ b/include/clone3.h @@ -0,0 +1,3 @@ +#include + +long clone3(struct clone_args *cl_args); diff --git a/lib/clone3.c b/lib/clone3.c new file mode 100644 index 0000000..c92274e --- /dev/null +++ b/lib/clone3.c @@ -0,0 +1,7 @@ +#include +#include +#include + +long clone3(struct clone_args *cl_args) { + return syscall(SYS_clone3, cl_args, sizeof(struct clone_args)); +}