This repository has been archived on 2022-05-27. You can view files and clone it, but cannot push or open issues or pull requests.
ocaml-cgroups2/examples/fib/fib_priv_sep.c

77 lines
1.5 KiB
C

// For privilege separation
#include <clone3.h>
#include <linux/wait.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
// This program
#include <stdint.h>
#include <stdio.h>
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;
}