Skip to content

Instantly share code, notes, and snippets.

@mvanotti
Last active January 27, 2025 21:20
Show Gist options
  • Save mvanotti/63c868250833ed489c890aff51c643dc to your computer and use it in GitHub Desktop.
Save mvanotti/63c868250833ed489c890aff51c643dc to your computer and use it in GitHub Desktop.
Check for Write | Exec permissions in mmap (x86_64)
#include <err.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>
#include "seccomp-bpf.h"
static bool install_syscall_filter(void) {
struct sock_filter filter[] = {
VALIDATE_ARCHITECTURE,
// 0 A = syscall_num
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, syscall_nr),
// 1 if (A == __NR_mmap) goto 5
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, __NR_mmap, 3, 0),
// 2 if (A == __NR_mprotect) goto 5
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, __NR_mprotect, 2, 0),
// 3 if (A == __NR_pkey_mprotect) goto 5
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, __NR_pkey_mprotect, 1, 0),
// 4 return ALLOW
BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ALLOW),
// mmap, mprotect and pkey_mprotect have the protection in arg2.
// mmap(addr, size, PROT, flags, fd, offset)
// mprotect(addr, size, prot)
// pkey_mprotect(addr, size, prot, key)
// 5 A = arg[2]
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, syscall_arg(2)),
// 6 A &= PROT_WRITE|PROT_EXEC
BPF_STMT(BPF_ALU + BPF_AND, PROT_WRITE | PROT_EXEC),
// 7 if (A == PROT_WRITE|PROT_EXEC) goto 8
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, PROT_WRITE | PROT_EXEC, 1, 0),
// 8 return ALLOW
BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ALLOW),
// 9 return KILL
KILL_PROCESS,
};
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) == -1) {
perror("prctl(NO_NEW_PRIVS)");
return false;
}
if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
perror("prctl(SECCOMP)");
return false;
}
return true;
}
int main(int argc, char *argv[], char *envp[]) {
if (argc <= 1) {
fprintf(stderr, "Usage: wxjail program [arg1] [arg2] ...\n");
exit(EXIT_FAILURE);
}
if (!install_syscall_filter()) {
fprintf(stderr, "Failed to install seccomp filter\n");
exit(EXIT_FAILURE);
}
if (execve(argv[1], &argv[1], envp) == -1) {
err(EXIT_FAILURE, "execve");
}
__builtin_unreachable();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment