Merge pull request #1084 from AFLplusplus/dev

push to stable
This commit is contained in:
van Hauser 2021-09-01 08:41:21 +02:00 committed by GitHub
commit 773baf9391
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 1423 additions and 15 deletions

View File

@ -13,6 +13,9 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
- added AFL_IGNORE_PROBLEMS plus checks to identify and abort on - added AFL_IGNORE_PROBLEMS plus checks to identify and abort on
incorrect LTO usage setups and enhanced the READMEs for better incorrect LTO usage setups and enhanced the READMEs for better
information on how to deal with instrumenting libraries information on how to deal with instrumenting libraries
- fix a regression introduced in 3.10 that resulted in less
coverage being detected. thanks to Collin May for reporting!
- afl-cc: - afl-cc:
- fix for shared linking on MacOS - fix for shared linking on MacOS
- llvm and LTO mode verified to work with new llvm 14-dev - llvm and LTO mode verified to work with new llvm 14-dev

View File

@ -197,6 +197,8 @@ gdb \
--args <my-executable> [my arguments] --args <my-executable> [my arguments]
``` ```
* `AFL_FRIDA_SECCOMP_FILE` - Write a log of any syscalls made by the target to
the specified file.
* `AFL_FRIDA_STALKER_IC_ENTRIES` - Configure the number of inline cache entries * `AFL_FRIDA_STALKER_IC_ENTRIES` - Configure the number of inline cache entries
stored along-side branch instructions which provide a cache to avoid having to stored along-side branch instructions which provide a cache to avoid having to
call back into FRIDA to find the next block. Default is 32. call back into FRIDA to find the next block. Default is 32.

View File

@ -26,6 +26,7 @@
js_api_set_persistent_return; js_api_set_persistent_return;
js_api_set_prefetch_backpatch_disable; js_api_set_prefetch_backpatch_disable;
js_api_set_prefetch_disable; js_api_set_prefetch_disable;
js_api_set_seccomp_file;
js_api_set_stalker_callback; js_api_set_stalker_callback;
js_api_set_stalker_ic_entries; js_api_set_stalker_ic_entries;
js_api_set_stats_file; js_api_set_stats_file;

View File

