Last active
December 30, 2024 23:17
-
-
Save lukaslihotzki/34fe03a0cde2c64d71bf9c3a6f9bde17 to your computer and use it in GitHub Desktop.
Program that denies its own exit using seccomp-bpf.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Program that denies its own exit using seccomp-bpf, so it will consume 100% CPU forever, unless killed externally. | |
// Execute this program with strace to see that exiting actually fails. | |
#include <errno.h> | |
#include <linux/bpf.h> | |
#include <linux/filter.h> | |
#include <linux/seccomp.h> | |
#include <linux/unistd.h> | |
#include <signal.h> | |
#include <stdio.h> | |
#include <sys/prctl.h> | |
#include <unistd.h> | |
void busy_loop(int signo) { | |
for (;;) __asm(""); | |
} | |
int main() { | |
// handle these signals by busy-looping to prevent exiting through them | |
signal(SIGTRAP, busy_loop); | |
signal(SIGSEGV, busy_loop); | |
signal(SIGILL, busy_loop); | |
signal(SIGBUS, busy_loop); | |
struct sock_filter filter[] = { | |
// unconditionally deny all syscalls (with EPERM) | |
BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ERRNO | (EPERM & SECCOMP_RET_DATA)), | |
}; | |
struct sock_fprog prog = { | |
.len = (unsigned short)(sizeof(filter) / sizeof(filter[0])), | |
.filter = filter, | |
}; | |
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { | |
perror("prctl(NO_NEW_PRIVS)"); | |
return 1; | |
} | |
if (prctl(PR_SET_SECCOMP, 2, &prog)) { | |
perror("prctl(PR_SET_SECCOMP)"); | |
return 1; | |
} | |
// At this point, the process cannot exit, neither directly nor indirectly. | |
// Try to call `exit` first (failing with EPERM) | |
syscall(__NR_exit, 0); | |
// Return from main, which will call `exit_group` (failing with EPERM) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment