Skip to content

Instantly share code, notes, and snippets.

@lukaslihotzki
Last active December 30, 2024 23:17
Show Gist options
  • Save lukaslihotzki/34fe03a0cde2c64d71bf9c3a6f9bde17 to your computer and use it in GitHub Desktop.
Save lukaslihotzki/34fe03a0cde2c64d71bf9c3a6f9bde17 to your computer and use it in GitHub Desktop.
Program that denies its own exit using seccomp-bpf.
// 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