@ -0,0 +1,359 @@
#ifndef _SECCOMP_H
#define _SECCOMP_H
#include <linux/seccomp.h>
#include "frida-gumjs.h"
#define SECCOMP_SOCKET_SEND_FD 0x1D3
#define SECCOMP_SOCKET_RECV_FD 0x1D4
#define SECCOMP_OUTPUT_FILE_FD 0x1D5
#define SECCOMP_PARENT_EVENT_FD 0x1D6
enum {
SYS_READ = 0,
SYS_WRITE = 1,
SYS_OPEN = 2,
SYS_CLOSE = 3,
SYS_STAT = 4,
SYS_FSTAT = 5,
SYS_LSTAT = 6,
SYS_POLL = 7,
SYS_LSEEK = 8,
SYS_MMAP = 9,
SYS_MPROTECT = 10,
SYS_MUNMAP = 11,
SYS_BRK = 12,
SYS_RT_SIGACTION = 13,
SYS_RT_SIGPROCMASK = 14,
SYS_RT_SIGRETURN = 15,
SYS_IOCTL = 16,
SYS_PREAD64 = 17,
SYS_PWRITE64 = 18,
SYS_READV = 19,
SYS_WRITEV = 20,
SYS_ACCESS = 21,
SYS_PIPE = 22,
SYS_SELECT = 23,
SYS_SCHED_YIELD = 24,
SYS_MREMAP = 25,
SYS_MSYNC = 26,
SYS_MINCORE = 27,
SYS_MADVISE = 28,
SYS_SHMGET = 29,
SYS_SHMAT = 30,
SYS_SHMCTL = 31,
SYS_DUP = 32,
SYS_DUP2 = 33,
SYS_PAUSE = 34,
SYS_NANOSLEEP = 35,
SYS_GETITIMER = 36,
SYS_ALARM = 37,
SYS_SETITIMER = 38,
SYS_GETPID = 39,
SYS_SENDFILE = 40,
SYS_SOCKET = 41,
SYS_CONNECT = 42,
SYS_ACCEPT = 43,
SYS_SENDTO = 44,
SYS_RECVFROM = 45,
SYS_SENDMSG = 46,
SYS_RECVMSG = 47,
SYS_SHUTDOWN = 48,
SYS_BIND = 49,
SYS_LISTEN = 50,
SYS_GETSOCKNAME = 51,
SYS_GETPEERNAME = 52,
SYS_SOCKETPAIR = 53,
SYS_SETSOCKOPT = 54,
SYS_GETSOCKOPT = 55,
SYS_CLONE = 56,
SYS_FORK = 57,
SYS_VFORK = 58,
SYS_EXECVE = 59,
SYS_EXIT = 60,
SYS_WAIT4 = 61,
SYS_KILL = 62,
SYS_UNAME = 63,
SYS_SEMGET = 64,
SYS_SEMOP = 65,
SYS_SEMCTL = 66,
SYS_SHMDT = 67,
SYS_MSGGET = 68,
SYS_MSGSND = 69,
SYS_MSGRCV = 70,
SYS_MSGCTL = 71,
SYS_FCNTL = 72,
SYS_FLOCK = 73,
SYS_FSYNC = 74,
SYS_FDATASYNC = 75,
SYS_TRUNCATE = 76,
SYS_FTRUNCATE = 77,
SYS_GETDENTS = 78,
SYS_GETCWD = 79,
SYS_CHDIR = 80,
SYS_FCHDIR = 81,
SYS_RENAME = 82,
SYS_MKDIR = 83,
SYS_RMDIR = 84,
SYS_CREAT = 85,
SYS_LINK = 86,
SYS_UNLINK = 87,
SYS_SYMLINK = 88,
SYS_READLINK = 89,
SYS_CHMOD = 90,
SYS_FCHMOD = 91,
SYS_CHOWN = 92,
SYS_FCHOWN = 93,
SYS_LCHOWN = 94,
SYS_UMASK = 95,
SYS_GETTIMEOFDAY = 96,
SYS_GETRLIMIT = 97,
SYS_GETRUSAGE = 98,
SYS_SYSINFO = 99,
SYS_TIMES = 100,
SYS_PTRACE = 101,
SYS_GETUID = 102,
SYS_SYSLOG = 103,
SYS_GETGID = 104,
SYS_SETUID = 105,
SYS_SETGID = 106,
SYS_GETEUID = 107,
SYS_GETEGID = 108,
SYS_SETPGID = 109,
SYS_GETPPID = 110,
SYS_GETPGRP = 111,
SYS_SETSID = 112,
SYS_SETREUID = 113,
SYS_SETREGID = 114,
SYS_GETGROUPS = 115,
SYS_SETGROUPS = 116,
SYS_SETRESUID = 117,
SYS_GETRESUID = 118,
SYS_SETRESGID = 119,
SYS_GETRESGID = 120,
SYS_GETPGID = 121,
SYS_SETFSUID = 122,
SYS_SETFSGID = 123,
SYS_GETSID = 124,
SYS_CAPGET = 125,
SYS_CAPSET = 126,
SYS_RT_SIGPENDING = 127,
SYS_RT_SIGTIMEDWAIT = 128,
SYS_RT_SIGQUEUEINFO = 129,
SYS_RT_SIGSUSPEND = 130,
SYS_SIGALTSTACK = 131,
SYS_UTIME = 132,
SYS_MKNOD = 133,
SYS_USELIB = 134,
SYS_PERSONALITY = 135,
SYS_USTAT = 136,
SYS_STATFS = 137,
SYS_FSTATFS = 138,
SYS_SYSFS = 139,
SYS_GETPRIORITY = 140,
SYS_SETPRIORITY = 141,
SYS_SCHED_SETPARAM = 142,
SYS_SCHED_GETPARAM = 143,
SYS_SCHED_SETSCHEDULER = 144,
SYS_SCHED_GETSCHEDULER = 145,
SYS_SCHED_GET_PRIORITY_MAX = 146,
SYS_SCHED_GET_PRIORITY_MIN = 147,
SYS_SCHED_RR_GET_INTERVAL = 148,
SYS_MLOCK = 149,
SYS_MUNLOCK = 150,
SYS_MLOCKALL = 151,
SYS_MUNLOCKALL = 152,
SYS_VHANGUP = 153,
SYS_MODIFY_LDT = 154,
SYS_PIVOT_ROOT = 155,
SYS__SYSCTL = 156,
SYS_PRCTL = 157,
SYS_ARCH_PRCTL = 158,
SYS_ADJTIMEX = 159,
SYS_SETRLIMIT = 160,
SYS_CHROOT = 161,
SYS_SYNC = 162,
SYS_ACCT = 163,
SYS_SETTIMEOFDAY = 164,
SYS_MOUNT = 165,
SYS_UMOUNT2 = 166,
SYS_SWAPON = 167,
SYS_SWAPOFF = 168,
SYS_REBOOT = 169,
SYS_SETHOSTNAME = 170,
SYS_SETDOMAINNAME = 171,
SYS_IOPL = 172,
SYS_IOPERM = 173,
SYS_CREATE_MODULE = 174,
SYS_INIT_MODULE = 175,
SYS_DELETE_MODULE = 176,
SYS_GET_KERNEL_SYMS = 177,
SYS_QUERY_MODULE = 178,
SYS_QUOTACTL = 179,
SYS_NFSSERVCTL = 180,
SYS_GETPMSG = 181,
SYS_PUTPMSG = 182,
SYS_AFS_SYSCALL = 183,
SYS_TUXCALL = 184,
SYS_SECURITY = 185,
SYS_GETTID = 186,
SYS_READAHEAD = 187,
SYS_SETXATTR = 188,
SYS_LSETXATTR = 189,
SYS_FSETXATTR = 190,
SYS_GETXATTR = 191,
SYS_LGETXATTR = 192,
SYS_FGETXATTR = 193,
SYS_LISTXATTR = 194,
SYS_LLISTXATTR = 195,
SYS_FLISTXATTR = 196,
SYS_REMOVEXATTR = 197,
SYS_LREMOVEXATTR = 198,
SYS_FREMOVEXATTR = 199,
SYS_TKILL = 200,
SYS_TIME = 201,
SYS_FUTEX = 202,
SYS_SCHED_SETAFFINITY = 203,
SYS_SCHED_GETAFFINITY = 204,
SYS_SET_THREAD_AREA = 205,
SYS_IO_SETUP = 206,
SYS_IO_DESTROY = 207,
SYS_IO_GETEVENTS = 208,
SYS_IO_SUBMIT = 209,
SYS_IO_CANCEL = 210,
SYS_GET_THREAD_AREA = 211,
SYS_LOOKUP_DCOOKIE = 212,
SYS_EPOLL_CREATE = 213,
SYS_EPOLL_CTL_OLD = 214,
SYS_EPOLL_WAIT_OLD = 215,
SYS_REMAP_FILE_PAGES = 216,
SYS_GETDENTS64 = 217,
SYS_SET_TID_ADDRESS = 218,
SYS_RESTART_SYSCALL = 219,
SYS_SEMTIMEDOP = 220,
SYS_FADVISE64 = 221,
SYS_TIMER_CREATE = 222,
SYS_TIMER_SETTIME = 223,
SYS_TIMER_GETTIME = 224,
SYS_TIMER_GETOVERRUN = 225,
SYS_TIMER_DELETE = 226,
SYS_CLOCK_SETTIME = 227,
SYS_CLOCK_GETTIME = 228,
SYS_CLOCK_GETRES = 229,
SYS_CLOCK_NANOSLEEP = 230,
SYS_EXIT_GROUP = 231,
SYS_EPOLL_WAIT = 232,
SYS_EPOLL_CTL = 233,
SYS_TGKILL = 234,
SYS_UTIMES = 235,
SYS_VSERVER = 236,
SYS_MBIND = 237,
SYS_SET_MEMPOLICY = 238,
SYS_GET_MEMPOLICY = 239,
SYS_MQ_OPEN = 240,
SYS_MQ_UNLINK = 241,
SYS_MQ_TIMEDSEND = 242,
SYS_MQ_TIMEDRECEIVE = 243,
SYS_MQ_NOTIFY = 244,
SYS_MQ_GETSETATTR = 245,
SYS_KEXEC_LOAD = 246,
SYS_WAITID = 247,
SYS_ADD_KEY = 248,
SYS_REQUEST_KEY = 249,
SYS_KEYCTL = 250,
SYS_IOPRIO_SET = 251,
SYS_IOPRIO_GET = 252,
SYS_INOTIFY_INIT = 253,
SYS_INOTIFY_ADD_WATCH = 254,
SYS_INOTIFY_RM_WATCH = 255,
SYS_MIGRATE_PAGES = 256,
SYS_OPENAT = 257,
SYS_MKDIRAT = 258,
SYS_MKNODAT = 259,
SYS_FCHOWNAT = 260,
SYS_FUTIMESAT = 261,
SYS_NEWFSTATAT = 262,
SYS_UNLINKAT = 263,
SYS_RENAMEAT = 264,
SYS_LINKAT = 265,
SYS_SYMLINKAT = 266,
SYS_READLINKAT = 267,
SYS_FCHMODAT = 268,
SYS_FACCESSAT = 269,
SYS_PSELECT6 = 270,
SYS_PPOLL = 271,
SYS_UNSHARE = 272,
SYS_SET_ROBUST_LIST = 273,
SYS_GET_ROBUST_LIST = 274,
SYS_SPLICE = 275,
SYS_TEE = 276,
SYS_SYNC_FILE_RANGE = 277,
SYS_VMSPLICE = 278,
SYS_MOVE_PAGES = 279,
SYS_UTIMENSAT = 280,
SYS_EPOLL_PWAIT = 281,
SYS_SIGNALFD = 282,
SYS_TIMERFD_CREATE = 283,
SYS_EVENTFD = 284,
SYS_FALLOCATE = 285,
SYS_TIMERFD_SETTIME = 286,
SYS_TIMERFD_GETTIME = 287,
SYS_ACCEPT4 = 288,
SYS_SIGNALFD4 = 289,
SYS_EVENTFD2 = 290,
SYS_EPOLL_CREATE1 = 291,
SYS_DUP3 = 292,
SYS_PIPE2 = 293,
SYS_INOTIFY_INIT1 = 294,
SYS_PREADV = 295,
SYS_PWRITEV = 296,
SYS_RT_TGSIGQUEUEINFO = 297,
SYS_PERF_EVENT_OPEN = 298,
SYS_RECVMMSG = 299,
SYS_FANOTIFY_INIT = 300,
SYS_FANOTIFY_MARK = 301,
SYS_PRLIMIT64 = 302
};
extern char *seccomp_filename;
typedef void (*seccomp_child_func_t)(int event_fd, void *ctx);
typedef void (*seccomp_filter_callback_t)(struct seccomp_notif * req,
struct seccomp_notif_resp *resp,
GumReturnAddressArray * frames);
void seccomp_config(void);
void seccomp_init(void);
void seccomp_on_fork(void);
void seccomp_print(char *format, ...);
void seccomp_atomic_set(volatile bool *ptr, bool val);
bool seccomp_atomic_try_set(volatile bool *ptr, bool val);
void seccomp_atomic_wait(volatile bool *ptr, bool val);
void seccomp_child_run(seccomp_child_func_t child_func, void *ctx, pid_t *child,
int *event_fd);
void seccomp_child_wait(int event_fd);
int seccomp_event_create(void);
void seccomp_event_signal(int fd);
void seccomp_event_wait(int fd);
void seccomp_event_destroy(int fd);
int seccomp_filter_install(pid_t child);
void seccomp_filter_child_install(void);
void seccomp_filter_run(int fd, seccomp_filter_callback_t callback);
void seccomp_socket_create(int *sock);
void seccomp_socket_send(int sockfd, int fd);
int seccomp_socket_recv(int sockfd);
char *seccomp_syscall_lookup(int id);
#endif

