runtime/native/src/main.cpp
2024-06-05 00:11:54 -04:00

66 lines
2.0 KiB
C++

#include <unistd.h>
#include <cstring>
#include <cerrno>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <linux/seccomp.h>
#include <linux/filter.h>
#include <cstddef>
#include <sys/prctl.h>
#include <trampoline/types.h>
#include "log.h"
#include "memory.h"
#include "trampoline.h"
#include "ptrace.h"
// Main
int main(__attribute__((unused)) int argc, char *argv[]) {
// Fork
pid_t pid = fork();
if (pid == -1) {
ERR("Unable To Fork Process: %s", strerror(errno));
} else if (pid == 0) {
// seccomp Filter
sock_filter filter[] = {
// Load Syscall Number To Accumulator
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(seccomp_data, nr)),
// If Syscall Does Not Match The Trampoline, Then Skip The Next Instruction
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, TRAMPOLINE_SYSCALL, 0, 1),
// Trigger PTrace And End Filter
BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_TRACE),
// Allow Syscall And End Filter
BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ALLOW)
};
sock_fprog prog = {
.len = (unsigned short) (sizeof(filter) / sizeof(filter[0])),
.filter = filter
};
// Setup PTrace
ptrace(PTRACE_TRACEME, 0, 0, 0);
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1) {
ERR("Unable To Prepare Process For seccomp: %s", strerror(errno));
}
if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) == -1) {
ERR("Unable To Set seccomp Filter: %s", strerror(errno));
}
// Execute Program
execvp(argv[1], (char *const *) &argv[1]);
ERR("Unable To Execute Program: %s: %s", argv[1], strerror(errno));
} else {
// Parent
// Wait For PTrace
waitpid(pid, nullptr, 0);
// Configure PTrace
ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_EXITKILL | PTRACE_O_TRACESECCOMP);
// Setup Trampoline
init_memory(pid);
init_trampoline();
// Start PTrace Loop
loop_ptrace(pid);
}
}