View File

@ -8,6 +8,7 @@
#include "instrument.h" #include "instrument.h"
#include "persistent.h" #include "persistent.h"
#include "ranges.h" #include "ranges.h"
#include "seccomp.h"
#include "stalker.h" #include "stalker.h"
#include "stats.h" #include "stats.h"
#include "util.h" #include "util.h"
@ -26,6 +27,7 @@ static void entry_launch(void) {
/* Child here */ /* Child here */
entry_run = TRUE; entry_run = TRUE;
instrument_on_fork(); instrument_on_fork();
seccomp_on_fork();
stats_on_fork(); stats_on_fork();
} }

View File

@ -191,6 +191,14 @@ class Afl {
static setPrefetchDisable() { static setPrefetchDisable() {
Afl.jsApiSetPrefetchDisable(); Afl.jsApiSetPrefetchDisable();
} }
/**
* See `AFL_FRIDA_SECCOMP_FILE`. This function takes a single `string` as
* an argument.
*/
static setSeccompFile(file) {
const buf = Memory.allocUtf8String(file);
Afl.jsApiSetSeccompFile(buf);
}
/* /*
* Set a function to be called for each instruction which is instrumented * Set a function to be called for each instruction which is instrumented
* by AFL FRIDA mode. * by AFL FRIDA mode.
@ -271,6 +279,7 @@ Afl.jsApiSetPersistentHook = Afl.jsApiGetFunction("js_api_set_persistent_hook",
Afl.jsApiSetPersistentReturn = Afl.jsApiGetFunction("js_api_set_persistent_return", "void", ["pointer"]); Afl.jsApiSetPersistentReturn = Afl.jsApiGetFunction("js_api_set_persistent_return", "void", ["pointer"]);
Afl.jsApiSetPrefetchBackpatchDisable = Afl.jsApiGetFunction("js_api_set_prefetch_backpatch_disable", "void", []); Afl.jsApiSetPrefetchBackpatchDisable = Afl.jsApiGetFunction("js_api_set_prefetch_backpatch_disable", "void", []);
Afl.jsApiSetPrefetchDisable = Afl.jsApiGetFunction("js_api_set_prefetch_disable", "void", []); Afl.jsApiSetPrefetchDisable = Afl.jsApiGetFunction("js_api_set_prefetch_disable", "void", []);
Afl.jsApiSetSeccompFile = Afl.jsApiGetFunction("js_api_set_seccomp_file", "void", ["pointer"]);
Afl.jsApiSetStalkerCallback = Afl.jsApiGetFunction("js_api_set_stalker_callback", "void", ["pointer"]); Afl.jsApiSetStalkerCallback = Afl.jsApiGetFunction("js_api_set_stalker_callback", "void", ["pointer"]);
Afl.jsApiSetStalkerIcEntries = Afl.jsApiGetFunction("js_api_set_stalker_ic_entries", "void", ["uint32"]); Afl.jsApiSetStalkerIcEntries = Afl.jsApiGetFunction("js_api_set_stalker_ic_entries", "void", ["uint32"]);
Afl.jsApiSetStatsFile = Afl.jsApiGetFunction("js_api_set_stats_file", "void", ["pointer"]); Afl.jsApiSetStatsFile = Afl.jsApiGetFunction("js_api_set_stats_file", "void", ["pointer"]);

View File

@ -7,6 +7,7 @@
#include "persistent.h" #include "persistent.h"
#include "prefetch.h" #include "prefetch.h"
#include "ranges.h" #include "ranges.h"
#include "seccomp.h"
#include "stalker.h" #include "stalker.h"
#include "stats.h" #include "stats.h"
#include "util.h" #include "util.h"
@ -171,6 +172,13 @@ js_api_set_instrument_unstable_coverage_file(char *path) {
} }
__attribute__((visibility("default"))) void js_api_set_seccomp_file(
char *file) {
seccomp_filename = g_strdup(file);
}
__attribute__((visibility("default"))) void js_api_set_stdout(char *file) { __attribute__((visibility("default"))) void js_api_set_stdout(char *file) {
output_stdout = g_strdup(file); output_stdout = g_strdup(file);

View File

@ -25,6 +25,7 @@
#include "persistent.h" #include "persistent.h"
#include "prefetch.h" #include "prefetch.h"
#include "ranges.h" #include "ranges.h"
#include "seccomp.h"
#include "stalker.h" #include "stalker.h"
#include "stats.h" #include "stats.h"
#include "util.h" #include "util.h"
@ -177,6 +178,7 @@ __attribute__((visibility("default"))) void afl_frida_start(void) {
persistent_config(); persistent_config();
prefetch_config(); prefetch_config();
ranges_config(); ranges_config();
seccomp_config();
stalker_config(); stalker_config();
stats_config(); stats_config();
@ -191,6 +193,7 @@ __attribute__((visibility("default"))) void afl_frida_start(void) {
lib_init(); lib_init();
persistent_init(); persistent_init();
prefetch_init(); prefetch_init();
seccomp_init();
stalker_init(); stalker_init();
ranges_init(); ranges_init();
stats_init(); stats_init();

View File

@ -0,0 +1,157 @@
#include <execinfo.h>
#include <fcntl.h>
#include <linux/seccomp.h>
#include <stdio.h>
#include <unistd.h>
#include "frida-gumjs.h"
#include "debug.h"
#include "seccomp.h"
#include "util.h"
char *seccomp_filename = NULL;
static void seccomp_vprint(int fd, char *format, va_list ap) {
char buffer[4096] = {0};
int len;
if (vsnprintf(buffer, sizeof(buffer) - 1, format, ap) < 0) { return; }
len = strnlen(buffer, sizeof(buffer));
IGNORED_RETURN(write(fd, buffer, len));
}
void seccomp_print(char *format, ...) {
va_list ap;
va_start(ap, format);
seccomp_vprint(SECCOMP_OUTPUT_FILE_FD, format, ap);
va_end(ap);
}
static void seccomp_filter_callback(struct seccomp_notif * req,
struct seccomp_notif_resp *resp,
GumReturnAddressArray * frames) {
GumDebugSymbolDetails details = {0};
if (req->data.nr == SYS_OPENAT) {
seccomp_print("SYS_OPENAT: (%s)\n", (char *)req->data.args[1]);
}
seccomp_print(
"\nID (%#llx) for PID %d - %d (%s) [0x%llx 0x%llx 0x%llx 0x%llx 0x%llx "
"0x%llx ]\n",
req->id, req->pid, req->data.nr, seccomp_syscall_lookup(req->data.nr),
req->data.args[0], req->data.args[1], req->data.args[2],
req->data.args[3], req->data.args[4], req->data.args[5]);
seccomp_print("FRAMES: (%u)\n", frames->len);
char **syms = backtrace_symbols(frames->items, frames->len);
if (syms == NULL) { FATAL("Failed to get symbols"); }
for (guint i = 0; i < frames->len; i++) {
if (gum_symbol_details_from_address(frames->items[i], &details)) {
seccomp_print("\t%3d. %s!%s\n", i, details.module_name,
details.symbol_name);
} else {
seccomp_print("\t%3d. %s\n", i, syms[i]);
}
}
free(syms);
resp->error = 0;
resp->val = 0;
resp->id = req->id;
resp->flags = SECCOMP_USER_NOTIF_FLAG_CONTINUE;
}
static void seccomp_child(int signal_parent, void *ctx) {
int sock_fd = *((int *)ctx);
int fd = seccomp_socket_recv(sock_fd);
if (close(sock_fd) < 0) { FATAL("child - close"); }
seccomp_event_signal(signal_parent);
seccomp_filter_child_install();
seccomp_filter_run(fd, seccomp_filter_callback);
}
void seccomp_on_fork(void) {
int sock[2] = {-1, -1};
pid_t child = -1;
int child_fd = -1;
if (seccomp_filename == NULL) { return; }
seccomp_socket_create(sock);
seccomp_child_run(seccomp_child, sock, &child, &child_fd);
if (dup2(child_fd, SECCOMP_PARENT_EVENT_FD) < 0) { FATAL("dup2"); }
if (close(child_fd) < 0) { FATAL("seccomp_on_fork - close (1)"); }
if (close(sock[STDIN_FILENO]) < 0) { FATAL("grandparent - close (2)"); }
int fd = seccomp_filter_install(child);
seccomp_socket_send(sock[STDOUT_FILENO], fd);
if (close(sock[STDOUT_FILENO]) < 0) { FATAL("grandparent - close (3)"); }
if (close(fd) < 0) { FATAL("grandparent - close (4)"); }
seccomp_child_wait(SECCOMP_PARENT_EVENT_FD);
}
void seccomp_config(void) {
seccomp_filename = getenv("AFL_FRIDA_SECCOMP_FILE");
}
void seccomp_init(void) {
char *path = NULL;
int fd;
OKF("Seccomp - file [%s]", seccomp_filename);
if (seccomp_filename == NULL) { return; }
path = g_canonicalize_filename(seccomp_filename, g_get_current_dir());
OKF("Seccomp - path [%s]", path);
fd = open(path, O_RDWR | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
if (dup2(fd, SECCOMP_OUTPUT_FILE_FD) < 0) {
FATAL("Failed to duplicate seccomp output file");
}
if (close(fd) < 0) { FATAL("Failed to close seccomp output file fd"); }
g_free(path);
}

View File

@ -0,0 +1,28 @@
#include <stdbool.h>
#include <stdio.h>
#include "debug.h"
void seccomp_atomic_set(volatile bool *ptr, bool val) {
if (!__sync_bool_compare_and_swap(ptr, !val, val)) {
FATAL("Failed to set event");
}
}
bool seccomp_atomic_try_set(volatile bool *ptr, bool val) {
return __sync_bool_compare_and_swap(ptr, !val, val);
}
void seccomp_atomic_wait(volatile bool *ptr, bool val) {
while (!__sync_bool_compare_and_swap(ptr, val, !val))
;
}

View File

@ -0,0 +1,69 @@
#include <fcntl.h>
#include <sched.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/prctl.h>
#include <sys/types.h>
#include <unistd.h>
#include "debug.h"
#include "seccomp.h"
#define SECCOMP_CHILD_STACK_SIZE (1UL << 20)
typedef void (*seccomp_child_func_t)(int event_fd, void *ctx);
typedef struct {
seccomp_child_func_t func;
int event_fd;
void * ctx;
} seccomp_child_func_ctx_t;
static int seccomp_child_func(void *ctx) {
seccomp_child_func_ctx_t *args = (seccomp_child_func_ctx_t *)ctx;
args->func(args->event_fd, args->ctx);
_exit(0);
return 0;
}
void seccomp_child_run(seccomp_child_func_t child_func, void *ctx, pid_t *child,
int *event_fd) {
int fd = seccomp_event_create();
seccomp_child_func_ctx_t *child_ctx =
malloc(sizeof(seccomp_child_func_ctx_t));
child_ctx->func = child_func;
child_ctx->ctx = ctx;
child_ctx->event_fd = fd;
int flags = CLONE_VM | CLONE_UNTRACED;
char *stack =
(char *)mmap(NULL, SECCOMP_CHILD_STACK_SIZE, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (stack == MAP_FAILED) { FATAL("mmap"); }
pid_t child_pid = clone(seccomp_child_func, &stack[SECCOMP_CHILD_STACK_SIZE],
flags, child_ctx, NULL, NULL, NULL);
if (child_pid < 0) { FATAL("clone"); }
if (child != NULL) { *child = child_pid; }
if (event_fd != NULL) { *event_fd = fd; }
}
void seccomp_child_wait(int event_fd) {
seccomp_event_wait(event_fd);
seccomp_event_destroy(event_fd);
}

View File

@ -0,0 +1,45 @@
#include <stdint.h>
#include <stdio.h>
#include <sys/eventfd.h>
#include <unistd.h>
#include "debug.h"
#include "seccomp.h"
int seccomp_event_create(void) {
int fd = eventfd(0, 0);
if (fd < 0) { FATAL("seccomp_event_create"); }
return fd;
}
void seccomp_event_signal(int fd) {
uint64_t val = 1;
if (write(fd, &val, sizeof(uint64_t)) != sizeof(uint64_t)) {
FATAL("seccomp_event_signal");
}
}
void seccomp_event_wait(int fd) {
uint64_t val = 1;
if (read(fd, &val, sizeof(uint64_t)) != sizeof(uint64_t)) {
FATAL("seccomp_event_wait");
}
}
void seccomp_event_destroy(int fd) {
if (close(fd) < 0) { FATAL("seccomp_event_destroy"); }
}

View File

@ -0,0 +1,258 @@
#include <alloca.h>
#include <errno.h>
#include <execinfo.h>
#include <linux/filter.h>
#include <linux/seccomp.h>
#include <sys/ioctl.h>
#include <sys/prctl.h>
#include <sys/syscall.h>
#include <signal.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "debug.h"
#include "frida-gumjs.h"
#include "seccomp.h"
#include "util.h"
#define SECCOMP_FILTER_NUM_FRAMES 512
extern void gum_linux_parse_ucontext(const ucontext_t *uc, GumCpuContext *ctx);
static struct sock_filter filter[] = {
/* Allow us sendmsg to SECCOMP_FD */
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, nr))),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_sendmsg, 0, 3),
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
(offsetof(struct seccomp_data, args[0]))),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SECCOMP_SOCKET_SEND_FD, 0, 1),
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
/* Allow close */
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, nr))),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_close, 0, 1),
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
/* Allow sigreturn */
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, nr))),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_rt_sigreturn, 0, 1),
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
/* Allow sigprocmaksk */
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, nr))),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_rt_sigprocmask, 0, 1),
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
/* Allow console output*/
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, nr))),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_lseek, 2, 0),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_fstat, 1, 0),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_write, 0, 4),
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
(offsetof(struct seccomp_data, args[0]))),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, STDERR_FILENO, 1, 0),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, STDOUT_FILENO, 0, 1),
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
/* Allow waiting for the child */
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, nr))),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_read, 0, 3),
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
(offsetof(struct seccomp_data, args[0]))),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SECCOMP_PARENT_EVENT_FD, 0, 1),
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
/* Allow us to make anonymous maps */
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, nr))),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_mmap, 0, 3),
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
(offsetof(struct seccomp_data, args[4]))),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, -1, 0, 1),
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
/* Allow msync/mincore used by cmplog */
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, nr))),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_msync, 1, 0),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_mincore, 0, 1),
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
/*
* Allow tgkill (SIGKILL, SIGSTOP) used in persistent mode. Also
* allow seccomp to send (SIGUSR1) to the child to collect trace.
*/
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_tgkill, 0, 5),
BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
(offsetof(struct seccomp_data, args[2]))),
/* Used by seccomp to signal the child to collect a callstack*/
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SIGUSR1, 2, 0),
/* Used when handling faults */
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SIGKILL, 1, 0),
/* Used by target app of interest */
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SIGSTOP, 0, 1),
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
/* Allow getpid / gettid */
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, nr))),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_getpid, 1, 0),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_gettid, 0, 1),
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
/* Allow exit_group */
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, nr))),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_exit_group, 0, 1),
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
/* Allow brk */
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, nr))),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_brk, 0, 1),
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
/* Send the rest to user-mode to filter */
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_USER_NOTIF)};
static volatile bool seccomp_filter_parent_done = false;
static volatile bool seccomp_filter_child_done = false;
static pid_t seccomp_filter_child = -1;
static GumCpuContext seccomp_filter_cpu_context = {0};
static GumReturnAddressArray seccomp_filter_frames = {.len = 0, .items = {0}};
static GumBacktracer * seccomp_filter_backtracer = NULL;
static void seccomp_filter_child_handler(int sig, siginfo_t *info,
void *ucontext) {
GumCpuContext cpu_context;
if (seccomp_filter_backtracer == NULL) {
seccomp_filter_backtracer = gum_backtracer_make_fuzzy();
}
gum_backtracer_generate(seccomp_filter_backtracer,
&seccomp_filter_cpu_context, &seccomp_filter_frames);
seccomp_atomic_set(&seccomp_filter_child_done, true);
}
static void seccomp_filter_parent_handler(int sig, siginfo_t *info,
void *ucontext) {
UNUSED_PARAMETER(sig);
UNUSED_PARAMETER(info);
ucontext_t *uc = (ucontext_t *)ucontext;
gum_linux_parse_ucontext(uc, &seccomp_filter_cpu_context);
if (tgkill(seccomp_filter_child, seccomp_filter_child, SIGUSR1) < 0) {
FATAL("kill");
}
seccomp_atomic_wait(&seccomp_filter_child_done, true);
seccomp_atomic_set(&seccomp_filter_parent_done, true);
}
void seccomp_filter_child_install(void) {
const struct sigaction sa = {.sa_sigaction = seccomp_filter_child_handler,
.sa_flags = SA_SIGINFO | SA_RESTART};
if (sigaction(SIGUSR1, &sa, NULL) < 0) { FATAL("sigaction"); }
}
int seccomp_filter_install(pid_t child) {
seccomp_filter_child = child;
const struct sigaction sa = {.sa_sigaction = seccomp_filter_parent_handler,
.sa_flags = SA_SIGINFO | SA_RESTART};
struct sock_fprog filter_prog = {
.len = sizeof(filter) / sizeof(struct sock_filter), .filter = filter};
if (sigaction(SIGUSR1, &sa, NULL) < 0) { FATAL("sigaction"); }
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
FATAL("PR_SET_NO_NEW_PRIVS %d", errno);
}
int fd = syscall(SYS_seccomp, SECCOMP_SET_MODE_FILTER,
SECCOMP_FILTER_FLAG_NEW_LISTENER, &filter_prog);
if (fd < 0) { FATAL("SYS_seccomp %d", fd); }
return fd;
}
void seccomp_filter_run(int fd, seccomp_filter_callback_t callback) {
struct seccomp_notif * req = NULL;
struct seccomp_notif_resp *resp = NULL;
struct seccomp_notif_sizes sizes;
if (syscall(SYS_seccomp, SECCOMP_GET_NOTIF_SIZES, 0, &sizes) == -1) {
FATAL("seccomp-SECCOMP_GET_NOTIF_SIZES");
}
if (sizes.seccomp_notif != sizeof(struct seccomp_notif)) {
FATAL("size - seccomp_notif");
}
if (sizes.seccomp_notif_resp != sizeof(struct seccomp_notif_resp)) {
FATAL("size - seccomp_notif");
}
req = alloca(sizes.seccomp_notif);
resp = alloca(sizes.seccomp_notif_resp);
while (true) {
memset(req, 0, sizes.seccomp_notif);
if (ioctl(fd, SECCOMP_IOCTL_NOTIF_RECV, req) < 0) {
if (errno == EINTR) { continue; }
FATAL("SECCOMP_IOCTL_NOTIF_RECV: %d\n", fd);
}
if (seccomp_atomic_try_set(&seccomp_filter_parent_done, false)) {
callback(req, resp, &seccomp_filter_frames);
} else {
if (kill(req->pid, SIGUSR1) < 0) { FATAL("kill"); }
}
if (ioctl(fd, SECCOMP_IOCTL_NOTIF_SEND, resp) < 0) {
if (errno == ENOENT) { continue; }
OKF("SECCOMP_IOCTL_NOTIF_SEND");
continue;
}
}
}

View File

@ -0,0 +1,121 @@
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include "debug.h"
#include "seccomp.h"
union cmsg {
char buf[CMSG_SPACE(sizeof(int))];
struct cmsghdr hdr;
};
void seccomp_socket_create(int *sock) {
int tmp_sock[2] = {-1, -1};
if (socketpair(AF_UNIX, SOCK_STREAM, 0, tmp_sock) < 0) {
FATAL("socketpair");
}
if (dup2(tmp_sock[STDIN_FILENO], SECCOMP_SOCKET_RECV_FD) < 0) {
FATAL("seccomp_socket_create - dup2 (1)");
}
if (dup2(tmp_sock[STDOUT_FILENO], SECCOMP_SOCKET_SEND_FD) < 0) {
FATAL("seccomp_socket_create - dup2 (1)");
}
if (close(tmp_sock[STDIN_FILENO]) < 0) {
FATAL("seccomp_socket_create - close (1)");
}
if (close(tmp_sock[STDOUT_FILENO]) < 0) {
FATAL("seccomp_socket_create - close (2)");
}
sock[STDIN_FILENO] = SECCOMP_SOCKET_RECV_FD;
sock[STDOUT_FILENO] = SECCOMP_SOCKET_SEND_FD;
}
void seccomp_socket_send(int sockfd, int fd) {
int data = 12345;
struct iovec iov = {.iov_base = &data, .iov_len = sizeof(data)};
union cmsg control_msg = {.hdr = {
.cmsg_len = CMSG_LEN(sizeof(int)),
.cmsg_level = SOL_SOCKET,
.cmsg_type = SCM_RIGHTS,
}};
struct msghdr message = {.msg_control = control_msg.buf,
.msg_controllen = sizeof(control_msg.buf),
.msg_flags = 0,
.msg_iov = &iov,
.msg_iovlen = 1,
.msg_name = NULL,
.msg_namelen = 0};
memcpy(CMSG_DATA(&control_msg.hdr), &fd, sizeof(int));
if (sendmsg(sockfd, &message, 0) == -1) { FATAL("sendmsg"); }
}
int seccomp_socket_recv(int sockfd) {
int data;
struct iovec iov = {.iov_base = &data, .iov_len = sizeof(data)};
union cmsg control_msg = {0};
struct msghdr message = {.msg_control = control_msg.buf,
.msg_controllen = sizeof(control_msg.buf),
.msg_flags = 0,
.msg_iov = &iov,
.msg_iovlen = 1,
.msg_name = NULL,
.msg_namelen = 0};
int fd;
if (recvmsg(sockfd, &message, 0) < 0) { FATAL("recvmsg"); }
if (control_msg.hdr.cmsg_len != CMSG_LEN(sizeof(int))) {
FATAL("control_msg.hdr.cmsg_len");
}
if (control_msg.hdr.cmsg_level != SOL_SOCKET) {
FATAL("control_msg.hdr.cmsg_level");
}
if (control_msg.hdr.cmsg_type != SCM_RIGHTS) {
FATAL("control_msg.hdr.cmsg_type");
}
memcpy(&fd, CMSG_DATA(&control_msg.hdr), sizeof(int));
return fd;
}

View File

@ -0,0 +1,335 @@
#include <limits.h>
#include <stdio.h>
#include "debug.h"
#include "seccomp.h"
typedef struct {
int id;
char name[PATH_MAX];
} syscall_entry_t;
static syscall_entry_t seccomp_syscall_table[] = {
{SYS_READ, "SYS_READ"},
{SYS_WRITE, "SYS_WRITE"},
{SYS_OPEN, "SYS_OPEN"},
{SYS_CLOSE, "SYS_CLOSE"},
{SYS_STAT, "SYS_STAT"},
{SYS_FSTAT, "SYS_FSTAT"},
{SYS_LSTAT, "SYS_LSTAT"},
{SYS_POLL, "SYS_POLL"},
{SYS_LSEEK, "SYS_LSEEK"},
{SYS_MMAP, "SYS_MMAP"},
{SYS_MPROTECT, "SYS_MPROTECT"},
{SYS_MUNMAP, "SYS_MUNMAP"},
{SYS_BRK, "SYS_BRK"},
{SYS_RT_SIGACTION, "SYS_RT_SIGACTION"},
{SYS_RT_SIGPROCMASK, "SYS_RT_SIGPROCMASK"},
{SYS_RT_SIGRETURN, "SYS_RT_SIGRETURN"},
{SYS_IOCTL, "SYS_IOCTL"},
{SYS_PREAD64, "SYS_PREAD64"},
{SYS_PWRITE64, "SYS_PWRITE64"},
{SYS_READV, "SYS_READV"},
{SYS_WRITEV, "SYS_WRITEV"},
{SYS_ACCESS, "SYS_ACCESS"},
{SYS_PIPE, "SYS_PIPE"},
{SYS_SELECT, "SYS_SELECT"},
{SYS_SCHED_YIELD, "SYS_SCHED_YIELD"},
{SYS_MREMAP, "SYS_MREMAP"},
{SYS_MSYNC, "SYS_MSYNC"},
{SYS_MINCORE, "SYS_MINCORE"},
{SYS_MADVISE, "SYS_MADVISE"},
{SYS_SHMGET, "SYS_SHMGET"},
{SYS_SHMAT, "SYS_SHMAT"},
{SYS_SHMCTL, "SYS_SHMCTL"},
{SYS_DUP, "SYS_DUP"},
{SYS_DUP2, "SYS_DUP2"},
{SYS_PAUSE, "SYS_PAUSE"},
{SYS_NANOSLEEP, "SYS_NANOSLEEP"},
{SYS_GETITIMER, "SYS_GETITIMER"},
{SYS_ALARM, "SYS_ALARM"},
{SYS_SETITIMER, "SYS_SETITIMER"},
{SYS_GETPID, "SYS_GETPID"},
{SYS_SENDFILE, "SYS_SENDFILE"},
{SYS_SOCKET, "SYS_SOCKET"},
{SYS_CONNECT, "SYS_CONNECT"},
{SYS_ACCEPT, "SYS_ACCEPT"},
{SYS_SENDTO, "SYS_SENDTO"},
{SYS_RECVFROM, "SYS_RECVFROM"},
{SYS_SENDMSG, "SYS_SENDMSG"},
{SYS_RECVMSG, "SYS_RECVMSG"},
{SYS_SHUTDOWN, "SYS_SHUTDOWN"},
{SYS_BIND, "SYS_BIND"},
{SYS_LISTEN, "SYS_LISTEN"},
{SYS_GETSOCKNAME, "SYS_GETSOCKNAME"},
{SYS_GETPEERNAME, "SYS_GETPEERNAME"},
{SYS_SOCKETPAIR, "SYS_SOCKETPAIR"},
{SYS_SETSOCKOPT, "SYS_SETSOCKOPT"},
{SYS_GETSOCKOPT, "SYS_GETSOCKOPT"},
{SYS_CLONE, "SYS_CLONE"},
{SYS_FORK, "SYS_FORK"},
{SYS_VFORK, "SYS_VFORK"},
{SYS_EXECVE, "SYS_EXECVE"},
{SYS_EXIT, "SYS_EXIT"},
{SYS_WAIT4, "SYS_WAIT4"},
{SYS_KILL, "SYS_KILL"},
{SYS_UNAME, "SYS_UNAME"},
{SYS_SEMGET, "SYS_SEMGET"},
{SYS_SEMOP, "SYS_SEMOP"},
{SYS_SEMCTL, "SYS_SEMCTL"},
{SYS_SHMDT, "SYS_SHMDT"},
{SYS_MSGGET, "SYS_MSGGET"},
{SYS_MSGSND, "SYS_MSGSND"},
{SYS_MSGRCV, "SYS_MSGRCV"},
{SYS_MSGCTL, "SYS_MSGCTL"},
{SYS_FCNTL, "SYS_FCNTL"},
{SYS_FLOCK, "SYS_FLOCK"},
{SYS_FSYNC, "SYS_FSYNC"},
{SYS_FDATASYNC, "SYS_FDATASYNC"},
{SYS_TRUNCATE, "SYS_TRUNCATE"},
{SYS_FTRUNCATE, "SYS_FTRUNCATE"},
{SYS_GETDENTS, "SYS_GETDENTS"},
{SYS_GETCWD, "SYS_GETCWD"},
{SYS_CHDIR, "SYS_CHDIR"},
{SYS_FCHDIR, "SYS_FCHDIR"},
{SYS_RENAME, "SYS_RENAME"},
{SYS_MKDIR, "SYS_MKDIR"},
{SYS_RMDIR, "SYS_RMDIR"},
{SYS_CREAT, "SYS_CREAT"},
{SYS_LINK, "SYS_LINK"},
{SYS_UNLINK, "SYS_UNLINK"},
{SYS_SYMLINK, "SYS_SYMLINK"},
{SYS_READLINK, "SYS_READLINK"},
{SYS_CHMOD, "SYS_CHMOD"},
{SYS_FCHMOD, "SYS_FCHMOD"},
{SYS_CHOWN, "SYS_CHOWN"},
{SYS_FCHOWN, "SYS_FCHOWN"},
{SYS_LCHOWN, "SYS_LCHOWN"},
{SYS_UMASK, "SYS_UMASK"},
{SYS_GETTIMEOFDAY, "SYS_GETTIMEOFDAY"},
{SYS_GETRLIMIT, "SYS_GETRLIMIT"},
{SYS_GETRUSAGE, "SYS_GETRUSAGE"},
{SYS_SYSINFO, "SYS_SYSINFO"},
{SYS_TIMES, "SYS_TIMES"},
{SYS_PTRACE, "SYS_PTRACE"},
{SYS_GETUID, "SYS_GETUID"},
{SYS_SYSLOG, "SYS_SYSLOG"},
{SYS_GETGID, "SYS_GETGID"},
{SYS_SETUID, "SYS_SETUID"},
{SYS_SETGID, "SYS_SETGID"},
{SYS_GETEUID, "SYS_GETEUID"},
{SYS_GETEGID, "SYS_GETEGID"},
{SYS_SETPGID, "SYS_SETPGID"},
{SYS_GETPPID, "SYS_GETPPID"},
{SYS_GETPGRP, "SYS_GETPGRP"},
{SYS_SETSID, "SYS_SETSID"},
{SYS_SETREUID, "SYS_SETREUID"},
{SYS_SETREGID, "SYS_SETREGID"},
{SYS_GETGROUPS, "SYS_GETGROUPS"},
{SYS_SETGROUPS, "SYS_SETGROUPS"},
{SYS_SETRESUID, "SYS_SETRESUID"},
{SYS_GETRESUID, "SYS_GETRESUID"},
{SYS_SETRESGID, "SYS_SETRESGID"},
{SYS_GETRESGID, "SYS_GETRESGID"},
{SYS_GETPGID, "SYS_GETPGID"},
{SYS_SETFSUID, "SYS_SETFSUID"},
{SYS_SETFSGID, "SYS_SETFSGID"},
{SYS_GETSID, "SYS_GETSID"},
{SYS_CAPGET, "SYS_CAPGET"},
{SYS_CAPSET, "SYS_CAPSET"},
{SYS_RT_SIGPENDING, "SYS_RT_SIGPENDING"},
{SYS_RT_SIGTIMEDWAIT, "SYS_RT_SIGTIMEDWAIT"},
{SYS_RT_SIGQUEUEINFO, "SYS_RT_SIGQUEUEINFO"},
{SYS_RT_SIGSUSPEND, "SYS_RT_SIGSUSPEND"},
{SYS_SIGALTSTACK, "SYS_SIGALTSTACK"},
{SYS_UTIME, "SYS_UTIME"},
{SYS_MKNOD, "SYS_MKNOD"},
{SYS_USELIB, "SYS_USELIB"},
{SYS_PERSONALITY, "SYS_PERSONALITY"},
{SYS_USTAT, "SYS_USTAT"},
{SYS_STATFS, "SYS_STATFS"},
{SYS_FSTATFS, "SYS_FSTATFS"},
{SYS_SYSFS, "SYS_SYSFS"},
{SYS_GETPRIORITY, "SYS_GETPRIORITY"},
{SYS_SETPRIORITY, "SYS_SETPRIORITY"},
{SYS_SCHED_SETPARAM, "SYS_SCHED_SETPARAM"},
{SYS_SCHED_GETPARAM, "SYS_SCHED_GETPARAM"},
{SYS_SCHED_SETSCHEDULER, "SYS_SCHED_SETSCHEDULER"},
{SYS_SCHED_GETSCHEDULER, "SYS_SCHED_GETSCHEDULER"},
{SYS_SCHED_GET_PRIORITY_MAX, "SYS_SCHED_GET_PRIORITY_MAX"},
{SYS_SCHED_GET_PRIORITY_MIN, "SYS_SCHED_GET_PRIORITY_MIN"},
{SYS_SCHED_RR_GET_INTERVAL, "SYS_SCHED_RR_GET_INTERVAL"},
{SYS_MLOCK, "SYS_MLOCK"},
{SYS_MUNLOCK, "SYS_MUNLOCK"},
{SYS_MLOCKALL, "SYS_MLOCKALL"},
{SYS_MUNLOCKALL, "SYS_MUNLOCKALL"},
{SYS_VHANGUP, "SYS_VHANGUP"},
{SYS_MODIFY_LDT, "SYS_MODIFY_LDT"},
{SYS_PIVOT_ROOT, "SYS_PIVOT_ROOT"},
{SYS__SYSCTL, "SYS__SYSCTL"},
{SYS_PRCTL, "SYS_PRCTL"},
{SYS_ARCH_PRCTL, "SYS_ARCH_PRCTL"},
{SYS_ADJTIMEX, "SYS_ADJTIMEX"},
{SYS_SETRLIMIT, "SYS_SETRLIMIT"},
{SYS_CHROOT, "SYS_CHROOT"},
{SYS_SYNC, "SYS_SYNC"},
{SYS_ACCT, "SYS_ACCT"},
{SYS_SETTIMEOFDAY, "SYS_SETTIMEOFDAY"},
{SYS_MOUNT, "SYS_MOUNT"},
{SYS_UMOUNT2, "SYS_UMOUNT2"},
{SYS_SWAPON, "SYS_SWAPON"},
{SYS_SWAPOFF, "SYS_SWAPOFF"},
{SYS_REBOOT, "SYS_REBOOT"},
{SYS_SETHOSTNAME, "SYS_SETHOSTNAME"},
{SYS_SETDOMAINNAME, "SYS_SETDOMAINNAME"},
{SYS_IOPL, "SYS_IOPL"},
{SYS_IOPERM, "SYS_IOPERM"},
{SYS_CREATE_MODULE, "SYS_CREATE_MODULE"},
{SYS_INIT_MODULE, "SYS_INIT_MODULE"},
{SYS_DELETE_MODULE, "SYS_DELETE_MODULE"},
{SYS_GET_KERNEL_SYMS, "SYS_GET_KERNEL_SYMS"},
{SYS_QUERY_MODULE, "SYS_QUERY_MODULE"},
{SYS_QUOTACTL, "SYS_QUOTACTL"},
{SYS_NFSSERVCTL, "SYS_NFSSERVCTL"},
{SYS_GETPMSG, "SYS_GETPMSG"},
{SYS_PUTPMSG, "SYS_PUTPMSG"},
{SYS_AFS_SYSCALL, "SYS_AFS_SYSCALL"},
{SYS_TUXCALL, "SYS_TUXCALL"},
{SYS_SECURITY, "SYS_SECURITY"},
{SYS_GETTID, "SYS_GETTID"},
{SYS_READAHEAD, "SYS_READAHEAD"},
{SYS_SETXATTR, "SYS_SETXATTR"},
{SYS_LSETXATTR, "SYS_LSETXATTR"},
{SYS_FSETXATTR, "SYS_FSETXATTR"},
{SYS_GETXATTR, "SYS_GETXATTR"},
{SYS_LGETXATTR, "SYS_LGETXATTR"},
{SYS_FGETXATTR, "SYS_FGETXATTR"},
{SYS_LISTXATTR, "SYS_LISTXATTR"},
{SYS_LLISTXATTR, "SYS_LLISTXATTR"},
{SYS_FLISTXATTR, "SYS_FLISTXATTR"},
{SYS_REMOVEXATTR, "SYS_REMOVEXATTR"},
{SYS_LREMOVEXATTR, "SYS_LREMOVEXATTR"},
{SYS_FREMOVEXATTR, "SYS_FREMOVEXATTR"},
{SYS_TKILL, "SYS_TKILL"},
{SYS_TIME, "SYS_TIME"},
{SYS_FUTEX, "SYS_FUTEX"},
{SYS_SCHED_SETAFFINITY, "SYS_SCHED_SETAFFINITY"},
{SYS_SCHED_GETAFFINITY, "SYS_SCHED_GETAFFINITY"},
{SYS_SET_THREAD_AREA, "SYS_SET_THREAD_AREA"},
{SYS_IO_SETUP, "SYS_IO_SETUP"},
{SYS_IO_DESTROY, "SYS_IO_DESTROY"},
{SYS_IO_GETEVENTS, "SYS_IO_GETEVENTS"},
{SYS_IO_SUBMIT, "SYS_IO_SUBMIT"},
{SYS_IO_CANCEL, "SYS_IO_CANCEL"},
{SYS_GET_THREAD_AREA, "SYS_GET_THREAD_AREA"},
{SYS_LOOKUP_DCOOKIE, "SYS_LOOKUP_DCOOKIE"},
{SYS_EPOLL_CREATE, "SYS_EPOLL_CREATE"},
{SYS_EPOLL_CTL_OLD, "SYS_EPOLL_CTL_OLD"},
{SYS_EPOLL_WAIT_OLD, "SYS_EPOLL_WAIT_OLD"},
{SYS_REMAP_FILE_PAGES, "SYS_REMAP_FILE_PAGES"},
{SYS_GETDENTS64, "SYS_GETDENTS64"},
{SYS_SET_TID_ADDRESS, "SYS_SET_TID_ADDRESS"},
{SYS_RESTART_SYSCALL, "SYS_RESTART_SYSCALL"},
{SYS_SEMTIMEDOP, "SYS_SEMTIMEDOP"},
{SYS_FADVISE64, "SYS_FADVISE64"},
{SYS_TIMER_CREATE, "SYS_TIMER_CREATE"},
{SYS_TIMER_SETTIME, "SYS_TIMER_SETTIME"},
{SYS_TIMER_GETTIME, "SYS_TIMER_GETTIME"},
{SYS_TIMER_GETOVERRUN, "SYS_TIMER_GETOVERRUN"},
{SYS_TIMER_DELETE, "SYS_TIMER_DELETE"},
{SYS_CLOCK_SETTIME, "SYS_CLOCK_SETTIME"},
{SYS_CLOCK_GETTIME, "SYS_CLOCK_GETTIME"},
{SYS_CLOCK_GETRES, "SYS_CLOCK_GETRES"},
{SYS_CLOCK_NANOSLEEP, "SYS_CLOCK_NANOSLEEP"},
{SYS_EXIT_GROUP, "SYS_EXIT_GROUP"},
{SYS_EPOLL_WAIT, "SYS_EPOLL_WAIT"},
{SYS_EPOLL_CTL, "SYS_EPOLL_CTL"},
{SYS_TGKILL, "SYS_TGKILL"},
{SYS_UTIMES, "SYS_UTIMES"},
{SYS_VSERVER, "SYS_VSERVER"},
{SYS_MBIND, "SYS_MBIND"},
{SYS_SET_MEMPOLICY, "SYS_SET_MEMPOLICY"},
{SYS_GET_MEMPOLICY, "SYS_GET_MEMPOLICY"},
{SYS_MQ_OPEN, "SYS_MQ_OPEN"},
{SYS_MQ_UNLINK, "SYS_MQ_UNLINK"},
{SYS_MQ_TIMEDSEND, "SYS_MQ_TIMEDSEND"},
{SYS_MQ_TIMEDRECEIVE, "SYS_MQ_TIMEDRECEIVE"},
{SYS_MQ_NOTIFY, "SYS_MQ_NOTIFY"},
{SYS_MQ_GETSETATTR, "SYS_MQ_GETSETATTR"},
{SYS_KEXEC_LOAD, "SYS_KEXEC_LOAD"},
{SYS_WAITID, "SYS_WAITID"},
{SYS_ADD_KEY, "SYS_ADD_KEY"},
{SYS_REQUEST_KEY, "SYS_REQUEST_KEY"},
{SYS_KEYCTL, "SYS_KEYCTL"},
{SYS_IOPRIO_SET, "SYS_IOPRIO_SET"},
{SYS_IOPRIO_GET, "SYS_IOPRIO_GET"},
{SYS_INOTIFY_INIT, "SYS_INOTIFY_INIT"},
{SYS_INOTIFY_ADD_WATCH, "SYS_INOTIFY_ADD_WATCH"},
{SYS_INOTIFY_RM_WATCH, "SYS_INOTIFY_RM_WATCH"},
{SYS_MIGRATE_PAGES, "SYS_MIGRATE_PAGES"},
{SYS_OPENAT, "SYS_OPENAT"},
{SYS_MKDIRAT, "SYS_MKDIRAT"},
{SYS_MKNODAT, "SYS_MKNODAT"},
{SYS_FCHOWNAT, "SYS_FCHOWNAT"},
{SYS_FUTIMESAT, "SYS_FUTIMESAT"},
{SYS_NEWFSTATAT, "SYS_NEWFSTATAT"},
{SYS_UNLINKAT, "SYS_UNLINKAT"},
{SYS_RENAMEAT, "SYS_RENAMEAT"},
{SYS_LINKAT, "SYS_LINKAT"},
{SYS_SYMLINKAT, "SYS_SYMLINKAT"},
{SYS_READLINKAT, "SYS_READLINKAT"},
{SYS_FCHMODAT, "SYS_FCHMODAT"},
{SYS_FACCESSAT, "SYS_FACCESSAT"},
{SYS_PSELECT6, "SYS_PSELECT6"},
{SYS_PPOLL, "SYS_PPOLL"},
{SYS_UNSHARE, "SYS_UNSHARE"},
{SYS_SET_ROBUST_LIST, "SYS_SET_ROBUST_LIST"},
{SYS_GET_ROBUST_LIST, "SYS_GET_ROBUST_LIST"},
{SYS_SPLICE, "SYS_SPLICE"},
{SYS_TEE, "SYS_TEE"},
{SYS_SYNC_FILE_RANGE, "SYS_SYNC_FILE_RANGE"},
{SYS_VMSPLICE, "SYS_VMSPLICE"},
{SYS_MOVE_PAGES, "SYS_MOVE_PAGES"},
{SYS_UTIMENSAT, "SYS_UTIMENSAT"},
{SYS_EPOLL_PWAIT, "SYS_EPOLL_PWAIT"},
{SYS_SIGNALFD, "SYS_SIGNALFD"},
{SYS_TIMERFD_CREATE, "SYS_TIMERFD_CREATE"},
{SYS_EVENTFD, "SYS_EVENTFD"},
{SYS_FALLOCATE, "SYS_FALLOCATE"},
{SYS_TIMERFD_SETTIME, "SYS_TIMERFD_SETTIME"},
{SYS_TIMERFD_GETTIME, "SYS_TIMERFD_GETTIME"},
{SYS_ACCEPT4, "SYS_ACCEPT4"},
{SYS_SIGNALFD4, "SYS_SIGNALFD4"},
{SYS_EVENTFD2, "SYS_EVENTFD2"},
{SYS_EPOLL_CREATE1, "SYS_EPOLL_CREATE1"},
{SYS_DUP3, "SYS_DUP3"},
{SYS_PIPE2, "SYS_PIPE2"},
{SYS_INOTIFY_INIT1, "SYS_INOTIFY_INIT1"},
{SYS_PREADV, "SYS_PREADV"},
{SYS_PWRITEV, "SYS_PWRITEV"},
{SYS_RT_TGSIGQUEUEINFO, "SYS_RT_TGSIGQUEUEINFO"},
{SYS_PERF_EVENT_OPEN, "SYS_PERF_EVENT_OPEN"},
{SYS_RECVMMSG, "SYS_RECVMMSG"},
{SYS_FANOTIFY_INIT, "SYS_FANOTIFY_INIT"},
{SYS_FANOTIFY_MARK, "SYS_FANOTIFY_MARK"},
{SYS_PRLIMIT64, "SYS_PRLIMIT64"},
};
char *seccomp_syscall_lookup(int id) {
if (id < 0) { FATAL("Invalid id: %d", id); }
if ((uint32_t)id >= sizeof(seccomp_syscall_table) / sizeof(syscall_entry_t)) {
FATAL("Invalid id: %d", id);
}
return seccomp_syscall_table[id].name;
}

View File

@ -225,6 +225,15 @@ class Afl {
Afl.jsApiSetPrefetchDisable(); Afl.jsApiSetPrefetchDisable();
} }
/**
* See `AFL_FRIDA_SECCOMP_FILE`. This function takes a single `string` as
* an argument.
*/
public static setSeccompFile(file: string): void {
const buf = Memory.allocUtf8String(file);
Afl.jsApiSetSeccompFile(buf);
}
/* /*
* Set a function to be called for each instruction which is instrumented * Set a function to be called for each instruction which is instrumented
* by AFL FRIDA mode. * by AFL FRIDA mode.
@ -387,6 +396,11 @@ class Afl {
"void", "void",
[]); []);
private static readonly jsApiSetSeccompFile = Afl.jsApiGetFunction(
"js_api_set_seccomp_file",
"void",
["pointer"]);
private static readonly jsApiSetStalkerCallback = Afl.jsApiGetFunction( private static readonly jsApiSetStalkerCallback = Afl.jsApiGetFunction(
"js_api_set_stalker_callback", "js_api_set_stalker_callback",
"void", "void",

View File

@ -143,17 +143,9 @@ u32 count_non_255_bytes(afl_state_t *afl, u8 *mem) {
and replacing it with 0x80 or 0x01 depending on whether the tuple and replacing it with 0x80 or 0x01 depending on whether the tuple
is hit or not. Called on every new crash or timeout, should be is hit or not. Called on every new crash or timeout, should be
reasonably fast. */ reasonably fast. */
#define TIMES4(x) x, x, x, x
#define TIMES8(x) TIMES4(x), TIMES4(x)
#define TIMES16(x) TIMES8(x), TIMES8(x)
#define TIMES32(x) TIMES16(x), TIMES16(x)
#define TIMES64(x) TIMES32(x), TIMES32(x)
#define TIMES255(x) \
TIMES64(x), TIMES64(x), TIMES64(x), TIMES32(x), TIMES16(x), TIMES8(x), \
TIMES4(x), x, x, x
const u8 simplify_lookup[256] = { const u8 simplify_lookup[256] = {
[0] = 1, [1] = TIMES255(128) [0] = 1, [1 ... 255] = 128
}; };
@ -167,11 +159,11 @@ const u8 count_class_lookup8[256] = {
[1] = 1, [1] = 1,
[2] = 2, [2] = 2,
[3] = 4, [3] = 4,
[4] = TIMES4(8), [4 ... 7] = 8,
[8] = TIMES8(16), [8 ... 15] = 16,
[16] = TIMES16(32), [16 ... 31] = 32,
[32] = TIMES32(64), [32 ... 127] = 64,
[128] = TIMES64(128) [128 ... 255] = 128
}; };

View File

@ -43,6 +43,7 @@ int main(int argc, char **argv) {
printf("This will only crash with libdislocator: %s\n", buf); printf("This will only crash with libdislocator: %s\n", buf);
} else if (*(unsigned int *)input == 0xabadcafe) } else if (*(unsigned int *)input == 0xabadcafe)
printf("GG you eat cmp tokens for breakfast!\n"); printf("GG you eat cmp tokens for breakfast!\n");
else if (memcmp(cmpval, input, 8) == 0) else if (memcmp(cmpval, input, 8) == 0)
printf("local var memcmp works!\n"); printf("local var memcmp works!\n");

@ -1 +1 @@
Subproject commit c0e03d2c6b55a22025324f121746b41b1e756fb8 Subproject commit 019b871539fe9ed3f41d882385a8b02c243d49ad

View File

@ -170,3 +170,4 @@ static void plot_toggled(GtkWidget *caller, gpointer data) {
} }
} }