mirror of
https://github.com/netblue30/firejail.git
synced 2026-05-15 22:01:33 -06:00
seccomp: allow defining separate filters for 32-bit arch
System calls (names and numbers) are not exactly the same for 32 bit and 64 bit architectures. Let's allow defining separate filters for 32-bit arch using seccomp.32, seccomp.32.drop, seccomp.32.keep. This is useful for mixed 64/32 bit application environments like Steam and Wine. Implement protocol and mdwx filtering also for 32 bit arch. It's still better to block secondary archs completely if not needed. Lists of supported system calls are also updated. Warn if preload libraries would be needed due to trace, tracelog or postexecseccomp (seccomp.drop=execve etc), because a 32-bit dynamic linker does not understand the 64 bit preload libraries. Closes #3267. Signed-off-by: Topi Miettinen <toiwoton@gmail.com>
This commit is contained in:
parent
ec0a097a07
commit
88eadbf31f
29 changed files with 1330 additions and 5388 deletions
|
|
@ -3,7 +3,7 @@ MYLIBS = src/lib
|
|||
APPS = src/firejail src/firemon src/fsec-print src/fsec-optimize src/firecfg src/fnetfilter src/libtrace src/libtracelog src/ftee \
|
||||
src/faudit src/fnet src/fseccomp src/fbuilder src/fcopy src/fldd src/libpostexecseccomp src/profstats
|
||||
MANPAGES = firejail.1 firemon.1 firecfg.1 firejail-profile.5 firejail-login.5 firejail-users.5
|
||||
SECCOMP_FILTERS = seccomp seccomp.debug seccomp.32 seccomp.block_secondary seccomp.mdwx
|
||||
SECCOMP_FILTERS = seccomp seccomp.debug seccomp.32 seccomp.block_secondary seccomp.mdwx seccomp.mdwx.32
|
||||
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
|
|
@ -48,6 +48,7 @@ ifeq ($(HAVE_SECCOMP),-DHAVE_SECCOMP)
|
|||
src/fsec-optimize/fsec-optimize seccomp.32
|
||||
src/fseccomp/fseccomp secondary block seccomp.block_secondary
|
||||
src/fseccomp/fseccomp memory-deny-write-execute seccomp.mdwx
|
||||
src/fseccomp/fseccomp memory-deny-write-execute.32 seccomp.mdwx.32
|
||||
endif
|
||||
|
||||
clean:
|
||||
|
|
@ -109,6 +110,7 @@ ifeq ($(HAVE_SECCOMP),-DHAVE_SECCOMP)
|
|||
install -c -m 0644 seccomp.32 $(DESTDIR)/$(libdir)/firejail/.
|
||||
install -c -m 0644 seccomp.block_secondary $(DESTDIR)/$(libdir)/firejail/.
|
||||
install -c -m 0644 seccomp.mdwx $(DESTDIR)/$(libdir)/firejail/.
|
||||
install -c -m 0644 seccomp.mdwx.32 $(DESTDIR)/$(libdir)/firejail/.
|
||||
endif
|
||||
ifeq ($(HAVE_CONTRIB_INSTALL),yes)
|
||||
install -c -m 0755 contrib/fix_private-bin.py $(DESTDIR)/$(libdir)/firejail/.
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ _firejail()
|
|||
_init_completion -s || return
|
||||
|
||||
case $prev in
|
||||
--help|--version|-debug-caps|--debug-syscalls|--list|--tree|--top|--join|--shutdown)
|
||||
--help|--version|-debug-caps|--debug-syscalls|--debug-syscalls32|--list|--tree|--top|--join|--shutdown)
|
||||
return 0
|
||||
;;
|
||||
--profile)
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@ all: firejail
|
|||
|
||||
include ../common.mk
|
||||
|
||||
%.o : %.c $(H_FILE_LIST) ../include/rundefs.h ../include/common.h ../include/ldd_utils.h ../include/euid_common.h ../include/pid.h ../include/seccomp.h ../include/syscall.h ../include/firejail_user.h
|
||||
%.o : %.c $(H_FILE_LIST) ../include/rundefs.h ../include/common.h ../include/ldd_utils.h ../include/euid_common.h ../include/pid.h ../include/seccomp.h ../include/syscall_i386.h ../include/syscall_x86_64.h ../include/firejail_user.h
|
||||
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@
|
||||
|
||||
firejail: $(OBJS) ../lib/libnetlink.o ../lib/common.o ../lib/ldd_utils.o ../lib/firejail_user.o
|
||||
$(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/common.o ../lib/ldd_utils.o ../lib/firejail_user.o $(LIBS) $(EXTRA_LDFLAGS)
|
||||
firejail: $(OBJS) ../lib/libnetlink.o ../lib/common.o ../lib/ldd_utils.o ../lib/firejail_user.o ../lib/errno.o ../lib/syscall.o
|
||||
$(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/common.o ../lib/ldd_utils.o ../lib/firejail_user.o ../lib/errno.o ../lib/syscall.o $(LIBS) $(EXTRA_LDFLAGS)
|
||||
|
||||
clean:; rm -fr *.o firejail *.gcov *.gcda *.gcno *.plist
|
||||
|
||||
|
|
|
|||
|
|
@ -182,9 +182,9 @@ typedef struct config_t {
|
|||
char *dns4;
|
||||
|
||||
// seccomp
|
||||
char *seccomp_list;// optional seccomp list on top of default filter
|
||||
char *seccomp_list_drop; // seccomp drop list
|
||||
char *seccomp_list_keep; // seccomp keep list
|
||||
char *seccomp_list, *seccomp_list32; // optional seccomp list on top of default filter
|
||||
char *seccomp_list_drop, *seccomp_list_drop32; // seccomp drop list
|
||||
char *seccomp_list_keep, *seccomp_list_keep32; // seccomp keep list
|
||||
char *protocol; // protocol list
|
||||
|
||||
// rlimits
|
||||
|
|
@ -270,6 +270,7 @@ extern int arg_overlay_keep; // place overlay diff in a known directory
|
|||
extern int arg_overlay_reuse; // allow the reuse of overlays
|
||||
|
||||
extern int arg_seccomp; // enable default seccomp filter
|
||||
extern int arg_seccomp32; // enable default seccomp filter for 32 bit arch
|
||||
extern int arg_seccomp_postexec; // need postexec ld.preload library?
|
||||
extern int arg_seccomp_block_secondary; // block any secondary architectures
|
||||
|
||||
|
|
@ -568,8 +569,8 @@ void fs_private_home_list(void);
|
|||
char *seccomp_check_list(const char *str);
|
||||
int seccomp_install_filters(void);
|
||||
int seccomp_load(const char *fname);
|
||||
int seccomp_filter_drop(void);
|
||||
int seccomp_filter_keep(void);
|
||||
int seccomp_filter_drop(bool native);
|
||||
int seccomp_filter_keep(bool native);
|
||||
void seccomp_print_filter(pid_t pid);
|
||||
|
||||
// caps.c
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include "firejail.h"
|
||||
#include "../include/pid.h"
|
||||
#include "../include/firejail_user.h"
|
||||
#include "../include/syscall.h"
|
||||
#define _GNU_SOURCE
|
||||
#include <sys/utsname.h>
|
||||
#include <sched.h>
|
||||
|
|
@ -72,6 +73,7 @@ int arg_overlay_keep = 0; // place overlay diff in a known directory
|
|||
int arg_overlay_reuse = 0; // allow the reuse of overlays
|
||||
|
||||
int arg_seccomp = 0; // enable default seccomp filter
|
||||
int arg_seccomp32 = 0; // enable default seccomp filter for 32 bit arch
|
||||
int arg_seccomp_postexec = 0; // need postexec ld.preload library?
|
||||
int arg_seccomp_block_secondary = 0; // block any secondary architectures
|
||||
|
||||
|
|
@ -548,6 +550,14 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
|
|||
else
|
||||
exit_err_feature("seccomp");
|
||||
}
|
||||
else if (strcmp(argv[i], "--debug-syscalls32") == 0) {
|
||||
if (checkcfg(CFG_SECCOMP)) {
|
||||
int rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 2, PATH_FSECCOMP_MAIN, "debug-syscalls32");
|
||||
exit(rv);
|
||||
}
|
||||
else
|
||||
exit_err_feature("seccomp");
|
||||
}
|
||||
else if (strcmp(argv[i], "--debug-errnos") == 0) {
|
||||
if (checkcfg(CFG_SECCOMP)) {
|
||||
int rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 2, PATH_FSECCOMP_MAIN, "debug-errnos");
|
||||
|
|
@ -956,6 +966,18 @@ static void run_builder(int argc, char **argv) {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
void filter_add_errno(int fd, int syscall, int arg, void *ptrarg, bool native) {}
|
||||
|
||||
static int check_postexec(const char *list) {
|
||||
char *prelist, *postlist;
|
||||
|
||||
if (list) {
|
||||
syscalls_in_list(list, "@default-keep", -1, &prelist, &postlist, true);
|
||||
if (postlist)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
// Main program
|
||||
|
|
@ -1263,6 +1285,18 @@ int main(int argc, char **argv) {
|
|||
else
|
||||
exit_err_feature("seccomp");
|
||||
}
|
||||
else if (strncmp(argv[i], "--seccomp.32=", 13) == 0) {
|
||||
if (checkcfg(CFG_SECCOMP)) {
|
||||
if (arg_seccomp32) {
|
||||
fprintf(stderr, "Error: seccomp.32 already enabled\n");
|
||||
exit(1);
|
||||
}
|
||||
arg_seccomp32 = 1;
|
||||
cfg.seccomp_list32 = seccomp_check_list(argv[i] + 13);
|
||||
}
|
||||
else
|
||||
exit_err_feature("seccomp");
|
||||
}
|
||||
else if (strncmp(argv[i], "--seccomp.drop=", 15) == 0) {
|
||||
if (checkcfg(CFG_SECCOMP)) {
|
||||
if (arg_seccomp) {
|
||||
|
|
@ -1275,6 +1309,18 @@ int main(int argc, char **argv) {
|
|||
else
|
||||
exit_err_feature("seccomp");
|
||||
}
|
||||
else if (strncmp(argv[i], "--seccomp.32.drop=", 18) == 0) {
|
||||
if (checkcfg(CFG_SECCOMP)) {
|
||||
if (arg_seccomp32) {
|
||||
fprintf(stderr, "Error: seccomp.32 already enabled\n");
|
||||
exit(1);
|
||||
}
|
||||
arg_seccomp32 = 1;
|
||||
cfg.seccomp_list_drop32 = seccomp_check_list(argv[i] + 18);
|
||||
}
|
||||
else
|
||||
exit_err_feature("seccomp");
|
||||
}
|
||||
else if (strncmp(argv[i], "--seccomp.keep=", 15) == 0) {
|
||||
if (checkcfg(CFG_SECCOMP)) {
|
||||
if (arg_seccomp) {
|
||||
|
|
@ -1287,8 +1333,24 @@ int main(int argc, char **argv) {
|
|||
else
|
||||
exit_err_feature("seccomp");
|
||||
}
|
||||
else if (strncmp(argv[i], "--seccomp.32.keep=", 18) == 0) {
|
||||
if (checkcfg(CFG_SECCOMP)) {
|
||||
if (arg_seccomp32) {
|
||||
fprintf(stderr, "Error: seccomp.32 already enabled\n");
|
||||
exit(1);
|
||||
}
|
||||
arg_seccomp32 = 1;
|
||||
cfg.seccomp_list_keep32 = seccomp_check_list(argv[i] + 18);
|
||||
}
|
||||
else
|
||||
exit_err_feature("seccomp");
|
||||
}
|
||||
else if (strcmp(argv[i], "--seccomp.block-secondary") == 0) {
|
||||
if (checkcfg(CFG_SECCOMP)) {
|
||||
if (arg_seccomp32) {
|
||||
fprintf(stderr, "Error: seccomp.32 conflicts with block-secondary\n");
|
||||
exit(1);
|
||||
}
|
||||
arg_seccomp_block_secondary = 1;
|
||||
}
|
||||
else
|
||||
|
|
@ -2542,6 +2604,14 @@ int main(int argc, char **argv) {
|
|||
// check network configuration options - it will exit if anything went wrong
|
||||
net_check_cfg();
|
||||
|
||||
#ifdef HAVE_SECCOMP
|
||||
if (arg_seccomp)
|
||||
arg_seccomp_postexec = check_postexec(cfg.seccomp_list) || check_postexec(cfg.seccomp_list_drop);
|
||||
#endif
|
||||
bool need_preload = arg_trace || arg_tracelog || arg_seccomp_postexec;
|
||||
if (need_preload && (cfg.seccomp_list32 || cfg.seccomp_list_drop32 || cfg.seccomp_list_keep32))
|
||||
fwarning("preload libraries (trace, tracelog, postexecseccomp due to seccomp.drop=execve etc.) are incompatible with 32 bit filters\n");
|
||||
|
||||
// check and assign an IP address - for macvlan it will be done again in the sandbox!
|
||||
if (any_bridge_configured()) {
|
||||
EUID_ROOT();
|
||||
|
|
|
|||
|
|
@ -98,13 +98,16 @@ void preproc_mount_mnt_dir(void) {
|
|||
//copy default seccomp files
|
||||
copy_file(PATH_SECCOMP_32, RUN_SECCOMP_32, getuid(), getgid(), 0644); // root needed
|
||||
}
|
||||
if (arg_allow_debuggers)
|
||||
if (arg_allow_debuggers) {
|
||||
copy_file(PATH_SECCOMP_DEFAULT_DEBUG, RUN_SECCOMP_CFG, getuid(), getgid(), 0644); // root needed
|
||||
else
|
||||
copy_file(PATH_SECCOMP_DEBUG_32, RUN_SECCOMP_32, getuid(), getgid(), 0644); // root needed
|
||||
} else
|
||||
copy_file(PATH_SECCOMP_DEFAULT, RUN_SECCOMP_CFG, getuid(), getgid(), 0644); // root needed
|
||||
|
||||
if (arg_memory_deny_write_execute)
|
||||
if (arg_memory_deny_write_execute) {
|
||||
copy_file(PATH_SECCOMP_MDWX, RUN_SECCOMP_MDWX, getuid(), getgid(), 0644); // root needed
|
||||
copy_file(PATH_SECCOMP_MDWX_32, RUN_SECCOMP_MDWX_32, getuid(), getgid(), 0644); // root needed
|
||||
}
|
||||
// as root, create empty RUN_SECCOMP_PROTOCOL and RUN_SECCOMP_POSTEXEC files
|
||||
create_empty_file_as_root(RUN_SECCOMP_PROTOCOL, 0644);
|
||||
if (set_perms(RUN_SECCOMP_PROTOCOL, getuid(), getgid(), 0644))
|
||||
|
|
@ -112,6 +115,9 @@ void preproc_mount_mnt_dir(void) {
|
|||
create_empty_file_as_root(RUN_SECCOMP_POSTEXEC, 0644);
|
||||
if (set_perms(RUN_SECCOMP_POSTEXEC, getuid(), getgid(), 0644))
|
||||
errExit("set_perms");
|
||||
create_empty_file_as_root(RUN_SECCOMP_POSTEXEC_32, 0644);
|
||||
if (set_perms(RUN_SECCOMP_POSTEXEC_32, getuid(), getgid(), 0644))
|
||||
errExit("set_perms");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -788,6 +788,18 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
|
|||
|
||||
return 0;
|
||||
}
|
||||
if (strncmp(ptr, "seccomp.32 ", 11) == 0) {
|
||||
#ifdef HAVE_SECCOMP
|
||||
if (checkcfg(CFG_SECCOMP)) {
|
||||
arg_seccomp32 = 1;
|
||||
cfg.seccomp_list32 = seccomp_check_list(ptr + 11);
|
||||
}
|
||||
else if (!arg_quiet)
|
||||
warning_feature_disabled("seccomp");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strcmp(ptr, "seccomp.block-secondary") == 0) {
|
||||
#ifdef HAVE_SECCOMP
|
||||
|
|
@ -811,6 +823,17 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
|
|||
#endif
|
||||
return 0;
|
||||
}
|
||||
if (strncmp(ptr, "seccomp.32.drop ", 13) == 0) {
|
||||
#ifdef HAVE_SECCOMP
|
||||
if (checkcfg(CFG_SECCOMP)) {
|
||||
arg_seccomp32 = 1;
|
||||
cfg.seccomp_list_drop32 = seccomp_check_list(ptr + 13);
|
||||
}
|
||||
else
|
||||
warning_feature_disabled("seccomp");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
// seccomp keep list
|
||||
if (strncmp(ptr, "seccomp.keep ", 13) == 0) {
|
||||
|
|
@ -824,6 +847,17 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
|
|||
#endif
|
||||
return 0;
|
||||
}
|
||||
if (strncmp(ptr, "seccomp.32.keep ", 13) == 0) {
|
||||
#ifdef HAVE_SECCOMP
|
||||
if (checkcfg(CFG_SECCOMP)) {
|
||||
arg_seccomp32 = 1;
|
||||
cfg.seccomp_list_keep32 = seccomp_check_list(ptr + 13);
|
||||
}
|
||||
else
|
||||
warning_feature_disabled("seccomp");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
// memory deny write&execute
|
||||
if (strcmp(ptr, "memory-deny-write-execute") == 0) {
|
||||
|
|
|
|||
|
|
@ -793,8 +793,6 @@ int sandbox(void* sandbox_arg) {
|
|||
if (rv)
|
||||
exit(rv);
|
||||
}
|
||||
if (arg_seccomp && (cfg.seccomp_list || cfg.seccomp_list_drop || cfg.seccomp_list_keep))
|
||||
arg_seccomp_postexec = 1;
|
||||
#endif
|
||||
|
||||
// need ld.so.preload if tracing or seccomp with any non-default lists
|
||||
|
|
@ -1113,9 +1111,15 @@ int sandbox(void* sandbox_arg) {
|
|||
// if a keep list is available, disregard the drop list
|
||||
if (arg_seccomp == 1) {
|
||||
if (cfg.seccomp_list_keep)
|
||||
seccomp_filter_keep();
|
||||
seccomp_filter_keep(true);
|
||||
else
|
||||
seccomp_filter_drop();
|
||||
seccomp_filter_drop(true);
|
||||
}
|
||||
if (arg_seccomp32 == 1) {
|
||||
if (cfg.seccomp_list_keep32)
|
||||
seccomp_filter_keep(false);
|
||||
else
|
||||
seccomp_filter_drop(false);
|
||||
|
||||
}
|
||||
else { // clean seccomp files under /run/firejail/mnt
|
||||
|
|
@ -1128,9 +1132,11 @@ int sandbox(void* sandbox_arg) {
|
|||
if (arg_debug)
|
||||
printf("Install memory write&execute filter\n");
|
||||
seccomp_load(RUN_SECCOMP_MDWX); // install filter
|
||||
seccomp_load(RUN_SECCOMP_MDWX_32);
|
||||
}
|
||||
else {
|
||||
int rv = unlink(RUN_SECCOMP_MDWX);
|
||||
rv |= unlink(RUN_SECCOMP_MDWX_32);
|
||||
(void) rv;
|
||||
}
|
||||
// make seccomp filters read-only
|
||||
|
|
|
|||
|
|
@ -191,7 +191,17 @@ static void seccomp_filter_block_secondary(void) {
|
|||
}
|
||||
|
||||
// drop filter for seccomp option
|
||||
int seccomp_filter_drop(void) {
|
||||
int seccomp_filter_drop(bool native) {
|
||||
const char *filter, *postexec_filter;
|
||||
|
||||
if (native) {
|
||||
filter = RUN_SECCOMP_CFG;
|
||||
postexec_filter = RUN_SECCOMP_POSTEXEC;
|
||||
} else {
|
||||
filter = RUN_SECCOMP_32;
|
||||
postexec_filter = RUN_SECCOMP_POSTEXEC_32;
|
||||
}
|
||||
|
||||
// if we have multiple seccomp commands, only one of them is executed
|
||||
// in the following order:
|
||||
// - seccomp.drop list
|
||||
|
|
@ -224,19 +234,28 @@ int seccomp_filter_drop(void) {
|
|||
if (arg_debug)
|
||||
printf("Build default+drop seccomp filter\n");
|
||||
|
||||
const char *command, *list;
|
||||
if (native) {
|
||||
command = "default";
|
||||
list = cfg.seccomp_list;
|
||||
} else {
|
||||
command = "default32";
|
||||
list = cfg.seccomp_list32;
|
||||
}
|
||||
|
||||
// build the seccomp filter as a regular user
|
||||
int rv;
|
||||
if (arg_allow_debuggers)
|
||||
rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 7,
|
||||
PATH_FSECCOMP, "default", "drop", RUN_SECCOMP_CFG, RUN_SECCOMP_POSTEXEC, cfg.seccomp_list, "allow-debuggers");
|
||||
PATH_FSECCOMP, command, "drop", filter, postexec_filter, list, "allow-debuggers");
|
||||
else
|
||||
rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 6,
|
||||
PATH_FSECCOMP, "default", "drop", RUN_SECCOMP_CFG, RUN_SECCOMP_POSTEXEC, cfg.seccomp_list);
|
||||
PATH_FSECCOMP, command, "drop", filter, postexec_filter, list);
|
||||
if (rv)
|
||||
exit(rv);
|
||||
|
||||
// optimize the new filter
|
||||
rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 2, PATH_FSEC_OPTIMIZE, RUN_SECCOMP_CFG);
|
||||
rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 2, PATH_FSEC_OPTIMIZE, filter);
|
||||
if (rv)
|
||||
exit(rv);
|
||||
}
|
||||
|
|
@ -250,36 +269,45 @@ int seccomp_filter_drop(void) {
|
|||
if (arg_debug)
|
||||
printf("Build drop seccomp filter\n");
|
||||
|
||||
const char *command, *list;
|
||||
if (native) {
|
||||
command = "drop";
|
||||
list = cfg.seccomp_list_drop;
|
||||
} else {
|
||||
command = "drop32";
|
||||
list = cfg.seccomp_list_drop32;
|
||||
}
|
||||
|
||||
// build the seccomp filter as a regular user
|
||||
int rv;
|
||||
if (arg_allow_debuggers)
|
||||
rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 6,
|
||||
PATH_FSECCOMP, "drop", RUN_SECCOMP_CFG, RUN_SECCOMP_POSTEXEC, cfg.seccomp_list_drop, "allow-debuggers");
|
||||
PATH_FSECCOMP, command, filter, postexec_filter, list, "allow-debuggers");
|
||||
else
|
||||
rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 5,
|
||||
PATH_FSECCOMP, "drop", RUN_SECCOMP_CFG, RUN_SECCOMP_POSTEXEC, cfg.seccomp_list_drop);
|
||||
PATH_FSECCOMP, command, filter, postexec_filter, list);
|
||||
|
||||
if (rv)
|
||||
exit(rv);
|
||||
|
||||
// optimize the drop filter
|
||||
rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 2, PATH_FSEC_OPTIMIZE, RUN_SECCOMP_CFG);
|
||||
rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 2, PATH_FSEC_OPTIMIZE, filter);
|
||||
if (rv)
|
||||
exit(rv);
|
||||
}
|
||||
|
||||
// load the filter
|
||||
if (seccomp_load(RUN_SECCOMP_CFG) == 0) {
|
||||
if (seccomp_load(filter) == 0) {
|
||||
if (arg_debug)
|
||||
printf("seccomp filter configured\n");
|
||||
}
|
||||
|
||||
if (arg_debug && access(PATH_FSEC_PRINT, X_OK) == 0) {
|
||||
struct stat st;
|
||||
if (stat(RUN_SECCOMP_POSTEXEC, &st) != -1 && st.st_size != 0) {
|
||||
printf("configuring postexec seccomp filter in %s\n", RUN_SECCOMP_POSTEXEC);
|
||||
if (stat(postexec_filter, &st) != -1 && st.st_size != 0) {
|
||||
printf("configuring postexec seccomp filter in %s\n", postexec_filter);
|
||||
sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 2,
|
||||
PATH_FSEC_PRINT, RUN_SECCOMP_POSTEXEC);
|
||||
PATH_FSEC_PRINT, postexec_filter);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -287,7 +315,7 @@ int seccomp_filter_drop(void) {
|
|||
}
|
||||
|
||||
// keep filter for seccomp option
|
||||
int seccomp_filter_keep(void) {
|
||||
int seccomp_filter_keep(bool native) {
|
||||
// secondary filters are not installed except when secondary
|
||||
// architectures are explicitly blocked
|
||||
if (arg_seccomp_block_secondary)
|
||||
|
|
@ -296,9 +324,22 @@ int seccomp_filter_keep(void) {
|
|||
if (arg_debug)
|
||||
printf("Build keep seccomp filter\n");
|
||||
|
||||
const char *command, *filter, *postexec_filter, *list;
|
||||
if (native) {
|
||||
command = "keep";
|
||||
filter = RUN_SECCOMP_CFG;
|
||||
postexec_filter = RUN_SECCOMP_POSTEXEC;
|
||||
list = cfg.seccomp_list_keep;
|
||||
} else {
|
||||
command = "keep32";
|
||||
filter = RUN_SECCOMP_32;
|
||||
postexec_filter = RUN_SECCOMP_POSTEXEC_32;
|
||||
list = cfg.seccomp_list_keep32;
|
||||
}
|
||||
|
||||
// build the seccomp filter as a regular user
|
||||
int rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 5,
|
||||
PATH_FSECCOMP, "keep", RUN_SECCOMP_CFG, RUN_SECCOMP_POSTEXEC, cfg.seccomp_list_keep);
|
||||
PATH_FSECCOMP, "keep", filter, postexec_filter, list);
|
||||
|
||||
if (rv) {
|
||||
fprintf(stderr, "Error: cannot configure seccomp filter\n");
|
||||
|
|
@ -309,17 +350,17 @@ int seccomp_filter_keep(void) {
|
|||
printf("seccomp filter configured\n");
|
||||
|
||||
// load the filter
|
||||
if (seccomp_load(RUN_SECCOMP_CFG) == 0) {
|
||||
if (seccomp_load(filter) == 0) {
|
||||
if (arg_debug)
|
||||
printf("seccomp filter configured\n");
|
||||
}
|
||||
|
||||
if (arg_debug && access(PATH_FSEC_PRINT, X_OK) == 0) {
|
||||
struct stat st;
|
||||
if (stat(RUN_SECCOMP_POSTEXEC, &st) != -1 && st.st_size != 0) {
|
||||
printf("configuring postexec seccomp filter in %s\n", RUN_SECCOMP_POSTEXEC);
|
||||
if (stat(postexec_filter, &st) != -1 && st.st_size != 0) {
|
||||
printf("configuring postexec seccomp filter in %s\n", postexec_filter);
|
||||
sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 2,
|
||||
PATH_FSEC_PRINT, RUN_SECCOMP_POSTEXEC);
|
||||
PATH_FSEC_PRINT, postexec_filter);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ static char *usage_str =
|
|||
" --debug-private-lib - debug for --private-lib option.\n"
|
||||
" --debug-protocols - print all recognized protocols.\n"
|
||||
" --debug-syscalls - print all recognized system calls.\n"
|
||||
" --debug-syscalls32 - print all recognized 32 bit system calls.\n"
|
||||
#ifdef HAVE_WHITELIST
|
||||
" --debug-whitelists - debug whitelisting.\n"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ static int pid_is_firejail(pid_t pid) {
|
|||
"apparmor.print", "caps.print", "cpu.print", "dns.print", "fs.print", "netfilter.print",
|
||||
"netfilter6.print", "profile.print", "protocol.print", "seccomp.print",
|
||||
// debug
|
||||
"debug-caps", "debug-errnos", "debug-protocols", "debug-syscalls",
|
||||
"debug-caps", "debug-errnos", "debug-protocols", "debug-syscalls", "debug-syscalls32",
|
||||
// file transfer
|
||||
"ls", "get", "put",
|
||||
// stats
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ include ../common.mk
|
|||
%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/seccomp.h ../include/syscall.h
|
||||
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@
|
||||
|
||||
fsec-print: $(OBJS) ../lib/libnetlink.o
|
||||
$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) $(EXTRA_LDFLAGS)
|
||||
fsec-print: $(OBJS) ../lib/libnetlink.o ../lib/errno.o ../lib/syscall.o
|
||||
$(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/errno.o ../lib/syscall.o $(LIBS) $(EXTRA_LDFLAGS)
|
||||
|
||||
clean:; rm -fr *.o fsec-print *.gcov *.gcda *.gcno *.plist
|
||||
|
||||
|
|
|
|||
|
|
@ -21,12 +21,10 @@
|
|||
#define FSEC_PRINT_H
|
||||
#include "../include/common.h"
|
||||
#include "../include/seccomp.h"
|
||||
#include "../include/syscall.h"
|
||||
#include <sys/mman.h>
|
||||
|
||||
// print.c
|
||||
void print(struct sock_filter *filter, int entries);
|
||||
|
||||
// syscall_list.c
|
||||
const char *syscall_find_nr(int nr);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@ static void usage(void) {
|
|||
printf("\tfsec-print file - disassemble seccomp filter\n");
|
||||
}
|
||||
|
||||
int arg_quiet = 0;
|
||||
void filter_add_errno(int fd, int syscall, int arg, void *ptrarg, bool native) {}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
#if 0
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2014-2020 Firejail Authors
|
||||
*
|
||||
* This file is part of firejail project
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#include "fsec_print.h"
|
||||
#include <sys/syscall.h>
|
||||
|
||||
typedef struct {
|
||||
const char * const name;
|
||||
int nr;
|
||||
} SyscallEntry;
|
||||
|
||||
static const SyscallEntry syslist[] = {
|
||||
//
|
||||
// code generated using tools/extract-syscall
|
||||
//
|
||||
#include "../include/syscall.h"
|
||||
//
|
||||
// end of generated code
|
||||
//
|
||||
}; // end of syslist
|
||||
|
||||
const char *syscall_find_nr(int nr) {
|
||||
int i;
|
||||
int elems = sizeof(syslist) / sizeof(syslist[0]);
|
||||
for (i = 0; i < elems; i++) {
|
||||
if (nr == syslist[i].nr)
|
||||
return syslist[i].name;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -5,8 +5,8 @@ include ../common.mk
|
|||
%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/syscall.h
|
||||
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@
|
||||
|
||||
fseccomp: $(OBJS)
|
||||
$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) $(EXTRA_LDFLAGS)
|
||||
fseccomp: $(OBJS) ../lib/errno.o ../lib/syscall.o
|
||||
$(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/errno.o ../lib/syscall.o $(LIBS) $(EXTRA_LDFLAGS)
|
||||
|
||||
clean:; rm -fr *.o fseccomp *.gcov *.gcda *.gcno *.plist
|
||||
|
||||
|
|
|
|||
|
|
@ -24,21 +24,11 @@
|
|||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "../include/common.h"
|
||||
#include "../include/syscall.h"
|
||||
|
||||
// main.c
|
||||
extern int arg_quiet;
|
||||
|
||||
// syscall.c
|
||||
void syscall_print(void);
|
||||
int syscall_check_list(const char *slist, void (*callback)(int fd, int syscall, int arg, void *ptrarg), int fd, int arg, void *ptrarg);
|
||||
const char *syscall_find_nr(int nr);
|
||||
void syscalls_in_list(const char *list, const char *slist, int fd, char **prelist, char **postlist);
|
||||
|
||||
// errno.c
|
||||
void errno_print(void);
|
||||
int errno_find_name(const char *name);
|
||||
char *errno_find_nr(int nr);
|
||||
|
||||
// protocol.c
|
||||
void protocol_print(void);
|
||||
void protocol_build_filter(const char *prlist, const char *fname);
|
||||
|
|
@ -49,27 +39,27 @@ void seccomp_secondary_32(const char *fname);
|
|||
void seccomp_secondary_block(const char *fname);
|
||||
|
||||
// seccomp_file.c
|
||||
void write_to_file(int fd, const void *data, int size);
|
||||
void filter_init(int fd);
|
||||
void filter_add_whitelist(int fd, int syscall, int arg, void *ptrarg);
|
||||
void filter_add_whitelist_for_excluded(int fd, int syscall, int arg, void *ptrarg);
|
||||
void filter_add_blacklist(int fd, int syscall, int arg, void *ptrarg);
|
||||
void filter_add_blacklist_for_excluded(int fd, int syscall, int arg, void *ptrarg);
|
||||
void filter_add_errno(int fd, int syscall, int arg, void *ptrarg);
|
||||
void write_to_file(int fd, const void *data, size_t size);
|
||||
void filter_init(int fd, bool native);
|
||||
void filter_add_whitelist(int fd, int syscall, int arg, void *ptrarg, bool native);
|
||||
void filter_add_whitelist_for_excluded(int fd, int syscall, int arg, void *ptrarg, bool native);
|
||||
void filter_add_blacklist(int fd, int syscall, int arg, void *ptrarg, bool native);
|
||||
void filter_add_blacklist_for_excluded(int fd, int syscall, int arg, void *ptrarg, bool native);
|
||||
void filter_end_blacklist(int fd);
|
||||
void filter_end_whitelist(int fd);
|
||||
|
||||
// seccomp.c
|
||||
// default list
|
||||
void seccomp_default(const char *fname, int allow_debuggers);
|
||||
void seccomp_default(const char *fname, int allow_debuggers, bool native);
|
||||
// drop list
|
||||
void seccomp_drop(const char *fname1, const char *fname2, char *list, int allow_debuggers);
|
||||
void seccomp_drop(const char *fname1, const char *fname2, char *list, int allow_debuggers, bool native);
|
||||
// default+drop list
|
||||
void seccomp_default_drop(const char *fname1, const char *fname2, char *list, int allow_debuggers);
|
||||
void seccomp_default_drop(const char *fname1, const char *fname2, char *list, int allow_debuggers, bool native);
|
||||
// whitelisted filter
|
||||
void seccomp_keep(const char *fname1, const char *fname2, char *list);
|
||||
void seccomp_keep(const char *fname1, const char *fname2, char *list, bool native);
|
||||
// block writable and executable memory
|
||||
void memory_deny_write_execute(const char *fname);
|
||||
void memory_deny_write_execute_32(const char *fname);
|
||||
|
||||
// seccomp_print
|
||||
void filter_print(const char *fname);
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ int arg_quiet = 0;
|
|||
static void usage(void) {
|
||||
printf("Usage:\n");
|
||||
printf("\tfseccomp debug-syscalls\n");
|
||||
printf("\tfseccomp debug-syscalls32\n");
|
||||
printf("\tfseccomp debug-errnos\n");
|
||||
printf("\tfseccomp debug-protocols\n");
|
||||
printf("\tfseccomp protocol build list file\n");
|
||||
|
|
@ -31,12 +32,20 @@ static void usage(void) {
|
|||
printf("\tfseccomp secondary block file\n");
|
||||
printf("\tfseccomp default file\n");
|
||||
printf("\tfseccomp default file allow-debuggers\n");
|
||||
printf("\tfseccomp default32 file\n");
|
||||
printf("\tfseccomp default32 file allow-debuggers\n");
|
||||
printf("\tfseccomp drop file1 file2 list\n");
|
||||
printf("\tfseccomp drop file1 file2 list allow-debuggers\n");
|
||||
printf("\tfseccomp drop32 file1 file2 list\n");
|
||||
printf("\tfseccomp drop32 file1 file2 list allow-debuggers\n");
|
||||
printf("\tfseccomp default drop file1 file2 list\n");
|
||||
printf("\tfseccomp default drop file1 file2 list allow-debuggers\n");
|
||||
printf("\tfseccomp default32 drop file1 file2 list\n");
|
||||
printf("\tfseccomp default32 drop file1 file2 list allow-debuggers\n");
|
||||
printf("\tfseccomp keep file1 file2 list\n");
|
||||
printf("\tfseccomp keep32 file1 file2 list\n");
|
||||
printf("\tfseccomp memory-deny-write-execute file\n");
|
||||
printf("\tfseccomp memory-deny-write-execute.32 file\n");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
|
@ -64,6 +73,8 @@ printf("\n");
|
|||
}
|
||||
else if (argc == 2 && strcmp(argv[1], "debug-syscalls") == 0)
|
||||
syscall_print();
|
||||
else if (argc == 2 && strcmp(argv[1], "debug-syscalls32") == 0)
|
||||
syscall_print_32();
|
||||
else if (argc == 2 && strcmp(argv[1], "debug-errnos") == 0)
|
||||
errno_print();
|
||||
else if (argc == 2 && strcmp(argv[1], "debug-protocols") == 0)
|
||||
|
|
@ -75,21 +86,37 @@ printf("\n");
|
|||
else if (argc == 4 && strcmp(argv[1], "secondary") == 0 && strcmp(argv[2], "block") == 0)
|
||||
seccomp_secondary_block(argv[3]);
|
||||
else if (argc == 3 && strcmp(argv[1], "default") == 0)
|
||||
seccomp_default(argv[2], 0);
|
||||
seccomp_default(argv[2], 0, true);
|
||||
else if (argc == 4 && strcmp(argv[1], "default") == 0 && strcmp(argv[3], "allow-debuggers") == 0)
|
||||
seccomp_default(argv[2], 1);
|
||||
seccomp_default(argv[2], 1, true);
|
||||
else if (argc == 3 && strcmp(argv[1], "default32") == 0)
|
||||
seccomp_default(argv[2], 0, false);
|
||||
else if (argc == 4 && strcmp(argv[1], "default32") == 0 && strcmp(argv[3], "allow-debuggers") == 0)
|
||||
seccomp_default(argv[2], 1, false);
|
||||
else if (argc == 5 && strcmp(argv[1], "drop") == 0)
|
||||
seccomp_drop(argv[2], argv[3], argv[4], 0);
|
||||
seccomp_drop(argv[2], argv[3], argv[4], 0, true);
|
||||
else if (argc == 6 && strcmp(argv[1], "drop") == 0 && strcmp(argv[5], "allow-debuggers") == 0)
|
||||
seccomp_drop(argv[2], argv[3], argv[4], 1);
|
||||
seccomp_drop(argv[2], argv[3], argv[4], 1, true);
|
||||
else if (argc == 5 && strcmp(argv[1], "drop32") == 0)
|
||||
seccomp_drop(argv[2], argv[3], argv[4], 0, false);
|
||||
else if (argc == 6 && strcmp(argv[1], "drop32") == 0 && strcmp(argv[5], "allow-debuggers") == 0)
|
||||
seccomp_drop(argv[2], argv[3], argv[4], 1, false);
|
||||
else if (argc == 6 && strcmp(argv[1], "default") == 0 && strcmp(argv[2], "drop") == 0)
|
||||
seccomp_default_drop(argv[3], argv[4], argv[5], 0);
|
||||
seccomp_default_drop(argv[3], argv[4], argv[5], 0, true);
|
||||
else if (argc == 7 && strcmp(argv[1], "default") == 0 && strcmp(argv[2], "drop") == 0 && strcmp(argv[6], "allow-debuggers") == 0)
|
||||
seccomp_default_drop(argv[3], argv[4], argv[5], 1);
|
||||
seccomp_default_drop(argv[3], argv[4], argv[5], 1, true);
|
||||
else if (argc == 6 && strcmp(argv[1], "default32") == 0 && strcmp(argv[2], "drop") == 0)
|
||||
seccomp_default_drop(argv[3], argv[4], argv[5], 0, false);
|
||||
else if (argc == 7 && strcmp(argv[1], "default32") == 0 && strcmp(argv[2], "drop") == 0 && strcmp(argv[6], "allow-debuggers") == 0)
|
||||
seccomp_default_drop(argv[3], argv[4], argv[5], 1, false);
|
||||
else if (argc == 5 && strcmp(argv[1], "keep") == 0)
|
||||
seccomp_keep(argv[2], argv[3], argv[4]);
|
||||
seccomp_keep(argv[2], argv[3], argv[4], true);
|
||||
else if (argc == 5 && strcmp(argv[1], "keep32") == 0)
|
||||
seccomp_keep(argv[2], argv[3], argv[4], false);
|
||||
else if (argc == 3 && strcmp(argv[1], "memory-deny-write-execute") == 0)
|
||||
memory_deny_write_execute(argv[2]);
|
||||
else if (argc == 3 && strcmp(argv[1], "memory-deny-write-execute.32") == 0)
|
||||
memory_deny_write_execute_32(argv[2]);
|
||||
else {
|
||||
fprintf(stderr, "Error fseccomp: invalid arguments\n");
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -122,10 +122,23 @@ void protocol_build_filter(const char *prlist, const char *fname) {
|
|||
|
||||
// header
|
||||
struct sock_filter filter_start[] = {
|
||||
VALIDATE_ARCHITECTURE,
|
||||
EXAMINE_SYSCALL,
|
||||
ONLY(SYS_socket),
|
||||
EXAMINE_ARGUMENT(0)
|
||||
#if defined __x86_64__
|
||||
/* check for native arch */
|
||||
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, (offsetof(struct seccomp_data, arch))),
|
||||
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ARCH_NR, 1 + 2 + 1, 0),
|
||||
/* i386 filter */
|
||||
EXAMINE_SYSCALL, // 1
|
||||
// checking SYS_socket only: filtering SYS_socketcall not possible with seccomp
|
||||
ONLY(359), // 1 + 2
|
||||
BPF_JUMP(BPF_JMP+BPF_JA+BPF_K, (3 + 1 + 2), 0, 0), // 1 + 2 + 1
|
||||
#else
|
||||
#warning 32 bit protocol filter not implemented yet for your architecture
|
||||
#endif
|
||||
VALIDATE_ARCHITECTURE, // 3
|
||||
EXAMINE_SYSCALL, // 3 + 1
|
||||
ONLY(SYS_socket), // 3 + 1 + 2
|
||||
|
||||
EXAMINE_ARGUMENT(0) // 3 + 1 + 2 + 1
|
||||
};
|
||||
memcpy(ptr, &filter_start[0], sizeof(filter_start));
|
||||
ptr += sizeof(filter_start);
|
||||
|
|
|
|||
|
|
@ -24,12 +24,12 @@
|
|||
#include <sys/syscall.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
static void add_default_list(int fd, int allow_debuggers) {
|
||||
static void add_default_list(int fd, int allow_debuggers, bool native) {
|
||||
int r;
|
||||
if (!allow_debuggers)
|
||||
r = syscall_check_list("@default-nodebuggers", filter_add_blacklist, fd, 0, NULL);
|
||||
r = syscall_check_list("@default-nodebuggers", filter_add_blacklist, fd, 0, NULL, native);
|
||||
else
|
||||
r = syscall_check_list("@default", filter_add_blacklist, fd, 0, NULL);
|
||||
r = syscall_check_list("@default", filter_add_blacklist, fd, 0, NULL, native);
|
||||
|
||||
assert(r == 0);
|
||||
//#ifdef SYS_mknod - emoved in 0.9.29 - it breaks Zotero extension
|
||||
|
|
@ -46,7 +46,7 @@ static void add_default_list(int fd, int allow_debuggers) {
|
|||
}
|
||||
|
||||
// default list
|
||||
void seccomp_default(const char *fname, int allow_debuggers) {
|
||||
void seccomp_default(const char *fname, int allow_debuggers, bool native) {
|
||||
assert(fname);
|
||||
|
||||
// open file
|
||||
|
|
@ -57,8 +57,8 @@ void seccomp_default(const char *fname, int allow_debuggers) {
|
|||
}
|
||||
|
||||
// build filter (no post-exec filter needed because default list is fine for us)
|
||||
filter_init(fd);
|
||||
add_default_list(fd, allow_debuggers);
|
||||
filter_init(fd, native);
|
||||
add_default_list(fd, allow_debuggers, native);
|
||||
filter_end_blacklist(fd);
|
||||
|
||||
// close file
|
||||
|
|
@ -66,7 +66,7 @@ void seccomp_default(const char *fname, int allow_debuggers) {
|
|||
}
|
||||
|
||||
// drop list
|
||||
void seccomp_drop(const char *fname1, const char *fname2, char *list, int allow_debuggers) {
|
||||
void seccomp_drop(const char *fname1, const char *fname2, char *list, int allow_debuggers, bool native) {
|
||||
assert(fname1);
|
||||
assert(fname2);
|
||||
(void) allow_debuggers; // todo: to implemnet it
|
||||
|
|
@ -79,15 +79,15 @@ void seccomp_drop(const char *fname1, const char *fname2, char *list, int allow_
|
|||
}
|
||||
|
||||
// build pre-exec filter: don't blacklist any syscalls in @default-keep
|
||||
filter_init(fd);
|
||||
filter_init(fd, native);
|
||||
|
||||
// allow exceptions in form of !syscall
|
||||
syscall_check_list(list, filter_add_whitelist_for_excluded, fd, 0, NULL);
|
||||
syscall_check_list(list, filter_add_whitelist_for_excluded, fd, 0, NULL, native);
|
||||
|
||||
char *prelist, *postlist;
|
||||
syscalls_in_list(list, "@default-keep", fd, &prelist, &postlist);
|
||||
syscalls_in_list(list, "@default-keep", fd, &prelist, &postlist, native);
|
||||
if (prelist)
|
||||
if (syscall_check_list(prelist, filter_add_blacklist, fd, 0, NULL)) {
|
||||
if (syscall_check_list(prelist, filter_add_blacklist, fd, 0, NULL, native)) {
|
||||
fprintf(stderr, "Error fseccomp: cannot build seccomp filter\n");
|
||||
exit(1);
|
||||
}
|
||||
|
|
@ -106,8 +106,8 @@ void seccomp_drop(const char *fname1, const char *fname2, char *list, int allow_
|
|||
}
|
||||
|
||||
// build post-exec filter: blacklist remaining syscalls
|
||||
filter_init(fd);
|
||||
if (syscall_check_list(postlist, filter_add_blacklist, fd, 0, NULL)) {
|
||||
filter_init(fd, native);
|
||||
if (syscall_check_list(postlist, filter_add_blacklist, fd, 0, NULL, native)) {
|
||||
fprintf(stderr, "Error fseccomp: cannot build seccomp filter\n");
|
||||
exit(1);
|
||||
}
|
||||
|
|
@ -118,7 +118,7 @@ void seccomp_drop(const char *fname1, const char *fname2, char *list, int allow_
|
|||
}
|
||||
|
||||
// default+drop
|
||||
void seccomp_default_drop(const char *fname1, const char *fname2, char *list, int allow_debuggers) {
|
||||
void seccomp_default_drop(const char *fname1, const char *fname2, char *list, int allow_debuggers, bool native) {
|
||||
assert(fname1);
|
||||
assert(fname2);
|
||||
|
||||
|
|
@ -131,16 +131,16 @@ void seccomp_default_drop(const char *fname1, const char *fname2, char *list, in
|
|||
|
||||
// build pre-exec filter: blacklist @default, don't blacklist
|
||||
// any listed syscalls in @default-keep
|
||||
filter_init(fd);
|
||||
filter_init(fd, native);
|
||||
|
||||
// allow exceptions in form of !syscall
|
||||
syscall_check_list(list, filter_add_whitelist_for_excluded, fd, 0, NULL);
|
||||
syscall_check_list(list, filter_add_whitelist_for_excluded, fd, 0, NULL, native);
|
||||
|
||||
add_default_list(fd, allow_debuggers);
|
||||
add_default_list(fd, allow_debuggers, native);
|
||||
char *prelist, *postlist;
|
||||
syscalls_in_list(list, "@default-keep", fd, &prelist, &postlist);
|
||||
syscalls_in_list(list, "@default-keep", fd, &prelist, &postlist, native);
|
||||
if (prelist)
|
||||
if (syscall_check_list(prelist, filter_add_blacklist, fd, 0, NULL)) {
|
||||
if (syscall_check_list(prelist, filter_add_blacklist, fd, 0, NULL, native)) {
|
||||
fprintf(stderr, "Error fseccomp: cannot build seccomp filter\n");
|
||||
exit(1);
|
||||
}
|
||||
|
|
@ -160,8 +160,8 @@ void seccomp_default_drop(const char *fname1, const char *fname2, char *list, in
|
|||
}
|
||||
|
||||
// build post-exec filter: blacklist remaining syscalls
|
||||
filter_init(fd);
|
||||
if (syscall_check_list(postlist, filter_add_blacklist, fd, 0, NULL)) {
|
||||
filter_init(fd, native);
|
||||
if (syscall_check_list(postlist, filter_add_blacklist, fd, 0, NULL, native)) {
|
||||
fprintf(stderr, "Error fseccomp: cannot build seccomp filter\n");
|
||||
exit(1);
|
||||
}
|
||||
|
|
@ -171,7 +171,7 @@ void seccomp_default_drop(const char *fname1, const char *fname2, char *list, in
|
|||
close(fd);
|
||||
}
|
||||
|
||||
void seccomp_keep(const char *fname1, const char *fname2, char *list) {
|
||||
void seccomp_keep(const char *fname1, const char *fname2, char *list, bool native) {
|
||||
(void) fname2;
|
||||
|
||||
// open file for pre-exec filter
|
||||
|
|
@ -182,17 +182,17 @@ void seccomp_keep(const char *fname1, const char *fname2, char *list) {
|
|||
}
|
||||
|
||||
// build pre-exec filter: whitelist also @default-keep
|
||||
filter_init(fd);
|
||||
filter_init(fd, native);
|
||||
|
||||
// allow exceptions in form of !syscall
|
||||
syscall_check_list(list, filter_add_blacklist_for_excluded, fd, 0, NULL);
|
||||
syscall_check_list(list, filter_add_blacklist_for_excluded, fd, 0, NULL, native);
|
||||
|
||||
// these syscalls are used by firejail after the seccomp filter is initialized
|
||||
int r;
|
||||
r = syscall_check_list("@default-keep", filter_add_whitelist, fd, 0, NULL);
|
||||
r = syscall_check_list("@default-keep", filter_add_whitelist, fd, 0, NULL, native);
|
||||
assert(r == 0);
|
||||
|
||||
if (syscall_check_list(list, filter_add_whitelist, fd, 0, NULL)) {
|
||||
if (syscall_check_list(list, filter_add_whitelist, fd, 0, NULL, native)) {
|
||||
fprintf(stderr, "Error fseccomp: cannot build seccomp filter\n");
|
||||
exit(1);
|
||||
}
|
||||
|
|
@ -206,6 +206,15 @@ void seccomp_keep(const char *fname1, const char *fname2, char *list) {
|
|||
#if defined(__x86_64__) || defined(__aarch64__) || defined(__powerpc64__)
|
||||
# define filter_syscall SYS_mmap
|
||||
# undef block_syscall
|
||||
#if defined(__x86_64__)
|
||||
// i386 syscalls
|
||||
# define filter_syscall_32 192
|
||||
# define block_syscall_32 90
|
||||
# define mprotect_32 125
|
||||
# define pkey_mprotect_32 380
|
||||
# define shmat_32 397
|
||||
# define memfd_create_32 356
|
||||
#endif
|
||||
#elif defined(__i386__)
|
||||
# define filter_syscall SYS_mmap2
|
||||
# define block_syscall SYS_mmap
|
||||
|
|
@ -216,6 +225,12 @@ void seccomp_keep(const char *fname1, const char *fname2, char *list) {
|
|||
# warning "Platform does not support seccomp memory-deny-write-execute filter yet"
|
||||
# undef filter_syscall
|
||||
# undef block_syscall
|
||||
# undef filter_syscall_32
|
||||
# undef block_syscall_32
|
||||
# undef mprotect_32
|
||||
# undef pkey_mprotect_32
|
||||
# undef shmat_32
|
||||
# undef memfd_create_32
|
||||
#endif
|
||||
|
||||
void memory_deny_write_execute(const char *fname) {
|
||||
|
|
@ -226,10 +241,10 @@ void memory_deny_write_execute(const char *fname) {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
filter_init(fd);
|
||||
filter_init(fd, true);
|
||||
|
||||
// build filter
|
||||
static const struct sock_filter filter[] = {
|
||||
struct sock_filter filter[] = {
|
||||
#ifdef block_syscall
|
||||
// block old multiplexing mmap syscall for i386
|
||||
BLACKLIST(block_syscall),
|
||||
|
|
@ -288,3 +303,75 @@ void memory_deny_write_execute(const char *fname) {
|
|||
// close file
|
||||
close(fd);
|
||||
}
|
||||
|
||||
void memory_deny_write_execute_32(const char *fname) {
|
||||
// open file
|
||||
int fd = open(fname, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Error fseccomp: cannot open %s file\n", fname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
filter_init(fd, false);
|
||||
|
||||
// build filter
|
||||
struct sock_filter filter[] = {
|
||||
#if defined(__x86_64__)
|
||||
#ifdef block_syscall_32
|
||||
// block old multiplexing mmap syscall for i386
|
||||
BLACKLIST(block_syscall_32),
|
||||
#endif
|
||||
#ifdef filter_syscall_32
|
||||
// block mmap(,,x|PROT_WRITE|PROT_EXEC) so W&X memory can't be created
|
||||
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, filter_syscall_32, 0, 5),
|
||||
EXAMINE_ARGUMENT(2),
|
||||
BPF_STMT(BPF_ALU+BPF_AND+BPF_K, PROT_WRITE|PROT_EXEC),
|
||||
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, PROT_WRITE|PROT_EXEC, 0, 1),
|
||||
KILL_PROCESS,
|
||||
RETURN_ALLOW,
|
||||
#endif
|
||||
#ifdef mprotect_32
|
||||
// block mprotect(,,PROT_EXEC) so writable memory can't be turned into executable
|
||||
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, mprotect_32, 0, 5),
|
||||
EXAMINE_ARGUMENT(2),
|
||||
BPF_STMT(BPF_ALU+BPF_AND+BPF_K, PROT_EXEC),
|
||||
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, PROT_EXEC, 0, 1),
|
||||
KILL_PROCESS,
|
||||
RETURN_ALLOW,
|
||||
#endif
|
||||
#ifdef pkey_mprotect_32
|
||||
// same for pkey_mprotect(,,PROT_EXEC), where available
|
||||
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, pkey_mprotect_32, 0, 5),
|
||||
EXAMINE_ARGUMENT(2),
|
||||
BPF_STMT(BPF_ALU+BPF_AND+BPF_K, PROT_EXEC),
|
||||
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, PROT_EXEC, 0, 1),
|
||||
KILL_PROCESS,
|
||||
RETURN_ALLOW,
|
||||
#endif
|
||||
|
||||
#ifdef shmat_32
|
||||
// block shmat(,,x|SHM_EXEC) so W&X shared memory can't be created
|
||||
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, shmat_32, 0, 5),
|
||||
EXAMINE_ARGUMENT(2),
|
||||
BPF_STMT(BPF_ALU+BPF_AND+BPF_K, SHM_EXEC),
|
||||
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, SHM_EXEC, 0, 1),
|
||||
KILL_PROCESS,
|
||||
RETURN_ALLOW,
|
||||
#endif
|
||||
#ifdef memfd_create_32
|
||||
// block memfd_create as it can be used to create
|
||||
// arbitrary memory contents which can be later mapped
|
||||
// as executable
|
||||
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, memfd_create_32, 0, 1),
|
||||
KILL_PROCESS,
|
||||
#endif
|
||||
#endif
|
||||
RETURN_ALLOW
|
||||
};
|
||||
write_to_file(fd, filter, sizeof(filter));
|
||||
|
||||
filter_end_blacklist(fd);
|
||||
|
||||
// close file
|
||||
close(fd);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,11 +21,11 @@
|
|||
#include "../include/seccomp.h"
|
||||
#include <sys/syscall.h>
|
||||
|
||||
void write_to_file(int fd, const void *data, int size) {
|
||||
void write_to_file(int fd, const void *data, size_t size) {
|
||||
assert(data);
|
||||
assert(size);
|
||||
|
||||
int written = 0;
|
||||
size_t written = 0;
|
||||
while (written < size) {
|
||||
int rv = write(fd, (unsigned char *) data + written, size - written);
|
||||
if (rv == -1) {
|
||||
|
|
@ -36,8 +36,8 @@ void write_to_file(int fd, const void *data, int size) {
|
|||
}
|
||||
}
|
||||
|
||||
void filter_init(int fd) {
|
||||
struct sock_filter filter[] = {
|
||||
void filter_init(int fd, bool native) {
|
||||
struct sock_filter filter_native[] = {
|
||||
VALIDATE_ARCHITECTURE,
|
||||
#if defined(__x86_64__)
|
||||
EXAMINE_SYSCALL,
|
||||
|
|
@ -46,6 +46,10 @@ void filter_init(int fd) {
|
|||
EXAMINE_SYSCALL
|
||||
#endif
|
||||
};
|
||||
struct sock_filter filter_32[] = {
|
||||
VALIDATE_ARCHITECTURE_32,
|
||||
EXAMINE_SYSCALL
|
||||
};
|
||||
|
||||
#if 0
|
||||
{
|
||||
|
|
@ -57,7 +61,10 @@ void filter_init(int fd) {
|
|||
}
|
||||
#endif
|
||||
|
||||
write_to_file(fd, filter, sizeof(filter));
|
||||
if (native)
|
||||
write_to_file(fd, filter_native, sizeof(filter_native));
|
||||
else
|
||||
write_to_file(fd, filter_32, sizeof(filter_32));
|
||||
}
|
||||
|
||||
static void write_whitelist(int fd, int syscall) {
|
||||
|
|
@ -74,9 +81,10 @@ static void write_blacklist(int fd, int syscall) {
|
|||
write_to_file(fd, filter, sizeof(filter));
|
||||
}
|
||||
|
||||
void filter_add_whitelist(int fd, int syscall, int arg, void *ptrarg) {
|
||||
void filter_add_whitelist(int fd, int syscall, int arg, void *ptrarg, bool native) {
|
||||
(void) arg;
|
||||
(void) ptrarg;
|
||||
(void) native;
|
||||
|
||||
if (syscall >= 0) {
|
||||
write_whitelist(fd, syscall);
|
||||
|
|
@ -84,18 +92,20 @@ void filter_add_whitelist(int fd, int syscall, int arg, void *ptrarg) {
|
|||
}
|
||||
|
||||
// handle seccomp list exceptions (seccomp x,y,!z)
|
||||
void filter_add_whitelist_for_excluded(int fd, int syscall, int arg, void *ptrarg) {
|
||||
void filter_add_whitelist_for_excluded(int fd, int syscall, int arg, void *ptrarg, bool native) {
|
||||
(void) arg;
|
||||
(void) ptrarg;
|
||||
(void) native;
|
||||
|
||||
if (syscall < 0) {
|
||||
write_whitelist(fd, -syscall);
|
||||
}
|
||||
}
|
||||
|
||||
void filter_add_blacklist(int fd, int syscall, int arg, void *ptrarg) {
|
||||
void filter_add_blacklist(int fd, int syscall, int arg, void *ptrarg, bool native) {
|
||||
(void) arg;
|
||||
(void) ptrarg;
|
||||
(void) native;
|
||||
|
||||
if (syscall >= 0) {
|
||||
write_blacklist(fd, syscall);
|
||||
|
|
@ -103,17 +113,20 @@ void filter_add_blacklist(int fd, int syscall, int arg, void *ptrarg) {
|
|||
}
|
||||
|
||||
// handle seccomp list exceptions (seccomp x,y,!z)
|
||||
void filter_add_blacklist_for_excluded(int fd, int syscall, int arg, void *ptrarg) {
|
||||
void filter_add_blacklist_for_excluded(int fd, int syscall, int arg, void *ptrarg, bool native) {
|
||||
(void) arg;
|
||||
(void) ptrarg;
|
||||
(void) native;
|
||||
|
||||
if (syscall < 0) {
|
||||
write_blacklist(fd, -syscall);
|
||||
}
|
||||
}
|
||||
|
||||
void filter_add_errno(int fd, int syscall, int arg, void *ptrarg) {
|
||||
void filter_add_errno(int fd, int syscall, int arg, void *ptrarg, bool native) {
|
||||
(void) ptrarg;
|
||||
(void) native;
|
||||
|
||||
struct sock_filter filter[] = {
|
||||
BLACKLIST_ERRNO(syscall, arg)
|
||||
};
|
||||
|
|
|
|||
|
|
@ -62,13 +62,17 @@
|
|||
#define RUN_SECCOMP_PROTOCOL RUN_SECCOMP_DIR "/seccomp.protocol" // protocol filter
|
||||
#define RUN_SECCOMP_CFG RUN_SECCOMP_DIR "/seccomp" // configured filter
|
||||
#define RUN_SECCOMP_32 RUN_SECCOMP_DIR "/seccomp.32" // 32bit arch filter installed on 64bit architectures
|
||||
#define RUN_SECCOMP_MDWX RUN_SECCOMP_DIR "/seccomp.mdwx" // filter for memory-deny-write-execute
|
||||
#define RUN_SECCOMP_MDWX RUN_SECCOMP_DIR "/seccomp.mdwx" // filter for memory-deny-write-execute
|
||||
#define RUN_SECCOMP_MDWX_32 RUN_SECCOMP_DIR "/seccomp.mdwx.32"
|
||||
#define RUN_SECCOMP_BLOCK_SECONDARY RUN_SECCOMP_DIR "/seccomp.block_secondary" // secondary arch blocking filter
|
||||
#define RUN_SECCOMP_POSTEXEC RUN_SECCOMP_DIR "/seccomp.postexec" // filter for post-exec library
|
||||
#define RUN_SECCOMP_POSTEXEC_32 RUN_SECCOMP_DIR "/seccomp.postexec32" // filter for post-exec library
|
||||
#define PATH_SECCOMP_DEFAULT LIBDIR "/firejail/seccomp" // default filter built during make
|
||||
#define PATH_SECCOMP_DEFAULT_DEBUG LIBDIR "/firejail/seccomp.debug" // default filter built during make
|
||||
#define PATH_SECCOMP_DEFAULT_DEBUG LIBDIR "/firejail/seccomp.debug" // debug filter built during make
|
||||
#define PATH_SECCOMP_32 LIBDIR "/firejail/seccomp.32" // 32bit arch filter built during make
|
||||
#define PATH_SECCOMP_MDWX LIBDIR "/firejail/seccomp.mdwx" // filter for memory-deny-write-execute built during make
|
||||
#define PATH_SECCOMP_DEBUG_32 LIBDIR "/firejail/seccomp.debug32" // 32bit arch debug filter built during make
|
||||
#define PATH_SECCOMP_MDWX LIBDIR "/firejail/seccomp.mdwx" // filter for memory-deny-write-execute built during make
|
||||
#define PATH_SECCOMP_MDWX_32 LIBDIR "/firejail/seccomp.mdwx.32"
|
||||
#define PATH_SECCOMP_BLOCK_SECONDARY LIBDIR "/firejail/seccomp.block_secondary" // secondary arch blocking filter built during make
|
||||
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
425
src/include/syscall_i386.h
Normal file
425
src/include/syscall_i386.h
Normal file
|
|
@ -0,0 +1,425 @@
|
|||
{ "_llseek", 140 },
|
||||
{ "_newselect", 142 },
|
||||
{ "_sysctl", 149 },
|
||||
{ "accept4", 364 },
|
||||
{ "access", 33 },
|
||||
{ "acct", 51 },
|
||||
{ "add_key", 286 },
|
||||
{ "adjtimex", 124 },
|
||||
{ "afs_syscall", 137 },
|
||||
{ "alarm", 27 },
|
||||
{ "arch_prctl", 384 },
|
||||
{ "bdflush", 134 },
|
||||
{ "bind", 361 },
|
||||
{ "bpf", 357 },
|
||||
{ "break", 17 },
|
||||
{ "brk", 45 },
|
||||
{ "capget", 184 },
|
||||
{ "capset", 185 },
|
||||
{ "chdir", 12 },
|
||||
{ "chmod", 15 },
|
||||
{ "chown", 182 },
|
||||
{ "chown32", 212 },
|
||||
{ "chroot", 61 },
|
||||
{ "clock_adjtime", 343 },
|
||||
{ "clock_adjtime64", 405 },
|
||||
{ "clock_getres", 266 },
|
||||
{ "clock_getres_time64", 406 },
|
||||
{ "clock_gettime", 265 },
|
||||
{ "clock_gettime64", 403 },
|
||||
{ "clock_nanosleep", 267 },
|
||||
{ "clock_nanosleep_time64", 407 },
|
||||
{ "clock_settime", 264 },
|
||||
{ "clock_settime64", 404 },
|
||||
{ "clone", 120 },
|
||||
{ "clone3", 435 },
|
||||
{ "close", 6 },
|
||||
{ "connect", 362 },
|
||||
{ "copy_file_range", 377 },
|
||||
{ "creat", 8 },
|
||||
{ "create_module", 127 },
|
||||
{ "delete_module", 129 },
|
||||
{ "dup", 41 },
|
||||
{ "dup2", 63 },
|
||||
{ "dup3", 330 },
|
||||
{ "epoll_create", 254 },
|
||||
{ "epoll_create1", 329 },
|
||||
{ "epoll_ctl", 255 },
|
||||
{ "epoll_pwait", 319 },
|
||||
{ "epoll_wait", 256 },
|
||||
{ "eventfd", 323 },
|
||||
{ "eventfd2", 328 },
|
||||
{ "execve", 11 },
|
||||
{ "execveat", 358 },
|
||||
{ "exit", 1 },
|
||||
{ "exit_group", 252 },
|
||||
{ "faccessat", 307 },
|
||||
{ "fadvise64", 250 },
|
||||
{ "fadvise64_64", 272 },
|
||||
{ "fallocate", 324 },
|
||||
{ "fanotify_init", 338 },
|
||||
{ "fanotify_mark", 339 },
|
||||
{ "fchdir", 133 },
|
||||
{ "fchmod", 94 },
|
||||
{ "fchmodat", 306 },
|
||||
{ "fchown", 95 },
|
||||
{ "fchown32", 207 },
|
||||
{ "fchownat", 298 },
|
||||
{ "fcntl", 55 },
|
||||
{ "fcntl64", 221 },
|
||||
{ "fdatasync", 148 },
|
||||
{ "fgetxattr", 231 },
|
||||
{ "finit_module", 350 },
|
||||
{ "flistxattr", 234 },
|
||||
{ "flock", 143 },
|
||||
{ "fork", 2 },
|
||||
{ "fremovexattr", 237 },
|
||||
{ "fsconfig", 431 },
|
||||
{ "fsetxattr", 228 },
|
||||
{ "fsmount", 432 },
|
||||
{ "fsopen", 430 },
|
||||
{ "fspick", 433 },
|
||||
{ "fstat", 108 },
|
||||
{ "fstat64", 197 },
|
||||
{ "fstatat64", 300 },
|
||||
{ "fstatfs", 100 },
|
||||
{ "fstatfs64", 269 },
|
||||
{ "fsync", 118 },
|
||||
{ "ftime", 35 },
|
||||
{ "ftruncate", 93 },
|
||||
{ "ftruncate64", 194 },
|
||||
{ "futex", 240 },
|
||||
{ "futex_time64", 422 },
|
||||
{ "futimesat", 299 },
|
||||
{ "get_kernel_syms", 130 },
|
||||
{ "get_mempolicy", 275 },
|
||||
{ "get_robust_list", 312 },
|
||||
{ "get_thread_area", 244 },
|
||||
{ "getcpu", 318 },
|
||||
{ "getcwd", 183 },
|
||||
{ "getdents", 141 },
|
||||
{ "getdents64", 220 },
|
||||
{ "getegid", 50 },
|
||||
{ "getegid32", 202 },
|
||||
{ "geteuid", 49 },
|
||||
{ "geteuid32", 201 },
|
||||
{ "getgid", 47 },
|
||||
{ "getgid32", 200 },
|
||||
{ "getgroups", 80 },
|
||||
{ "getgroups32", 205 },
|
||||
{ "getitimer", 105 },
|
||||
{ "getpeername", 368 },
|
||||
{ "getpgid", 132 },
|
||||
{ "getpgrp", 65 },
|
||||
{ "getpid", 20 },
|
||||
{ "getpmsg", 188 },
|
||||
{ "getppid", 64 },
|
||||
{ "getpriority", 96 },
|
||||
{ "getrandom", 355 },
|
||||
{ "getresgid", 171 },
|
||||
{ "getresgid32", 211 },
|
||||
{ "getresuid", 165 },
|
||||
{ "getresuid32", 209 },
|
||||
{ "getrlimit", 76 },
|
||||
{ "getrusage", 77 },
|
||||
{ "getsid", 147 },
|
||||
{ "getsockname", 367 },
|
||||
{ "getsockopt", 365 },
|
||||
{ "gettid", 224 },
|
||||
{ "gettimeofday", 78 },
|
||||
{ "getuid", 24 },
|
||||
{ "getuid32", 199 },
|
||||
{ "getxattr", 229 },
|
||||
{ "gtty", 32 },
|
||||
{ "idle", 112 },
|
||||
{ "init_module", 128 },
|
||||
{ "inotify_add_watch", 292 },
|
||||
{ "inotify_init", 291 },
|
||||
{ "inotify_init1", 332 },
|
||||
{ "inotify_rm_watch", 293 },
|
||||
{ "io_cancel", 249 },
|
||||
{ "io_destroy", 246 },
|
||||
{ "io_getevents", 247 },
|
||||
{ "io_pgetevents", 385 },
|
||||
{ "io_pgetevents_time64", 416 },
|
||||
{ "io_setup", 245 },
|
||||
{ "io_submit", 248 },
|
||||
{ "io_uring_enter", 426 },
|
||||
{ "io_uring_register", 427 },
|
||||
{ "io_uring_setup", 425 },
|
||||
{ "ioctl", 54 },
|
||||
{ "ioperm", 101 },
|
||||
{ "iopl", 110 },
|
||||
{ "ioprio_get", 290 },
|
||||
{ "ioprio_set", 289 },
|
||||
{ "ipc", 117 },
|
||||
{ "kcmp", 349 },
|
||||
{ "kexec_load", 283 },
|
||||
{ "keyctl", 288 },
|
||||
{ "kill", 37 },
|
||||
{ "lchown", 16 },
|
||||
{ "lchown32", 198 },
|
||||
{ "lgetxattr", 230 },
|
||||
{ "link", 9 },
|
||||
{ "linkat", 303 },
|
||||
{ "listen", 363 },
|
||||
{ "listxattr", 232 },
|
||||
{ "llistxattr", 233 },
|
||||
{ "lock", 53 },
|
||||
{ "lookup_dcookie", 253 },
|
||||
{ "lremovexattr", 236 },
|
||||
{ "lseek", 19 },
|
||||
{ "lsetxattr", 227 },
|
||||
{ "lstat", 107 },
|
||||
{ "lstat64", 196 },
|
||||
{ "madvise", 219 },
|
||||
{ "mbind", 274 },
|
||||
{ "membarrier", 375 },
|
||||
{ "memfd_create", 356 },
|
||||
{ "migrate_pages", 294 },
|
||||
{ "mincore", 218 },
|
||||
{ "mkdir", 39 },
|
||||
{ "mkdirat", 296 },
|
||||
{ "mknod", 14 },
|
||||
{ "mknodat", 297 },
|
||||
{ "mlock", 150 },
|
||||
{ "mlock2", 376 },
|
||||
{ "mlockall", 152 },
|
||||
{ "mmap", 90 },
|
||||
{ "mmap2", 192 },
|
||||
{ "modify_ldt", 123 },
|
||||
{ "mount", 21 },
|
||||
{ "move_mount", 429 },
|
||||
{ "move_pages", 317 },
|
||||
{ "mprotect", 125 },
|
||||
{ "mpx", 56 },
|
||||
{ "mq_getsetattr", 282 },
|
||||
{ "mq_notify", 281 },
|
||||
{ "mq_open", 277 },
|
||||
{ "mq_timedreceive", 280 },
|
||||
{ "mq_timedreceive_time64", 419 },
|
||||
{ "mq_timedsend", 279 },
|
||||
{ "mq_timedsend_time64", 418 },
|
||||
{ "mq_unlink", 278 },
|
||||
{ "mremap", 163 },
|
||||
{ "msgctl", 402 },
|
||||
{ "msgget", 399 },
|
||||
{ "msgrcv", 401 },
|
||||
{ "msgsnd", 400 },
|
||||
{ "msync", 144 },
|
||||
{ "munlock", 151 },
|
||||
{ "munlockall", 153 },
|
||||
{ "munmap", 91 },
|
||||
{ "name_to_handle_at", 341 },
|
||||
{ "nanosleep", 162 },
|
||||
{ "nfsservctl", 169 },
|
||||
{ "nice", 34 },
|
||||
{ "oldfstat", 28 },
|
||||
{ "oldlstat", 84 },
|
||||
{ "oldolduname", 59 },
|
||||
{ "oldstat", 18 },
|
||||
{ "olduname", 109 },
|
||||
{ "open", 5 },
|
||||
{ "open_by_handle_at", 342 },
|
||||
{ "open_tree", 428 },
|
||||
{ "openat", 295 },
|
||||
{ "pause", 29 },
|
||||
{ "perf_event_open", 336 },
|
||||
{ "personality", 136 },
|
||||
{ "pidfd_open", 434 },
|
||||
{ "pidfd_send_signal", 424 },
|
||||
{ "pipe", 42 },
|
||||
{ "pipe2", 331 },
|
||||
{ "pivot_root", 217 },
|
||||
{ "pkey_alloc", 381 },
|
||||
{ "pkey_free", 382 },
|
||||
{ "pkey_mprotect", 380 },
|
||||
{ "poll", 168 },
|
||||
{ "ppoll", 309 },
|
||||
{ "ppoll_time64", 414 },
|
||||
{ "prctl", 172 },
|
||||
{ "pread64", 180 },
|
||||
{ "preadv", 333 },
|
||||
{ "preadv2", 378 },
|
||||
{ "prlimit64", 340 },
|
||||
{ "process_vm_readv", 347 },
|
||||
{ "process_vm_writev", 348 },
|
||||
{ "prof", 44 },
|
||||
{ "profil", 98 },
|
||||
{ "pselect6", 308 },
|
||||
{ "pselect6_time64", 413 },
|
||||
{ "ptrace", 26 },
|
||||
{ "putpmsg", 189 },
|
||||
{ "pwrite64", 181 },
|
||||
{ "pwritev", 334 },
|
||||
{ "pwritev2", 379 },
|
||||
{ "query_module", 167 },
|
||||
{ "quotactl", 131 },
|
||||
{ "read", 3 },
|
||||
{ "readahead", 225 },
|
||||
{ "readdir", 89 },
|
||||
{ "readlink", 85 },
|
||||
{ "readlinkat", 305 },
|
||||
{ "readv", 145 },
|
||||
{ "reboot", 88 },
|
||||
{ "recvfrom", 371 },
|
||||
{ "recvmmsg", 337 },
|
||||
{ "recvmmsg_time64", 417 },
|
||||
{ "recvmsg", 372 },
|
||||
{ "remap_file_pages", 257 },
|
||||
{ "removexattr", 235 },
|
||||
{ "rename", 38 },
|
||||
{ "renameat", 302 },
|
||||
{ "renameat2", 353 },
|
||||
{ "request_key", 287 },
|
||||
{ "restart_syscall", 0 },
|
||||
{ "rmdir", 40 },
|
||||
{ "rseq", 386 },
|
||||
{ "rt_sigaction", 174 },
|
||||
{ "rt_sigpending", 176 },
|
||||
{ "rt_sigprocmask", 175 },
|
||||
{ "rt_sigqueueinfo", 178 },
|
||||
{ "rt_sigreturn", 173 },
|
||||
{ "rt_sigsuspend", 179 },
|
||||
{ "rt_sigtimedwait", 177 },
|
||||
{ "rt_sigtimedwait_time64", 421 },
|
||||
{ "rt_tgsigqueueinfo", 335 },
|
||||
{ "sched_get_priority_max", 159 },
|
||||
{ "sched_get_priority_min", 160 },
|
||||
{ "sched_getaffinity", 242 },
|
||||
{ "sched_getattr", 352 },
|
||||
{ "sched_getparam", 155 },
|
||||
{ "sched_getscheduler", 157 },
|
||||
{ "sched_rr_get_interval", 161 },
|
||||
{ "sched_rr_get_interval_time64", 423 },
|
||||
{ "sched_setaffinity", 241 },
|
||||
{ "sched_setattr", 351 },
|
||||
{ "sched_setparam", 154 },
|
||||
{ "sched_setscheduler", 156 },
|
||||
{ "sched_yield", 158 },
|
||||
{ "seccomp", 354 },
|
||||
{ "select", 82 },
|
||||
{ "semctl", 394 },
|
||||
{ "semget", 393 },
|
||||
{ "semtimedop_time64", 420 },
|
||||
{ "sendfile", 187 },
|
||||
{ "sendfile64", 239 },
|
||||
{ "sendmmsg", 345 },
|
||||
{ "sendmsg", 370 },
|
||||
{ "sendto", 369 },
|
||||
{ "set_mempolicy", 276 },
|
||||
{ "set_robust_list", 311 },
|
||||
{ "set_thread_area", 243 },
|
||||
{ "set_tid_address", 258 },
|
||||
{ "setdomainname", 121 },
|
||||
{ "setfsgid", 139 },
|
||||
{ "setfsgid32", 216 },
|
||||
{ "setfsuid", 138 },
|
||||
{ "setfsuid32", 215 },
|
||||
{ "setgid", 46 },
|
||||
{ "setgid32", 214 },
|
||||
{ "setgroups", 81 },
|
||||
{ "setgroups32", 206 },
|
||||
{ "sethostname", 74 },
|
||||
{ "setitimer", 104 },
|
||||
{ "setns", 346 },
|
||||
{ "setpgid", 57 },
|
||||
{ "setpriority", 97 },
|
||||
{ "setregid", 71 },
|
||||
{ "setregid32", 204 },
|
||||
{ "setresgid", 170 },
|
||||
{ "setresgid32", 210 },
|
||||
{ "setresuid", 164 },
|
||||
{ "setresuid32", 208 },
|
||||
{ "setreuid", 70 },
|
||||
{ "setreuid32", 203 },
|
||||
{ "setrlimit", 75 },
|
||||
{ "setsid", 66 },
|
||||
{ "setsockopt", 366 },
|
||||
{ "settimeofday", 79 },
|
||||
{ "setuid", 23 },
|
||||
{ "setuid32", 213 },
|
||||
{ "setxattr", 226 },
|
||||
{ "sgetmask", 68 },
|
||||
{ "shmat", 397 },
|
||||
{ "shmctl", 396 },
|
||||
{ "shmdt", 398 },
|
||||
{ "shmget", 395 },
|
||||
{ "shutdown", 373 },
|
||||
{ "sigaction", 67 },
|
||||
{ "sigaltstack", 186 },
|
||||
{ "signal", 48 },
|
||||
{ "signalfd", 321 },
|
||||
{ "signalfd4", 327 },
|
||||
{ "sigpending", 73 },
|
||||
{ "sigprocmask", 126 },
|
||||
{ "sigreturn", 119 },
|
||||
{ "sigsuspend", 72 },
|
||||
{ "socket", 359 },
|
||||
{ "socketcall", 102 },
|
||||
{ "socketpair", 360 },
|
||||
{ "splice", 313 },
|
||||
{ "ssetmask", 69 },
|
||||
{ "stat", 106 },
|
||||
{ "stat64", 195 },
|
||||
{ "statfs", 99 },
|
||||
{ "statfs64", 268 },
|
||||
{ "statx", 383 },
|
||||
{ "stime", 25 },
|
||||
{ "stty", 31 },
|
||||
{ "swapoff", 115 },
|
||||
{ "swapon", 87 },
|
||||
{ "symlink", 83 },
|
||||
{ "symlinkat", 304 },
|
||||
{ "sync", 36 },
|
||||
{ "sync_file_range", 314 },
|
||||
{ "syncfs", 344 },
|
||||
{ "sysfs", 135 },
|
||||
{ "sysinfo", 116 },
|
||||
{ "syslog", 103 },
|
||||
{ "tee", 315 },
|
||||
{ "tgkill", 270 },
|
||||
{ "time", 13 },
|
||||
{ "timer_create", 259 },
|
||||
{ "timer_delete", 263 },
|
||||
{ "timer_getoverrun", 262 },
|
||||
{ "timer_gettime", 261 },
|
||||
{ "timer_gettime64", 408 },
|
||||
{ "timer_settime", 260 },
|
||||
{ "timer_settime64", 409 },
|
||||
{ "timerfd_create", 322 },
|
||||
{ "timerfd_gettime", 326 },
|
||||
{ "timerfd_gettime64", 410 },
|
||||
{ "timerfd_settime", 325 },
|
||||
{ "timerfd_settime64", 411 },
|
||||
{ "times", 43 },
|
||||
{ "tkill", 238 },
|
||||
{ "truncate", 92 },
|
||||
{ "truncate64", 193 },
|
||||
{ "ugetrlimit", 191 },
|
||||
{ "ulimit", 58 },
|
||||
{ "umask", 60 },
|
||||
{ "umount", 22 },
|
||||
{ "umount2", 52 },
|
||||
{ "uname", 122 },
|
||||
{ "unlink", 10 },
|
||||
{ "unlinkat", 301 },
|
||||
{ "unshare", 310 },
|
||||
{ "uselib", 86 },
|
||||
{ "userfaultfd", 374 },
|
||||
{ "ustat", 62 },
|
||||
{ "utime", 30 },
|
||||
{ "utimensat", 320 },
|
||||
{ "utimensat_time64", 412 },
|
||||
{ "utimes", 271 },
|
||||
{ "vfork", 190 },
|
||||
{ "vhangup", 111 },
|
||||
{ "vm86", 166 },
|
||||
{ "vm86old", 113 },
|
||||
{ "vmsplice", 316 },
|
||||
{ "vserver", 273 },
|
||||
{ "wait4", 114 },
|
||||
{ "waitid", 284 },
|
||||
{ "waitpid", 7 },
|
||||
{ "write", 4 },
|
||||
{ "writev", 146 },
|
||||
347
src/include/syscall_x86_64.h
Normal file
347
src/include/syscall_x86_64.h
Normal file
|
|
@ -0,0 +1,347 @@
|
|||
{ "_sysctl", 156 },
|
||||
{ "accept", 43 },
|
||||
{ "accept4", 288 },
|
||||
{ "access", 21 },
|
||||
{ "acct", 163 },
|
||||
{ "add_key", 248 },
|
||||
{ "adjtimex", 159 },
|
||||
{ "afs_syscall", 183 },
|
||||
{ "alarm", 37 },
|
||||
{ "arch_prctl", 158 },
|
||||
{ "bind", 49 },
|
||||
{ "bpf", 321 },
|
||||
{ "brk", 12 },
|
||||
{ "capget", 125 },
|
||||
{ "capset", 126 },
|
||||
{ "chdir", 80 },
|
||||
{ "chmod", 90 },
|
||||
{ "chown", 92 },
|
||||
{ "chroot", 161 },
|
||||
{ "clock_adjtime", 305 },
|
||||
{ "clock_getres", 229 },
|
||||
{ "clock_gettime", 228 },
|
||||
{ "clock_nanosleep", 230 },
|
||||
{ "clock_settime", 227 },
|
||||
{ "clone", 56 },
|
||||
{ "clone3", 435 },
|
||||
{ "close", 3 },
|
||||
{ "connect", 42 },
|
||||
{ "copy_file_range", 326 },
|
||||
{ "creat", 85 },
|
||||
{ "create_module", 174 },
|
||||
{ "delete_module", 176 },
|
||||
{ "dup", 32 },
|
||||
{ "dup2", 33 },
|
||||
{ "dup3", 292 },
|
||||
{ "epoll_create", 213 },
|
||||
{ "epoll_create1", 291 },
|
||||
{ "epoll_ctl", 233 },
|
||||
{ "epoll_ctl_old", 214 },
|
||||
{ "epoll_pwait", 281 },
|
||||
{ "epoll_wait", 232 },
|
||||
{ "epoll_wait_old", 215 },
|
||||
{ "eventfd", 284 },
|
||||
{ "eventfd2", 290 },
|
||||
{ "execve", 59 },
|
||||
{ "execveat", 322 },
|
||||
{ "exit", 60 },
|
||||
{ "exit_group", 231 },
|
||||
{ "faccessat", 269 },
|
||||
{ "fadvise64", 221 },
|
||||
{ "fallocate", 285 },
|
||||
{ "fanotify_init", 300 },
|
||||
{ "fanotify_mark", 301 },
|
||||
{ "fchdir", 81 },
|
||||
{ "fchmod", 91 },
|
||||
{ "fchmodat", 268 },
|
||||
{ "fchown", 93 },
|
||||
{ "fchownat", 260 },
|
||||
{ "fcntl", 72 },
|
||||
{ "fdatasync", 75 },
|
||||
{ "fgetxattr", 193 },
|
||||
{ "finit_module", 313 },
|
||||
{ "flistxattr", 196 },
|
||||
{ "flock", 73 },
|
||||
{ "fork", 57 },
|
||||
{ "fremovexattr", 199 },
|
||||
{ "fsconfig", 431 },
|
||||
{ "fsetxattr", 190 },
|
||||
{ "fsmount", 432 },
|
||||
{ "fsopen", 430 },
|
||||
{ "fspick", 433 },
|
||||
{ "fstat", 5 },
|
||||
{ "fstatfs", 138 },
|
||||
{ "fsync", 74 },
|
||||
{ "ftruncate", 77 },
|
||||
{ "futex", 202 },
|
||||
{ "futimesat", 261 },
|
||||
{ "get_kernel_syms", 177 },
|
||||
{ "get_mempolicy", 239 },
|
||||
{ "get_robust_list", 274 },
|
||||
{ "get_thread_area", 211 },
|
||||
{ "getcpu", 309 },
|
||||
{ "getcwd", 79 },
|
||||
{ "getdents", 78 },
|
||||
{ "getdents64", 217 },
|
||||
{ "getegid", 108 },
|
||||
{ "geteuid", 107 },
|
||||
{ "getgid", 104 },
|
||||
{ "getgroups", 115 },
|
||||
{ "getitimer", 36 },
|
||||
{ "getpeername", 52 },
|
||||
{ "getpgid", 121 },
|
||||
{ "getpgrp", 111 },
|
||||
{ "getpid", 39 },
|
||||
{ "getpmsg", 181 },
|
||||
{ "getppid", 110 },
|
||||
{ "getpriority", 140 },
|
||||
{ "getrandom", 318 },
|
||||
{ "getresgid", 120 },
|
||||
{ "getresuid", 118 },
|
||||
{ "getrlimit", 97 },
|
||||
{ "getrusage", 98 },
|
||||
{ "getsid", 124 },
|
||||
{ "getsockname", 51 },
|
||||
{ "getsockopt", 55 },
|
||||
{ "gettid", 186 },
|
||||
{ "gettimeofday", 96 },
|
||||
{ "getuid", 102 },
|
||||
{ "getxattr", 191 },
|
||||
{ "init_module", 175 },
|
||||
{ "inotify_add_watch", 254 },
|
||||
{ "inotify_init", 253 },
|
||||
{ "inotify_init1", 294 },
|
||||
{ "inotify_rm_watch", 255 },
|
||||
{ "io_cancel", 210 },
|
||||
{ "io_destroy", 207 },
|
||||
{ "io_getevents", 208 },
|
||||
{ "io_pgetevents", 333 },
|
||||
{ "io_setup", 206 },
|
||||
{ "io_submit", 209 },
|
||||
{ "io_uring_enter", 426 },
|
||||
{ "io_uring_register", 427 },
|
||||
{ "io_uring_setup", 425 },
|
||||
{ "ioctl", 16 },
|
||||
{ "ioperm", 173 },
|
||||
{ "iopl", 172 },
|
||||
{ "ioprio_get", 252 },
|
||||
{ "ioprio_set", 251 },
|
||||
{ "kcmp", 312 },
|
||||
{ "kexec_file_load", 320 },
|
||||
{ "kexec_load", 246 },
|
||||
{ "keyctl", 250 },
|
||||
{ "kill", 62 },
|
||||
{ "lchown", 94 },
|
||||
{ "lgetxattr", 192 },
|
||||
{ "link", 86 },
|
||||
{ "linkat", 265 },
|
||||
{ "listen", 50 },
|
||||
{ "listxattr", 194 },
|
||||
{ "llistxattr", 195 },
|
||||
{ "lookup_dcookie", 212 },
|
||||
{ "lremovexattr", 198 },
|
||||
{ "lseek", 8 },
|
||||
{ "lsetxattr", 189 },
|
||||
{ "lstat", 6 },
|
||||
{ "madvise", 28 },
|
||||
{ "mbind", 237 },
|
||||
{ "membarrier", 324 },
|
||||
{ "memfd_create", 319 },
|
||||
{ "migrate_pages", 256 },
|
||||
{ "mincore", 27 },
|
||||
{ "mkdir", 83 },
|
||||
{ "mkdirat", 258 },
|
||||
{ "mknod", 133 },
|
||||
{ "mknodat", 259 },
|
||||
{ "mlock", 149 },
|
||||
{ "mlock2", 325 },
|
||||
{ "mlockall", 151 },
|
||||
{ "mmap", 9 },
|
||||
{ "modify_ldt", 154 },
|
||||
{ "mount", 165 },
|
||||
{ "move_mount", 429 },
|
||||
{ "move_pages", 279 },
|
||||
{ "mprotect", 10 },
|
||||
{ "mq_getsetattr", 245 },
|
||||
{ "mq_notify", 244 },
|
||||
{ "mq_open", 240 },
|
||||
{ "mq_timedreceive", 243 },
|
||||
{ "mq_timedsend", 242 },
|
||||
{ "mq_unlink", 241 },
|
||||
{ "mremap", 25 },
|
||||
{ "msgctl", 71 },
|
||||
{ "msgget", 68 },
|
||||
{ "msgrcv", 70 },
|
||||
{ "msgsnd", 69 },
|
||||
{ "msync", 26 },
|
||||
{ "munlock", 150 },
|
||||
{ "munlockall", 152 },
|
||||
{ "munmap", 11 },
|
||||
{ "name_to_handle_at", 303 },
|
||||
{ "nanosleep", 35 },
|
||||
{ "newfstatat", 262 },
|
||||
{ "nfsservctl", 180 },
|
||||
{ "open", 2 },
|
||||
{ "open_by_handle_at", 304 },
|
||||
{ "open_tree", 428 },
|
||||
{ "openat", 257 },
|
||||
{ "pause", 34 },
|
||||
{ "perf_event_open", 298 },
|
||||
{ "personality", 135 },
|
||||
{ "pidfd_open", 434 },
|
||||
{ "pidfd_send_signal", 424 },
|
||||
{ "pipe", 22 },
|
||||
{ "pipe2", 293 },
|
||||
{ "pivot_root", 155 },
|
||||
{ "pkey_alloc", 330 },
|
||||
{ "pkey_free", 331 },
|
||||
{ "pkey_mprotect", 329 },
|
||||
{ "poll", 7 },
|
||||
{ "ppoll", 271 },
|
||||
{ "prctl", 157 },
|
||||
{ "pread64", 17 },
|
||||
{ "preadv", 295 },
|
||||
{ "preadv2", 327 },
|
||||
{ "prlimit64", 302 },
|
||||
{ "process_vm_readv", 310 },
|
||||
{ "process_vm_writev", 311 },
|
||||
{ "pselect6", 270 },
|
||||
{ "ptrace", 101 },
|
||||
{ "putpmsg", 182 },
|
||||
{ "pwrite64", 18 },
|
||||
{ "pwritev", 296 },
|
||||
{ "pwritev2", 328 },
|
||||
{ "query_module", 178 },
|
||||
{ "quotactl", 179 },
|
||||
{ "read", 0 },
|
||||
{ "readahead", 187 },
|
||||
{ "readlink", 89 },
|
||||
{ "readlinkat", 267 },
|
||||
{ "readv", 19 },
|
||||
{ "reboot", 169 },
|
||||
{ "recvfrom", 45 },
|
||||
{ "recvmmsg", 299 },
|
||||
{ "recvmsg", 47 },
|
||||
{ "remap_file_pages", 216 },
|
||||
{ "removexattr", 197 },
|
||||
{ "rename", 82 },
|
||||
{ "renameat", 264 },
|
||||
{ "renameat2", 316 },
|
||||
{ "request_key", 249 },
|
||||
{ "restart_syscall", 219 },
|
||||
{ "rmdir", 84 },
|
||||
{ "rseq", 334 },
|
||||
{ "rt_sigaction", 13 },
|
||||
{ "rt_sigpending", 127 },
|
||||
{ "rt_sigprocmask", 14 },
|
||||
{ "rt_sigqueueinfo", 129 },
|
||||
{ "rt_sigreturn", 15 },
|
||||
{ "rt_sigsuspend", 130 },
|
||||
{ "rt_sigtimedwait", 128 },
|
||||
{ "rt_tgsigqueueinfo", 297 },
|
||||
{ "sched_get_priority_max", 146 },
|
||||
{ "sched_get_priority_min", 147 },
|
||||
{ "sched_getaffinity", 204 },
|
||||
{ "sched_getattr", 315 },
|
||||
{ "sched_getparam", 143 },
|
||||
{ "sched_getscheduler", 145 },
|
||||
{ "sched_rr_get_interval", 148 },
|
||||
{ "sched_setaffinity", 203 },
|
||||
{ "sched_setattr", 314 },
|
||||
{ "sched_setparam", 142 },
|
||||
{ "sched_setscheduler", 144 },
|
||||
{ "sched_yield", 24 },
|
||||
{ "seccomp", 317 },
|
||||
{ "security", 185 },
|
||||
{ "select", 23 },
|
||||
{ "semctl", 66 },
|
||||
{ "semget", 64 },
|
||||
{ "semop", 65 },
|
||||
{ "semtimedop", 220 },
|
||||
{ "sendfile", 40 },
|
||||
{ "sendmmsg", 307 },
|
||||
{ "sendmsg", 46 },
|
||||
{ "sendto", 44 },
|
||||
{ "set_mempolicy", 238 },
|
||||
{ "set_robust_list", 273 },
|
||||
{ "set_thread_area", 205 },
|
||||
{ "set_tid_address", 218 },
|
||||
{ "setdomainname", 171 },
|
||||
{ "setfsgid", 123 },
|
||||
{ "setfsuid", 122 },
|
||||
{ "setgid", 106 },
|
||||
{ "setgroups", 116 },
|
||||
{ "sethostname", 170 },
|
||||
{ "setitimer", 38 },
|
||||
{ "setns", 308 },
|
||||
{ "setpgid", 109 },
|
||||
{ "setpriority", 141 },
|
||||
{ "setregid", 114 },
|
||||
{ "setresgid", 119 },
|
||||
{ "setresuid", 117 },
|
||||
{ "setreuid", 113 },
|
||||
{ "setrlimit", 160 },
|
||||
{ "setsid", 112 },
|
||||
{ "setsockopt", 54 },
|
||||
{ "settimeofday", 164 },
|
||||
{ "setuid", 105 },
|
||||
{ "setxattr", 188 },
|
||||
{ "shmat", 30 },
|
||||
{ "shmctl", 31 },
|
||||
{ "shmdt", 67 },
|
||||
{ "shmget", 29 },
|
||||
{ "shutdown", 48 },
|
||||
{ "sigaltstack", 131 },
|
||||
{ "signalfd", 282 },
|
||||
{ "signalfd4", 289 },
|
||||
{ "socket", 41 },
|
||||
{ "socketpair", 53 },
|
||||
{ "splice", 275 },
|
||||
{ "stat", 4 },
|
||||
{ "statfs", 137 },
|
||||
{ "statx", 332 },
|
||||
{ "swapoff", 168 },
|
||||
{ "swapon", 167 },
|
||||
{ "symlink", 88 },
|
||||
{ "symlinkat", 266 },
|
||||
{ "sync", 162 },
|
||||
{ "sync_file_range", 277 },
|
||||
{ "syncfs", 306 },
|
||||
{ "sysfs", 139 },
|
||||
{ "sysinfo", 99 },
|
||||
{ "syslog", 103 },
|
||||
{ "tee", 276 },
|
||||
{ "tgkill", 234 },
|
||||
{ "time", 201 },
|
||||
{ "timer_create", 222 },
|
||||
{ "timer_delete", 226 },
|
||||
{ "timer_getoverrun", 225 },
|
||||
{ "timer_gettime", 224 },
|
||||
{ "timer_settime", 223 },
|
||||
{ "timerfd_create", 283 },
|
||||
{ "timerfd_gettime", 287 },
|
||||
{ "timerfd_settime", 286 },
|
||||
{ "times", 100 },
|
||||
{ "tkill", 200 },
|
||||
{ "truncate", 76 },
|
||||
{ "tuxcall", 184 },
|
||||
{ "umask", 95 },
|
||||
{ "umount2", 166 },
|
||||
{ "uname", 63 },
|
||||
{ "unlink", 87 },
|
||||
{ "unlinkat", 263 },
|
||||
{ "unshare", 272 },
|
||||
{ "uselib", 134 },
|
||||
{ "userfaultfd", 323 },
|
||||
{ "ustat", 136 },
|
||||
{ "utime", 132 },
|
||||
{ "utimensat", 280 },
|
||||
{ "utimes", 235 },
|
||||
{ "vfork", 58 },
|
||||
{ "vhangup", 153 },
|
||||
{ "vmsplice", 278 },
|
||||
{ "vserver", 236 },
|
||||
{ "wait4", 61 },
|
||||
{ "waitid", 247 },
|
||||
{ "write", 1 },
|
||||
{ "writev", 20 },
|
||||
|
|
@ -17,9 +17,11 @@
|
|||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#include "fseccomp.h"
|
||||
#include "../include/syscall.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
//#include <attr/xattr.h>
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -18,9 +18,13 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#define _GNU_SOURCE
|
||||
#include "fseccomp.h"
|
||||
#include "../include/syscall.h"
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/syscall.h>
|
||||
#include "../include/common.h"
|
||||
|
||||
typedef struct {
|
||||
const char * const name;
|
||||
|
|
@ -39,15 +43,29 @@ typedef struct {
|
|||
int syscall;
|
||||
} SyscallCheckList;
|
||||
|
||||
// Native syscalls (64 bit versions for 64 bit arch etc)
|
||||
static const SyscallEntry syslist[] = {
|
||||
//
|
||||
// code generated using tools/extract-syscall
|
||||
//
|
||||
#include "../include/syscall.h"
|
||||
//
|
||||
// end of generated code
|
||||
//
|
||||
}; // end of syslist
|
||||
#if defined(__x86_64__)
|
||||
// code generated using
|
||||
// awk '/__NR_/ { print "{ \"" gensub("__NR_", "", "g", $2) "\", " $3 " },"; }' < /usr/include/x86_64-linux-gnu/asm/unistd_64.h
|
||||
#include "../include/syscall_x86_64.h"
|
||||
#elif defined(__i386__)
|
||||
// awk '/__NR_/ { print "{ \"" gensub("__NR_", "", "g", $2) "\", " $3 " },"; }' < /usr/include/x86_64-linux-gnu/asm/unistd_32.h
|
||||
#include "../include/syscall_i386.h"
|
||||
#else
|
||||
#warning "Please submit a syscall table for your architecture"
|
||||
#endif
|
||||
};
|
||||
|
||||
// 32 bit syscalls for 64 bit arch
|
||||
static const SyscallEntry syslist32[] = {
|
||||
#if defined(__x86_64__)
|
||||
#include "../include/syscall_i386.h"
|
||||
// TODO for other 64 bit archs
|
||||
#elif defined(__i386__) || defined(__arm__) || defined(__powerpc__)
|
||||
// no secondary arch for 32 bit archs
|
||||
#endif
|
||||
};
|
||||
|
||||
static const SyscallGroupList sysgroups[] = {
|
||||
{ .name = "@aio", .list =
|
||||
|
|
@ -1424,6 +1442,17 @@ static int syscall_find_name(const char *name) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int syscall_find_name_32(const char *name) {
|
||||
int i;
|
||||
int elems = sizeof(syslist32) / sizeof(syslist32[0]);
|
||||
for (i = 0; i < elems; i++) {
|
||||
if (strcmp(name, syslist32[i].name) == 0)
|
||||
return syslist32[i].nr;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *syscall_find_nr(int nr) {
|
||||
int i;
|
||||
int elems = sizeof(syslist) / sizeof(syslist[0]);
|
||||
|
|
@ -1435,6 +1464,17 @@ const char *syscall_find_nr(int nr) {
|
|||
return "unknown";
|
||||
}
|
||||
|
||||
const char *syscall_find_nr_32(int nr) {
|
||||
int i;
|
||||
int elems = sizeof(syslist32) / sizeof(syslist32[0]);
|
||||
for (i = 0; i < elems; i++) {
|
||||
if (nr == syslist32[i].nr)
|
||||
return syslist32[i].name;
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
void syscall_print(void) {
|
||||
int i;
|
||||
int elems = sizeof(syslist) / sizeof(syslist[0]);
|
||||
|
|
@ -1444,6 +1484,15 @@ void syscall_print(void) {
|
|||
printf("\n");
|
||||
}
|
||||
|
||||
void syscall_print_32(void) {
|
||||
int i;
|
||||
int elems = sizeof(syslist32) / sizeof(syslist32[0]);
|
||||
for (i = 0; i < elems; i++) {
|
||||
printf("%d\t- %s\n", syslist32[i].nr, syslist32[i].name);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static const char *syscall_find_group(const char *name) {
|
||||
int i;
|
||||
int elems = sizeof(sysgroups) / sizeof(sysgroups[0]);
|
||||
|
|
@ -1458,7 +1507,7 @@ static const char *syscall_find_group(const char *name) {
|
|||
// allowed input:
|
||||
// - syscall
|
||||
// - syscall(error)
|
||||
static void syscall_process_name(const char *name, int *syscall_nr, int *error_nr) {
|
||||
static void syscall_process_name(const char *name, int *syscall_nr, int *error_nr, bool native) {
|
||||
assert(name);
|
||||
if (strlen(name) == 0)
|
||||
goto error;
|
||||
|
|
@ -1482,8 +1531,12 @@ static void syscall_process_name(const char *name, int *syscall_nr, int *error_n
|
|||
|
||||
if (*syscall_name == '$')
|
||||
*syscall_nr = strtol(syscall_name + 1, NULL, 0);
|
||||
else
|
||||
*syscall_nr = syscall_find_name(syscall_name);
|
||||
else {
|
||||
if (native)
|
||||
*syscall_nr = syscall_find_name(syscall_name);
|
||||
else
|
||||
*syscall_nr = syscall_find_name_32(syscall_name);
|
||||
}
|
||||
if (error_name) {
|
||||
*error_nr = errno_find_name(error_name);
|
||||
if (*error_nr == -1)
|
||||
|
|
@ -1499,7 +1552,7 @@ error:
|
|||
}
|
||||
|
||||
// return 1 if error, 0 if OK
|
||||
int syscall_check_list(const char *slist, void (*callback)(int fd, int syscall, int arg, void *ptrarg), int fd, int arg, void *ptrarg) {
|
||||
int syscall_check_list(const char *slist, filter_fn *callback, int fd, int arg, void *ptrarg, bool native) {
|
||||
// don't allow empty lists
|
||||
if (slist == NULL || *slist == '\0') {
|
||||
fprintf(stderr, "Error fseccomp: empty syscall lists are not allowed\n");
|
||||
|
|
@ -1527,7 +1580,7 @@ int syscall_check_list(const char *slist, void (*callback)(int fd, int syscall,
|
|||
fprintf(stderr, "Error fseccomp: unknown syscall group %s\n", ptr);
|
||||
exit(1);
|
||||
}
|
||||
syscall_check_list(new_list, callback, fd, arg, ptrarg);
|
||||
syscall_check_list(new_list, callback, fd, arg, ptrarg, native);
|
||||
}
|
||||
else {
|
||||
bool negate = false;
|
||||
|
|
@ -1535,20 +1588,20 @@ int syscall_check_list(const char *slist, void (*callback)(int fd, int syscall,
|
|||
negate = true;
|
||||
ptr++;
|
||||
}
|
||||
syscall_process_name(ptr, &syscall_nr, &error_nr);
|
||||
syscall_process_name(ptr, &syscall_nr, &error_nr, native);
|
||||
if (syscall_nr == -1) {;}
|
||||
else if (callback != NULL) {
|
||||
if (negate) {
|
||||
syscall_nr = -syscall_nr;
|
||||
}
|
||||
if (error_nr != -1 && fd != 0) {
|
||||
filter_add_errno(fd, syscall_nr, error_nr, ptrarg);
|
||||
if (error_nr != -1 && fd > 0) {
|
||||
filter_add_errno(fd, syscall_nr, error_nr, ptrarg, native);
|
||||
}
|
||||
else if (error_nr != -1 && fd == 0) {
|
||||
callback(fd, syscall_nr, error_nr, ptrarg);
|
||||
callback(fd, syscall_nr, error_nr, ptrarg, native);
|
||||
}
|
||||
else {
|
||||
callback(fd, syscall_nr, arg, ptrarg);
|
||||
callback(fd, syscall_nr, arg, ptrarg, native);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1559,41 +1612,50 @@ int syscall_check_list(const char *slist, void (*callback)(int fd, int syscall,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void find_syscall(int fd, int syscall, int arg, void *ptrarg) {
|
||||
static void find_syscall(int fd, int syscall, int arg, void *ptrarg, bool native) {
|
||||
(void)fd;
|
||||
(void) arg;
|
||||
(void)native;
|
||||
SyscallCheckList *ptr = ptrarg;
|
||||
if (abs(syscall) == ptr->syscall)
|
||||
ptr->found = true;
|
||||
}
|
||||
|
||||
// go through list2 and find matches for problem syscall
|
||||
static void syscall_in_list(int fd, int syscall, int arg, void *ptrarg) {
|
||||
static void syscall_in_list(int fd, int syscall, int arg, void *ptrarg, bool native) {
|
||||
(void) fd;
|
||||
(void)arg;
|
||||
SyscallCheckList *ptr = ptrarg;
|
||||
SyscallCheckList sl;
|
||||
const char *name;
|
||||
|
||||
sl.found = false;
|
||||
sl.syscall = syscall;
|
||||
syscall_check_list(ptr->slist, find_syscall, fd, 0, &sl);
|
||||
syscall_check_list(ptr->slist, find_syscall, fd, 0, &sl, native);
|
||||
|
||||
if (native)
|
||||
name = syscall_find_nr(syscall);
|
||||
else
|
||||
name = syscall_find_nr_32(syscall);
|
||||
|
||||
// if found in the problem list, add to post-exec list
|
||||
if (sl.found) {
|
||||
if (ptr->postlist) {
|
||||
if (asprintf(&ptr->postlist, "%s,%s", ptr->postlist, syscall_find_nr(syscall)) == -1)
|
||||
if (asprintf(&ptr->postlist, "%s,%s", ptr->postlist, name) == -1)
|
||||
errExit("asprintf");
|
||||
}
|
||||
else
|
||||
ptr->postlist = strdup(syscall_find_nr(syscall));
|
||||
ptr->postlist = strdup(name);
|
||||
}
|
||||
else { // no problem, add to pre-exec list
|
||||
// build syscall:error_no
|
||||
char *newcall = NULL;
|
||||
if (arg != 0) {
|
||||
if (asprintf(&newcall, "%s:%s", syscall_find_nr(syscall), errno_find_nr(arg)) == -1)
|
||||
if (asprintf(&newcall, "%s:%s", name, errno_find_nr(arg)) == -1)
|
||||
errExit("asprintf");
|
||||
}
|
||||
else {
|
||||
newcall = strdup(syscall_find_nr(syscall));
|
||||
newcall = strdup(name);
|
||||
if (!newcall)
|
||||
errExit("strdup");
|
||||
}
|
||||
|
|
@ -1609,14 +1671,14 @@ static void syscall_in_list(int fd, int syscall, int arg, void *ptrarg) {
|
|||
}
|
||||
|
||||
// go through list and find matches for syscalls in list @default-keep
|
||||
void syscalls_in_list(const char *list, const char *slist, int fd, char **prelist, char **postlist) {
|
||||
void syscalls_in_list(const char *list, const char *slist, int fd, char **prelist, char **postlist, bool native) {
|
||||
(void) fd;
|
||||
SyscallCheckList sl;
|
||||
// these syscalls are used by firejail after the seccomp filter is initialized
|
||||
sl.slist = slist;
|
||||
sl.prelist = NULL;
|
||||
sl.postlist = NULL;
|
||||
syscall_check_list(list, syscall_in_list, 0, 0, &sl);
|
||||
syscall_check_list(list, syscall_in_list, 0, 0, &sl, native);
|
||||
if (!arg_quiet) {
|
||||
printf("Seccomp list in: %s,", list);
|
||||
if (sl.slist)
|
||||
|
|
@ -386,19 +386,31 @@ first argument to socket system call. Recognized values: \fBunix\fR,
|
|||
\fBseccomp
|
||||
Enable seccomp filter and blacklist the syscalls in the default list. See man 1 firejail for more details.
|
||||
.TP
|
||||
\fBseccomp.32
|
||||
Enable seccomp filter and blacklist the syscalls in the default list for 32 bit system calls on a 64 bit architecture system.
|
||||
.TP
|
||||
\fBseccomp syscall,syscall,syscall
|
||||
Enable seccomp filter and blacklist the system calls in the list on top of default seccomp filter.
|
||||
.TP
|
||||
\fBseccomp.32 syscall,syscall,syscall
|
||||
Enable seccomp filter and blacklist the system calls in the list on top of default seccomp filter for 32 bit system calls on a 64 bit architecture system.
|
||||
.TP
|
||||
\fBseccomp.block-secondary
|
||||
Enable seccomp filter and filter system call architectures
|
||||
so that only the native architecture is allowed.
|
||||
.TP
|
||||
\fBseccomp.drop syscall,syscall,syscall
|
||||
Enable seccomp filter and blacklist the system calls in the list.
|
||||
Enable seccomp filter and blacklist the system calls in the list.
|
||||
.TP
|
||||
\fBseccomp.32.drop syscall,syscall,syscall
|
||||
Enable seccomp filter and blacklist the system calls in the list for 32 bit system calls on a 64 bit architecture system.
|
||||
.TP
|
||||
\fBseccomp.keep syscall,syscall,syscall
|
||||
Enable seccomp filter and whitelist the system calls in the list.
|
||||
.TP
|
||||
\fBseccomp.32.keep syscall,syscall,syscall
|
||||
Enable seccomp filter and whitelist the system calls in the list for 32 bit system calls on a 64 bit architecture system.
|
||||
.TP
|
||||
\fBx11
|
||||
Enable X11 sandboxing.
|
||||
.TP
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ firejail {\-\-list | \-\-netstats | \-\-top | \-\-tree}
|
|||
Miscellaneous:
|
||||
.PP
|
||||
.RS
|
||||
firejail {\-? | \-\-debug-caps | \-\-debug-errnos | \-\-debug-syscalls | \-\-debug-protocols | \-\-help | \-\-version}
|
||||
firejail {\-? | \-\-debug-caps | \-\-debug-errnos | \-\-debug-syscalls | \-\-debug-syscalls32 | \-\-debug-protocols | \-\-help | \-\-version}
|
||||
.RE
|
||||
.SH DESCRIPTION
|
||||
Firejail is a SUID sandbox program that reduces the risk of security breaches by
|
||||
|
|
@ -386,6 +386,10 @@ Example:
|
|||
.br
|
||||
$ firejail \-\-debug-syscalls
|
||||
.TP
|
||||
\fB\-\-debug-syscalls32
|
||||
Print all recognized 32 bit system calls in the current Firejail software build and exit.
|
||||
.br
|
||||
.TP
|
||||
\fB\-\-debug-whitelists\fR
|
||||
Debug whitelisting.
|
||||
.br
|
||||
|
|
@ -1832,7 +1836,9 @@ Exceptions can be allowed with prefix !.
|
|||
System architecture is strictly imposed only if flag
|
||||
\-\-seccomp.block-secondary is used. The filter is applied at run time
|
||||
only if the correct architecture was detected. For the case of I386
|
||||
and AMD64 both 32-bit and 64-bit filters are installed.
|
||||
and AMD64 both 32-bit and 64-bit filters are installed. On a 64 bit
|
||||
architecture, an additional filter for 32 bit system calls can be
|
||||
installed with \-\-seccomp.32.
|
||||
.br
|
||||
|
||||
.br
|
||||
|
|
@ -1881,7 +1887,8 @@ rm: cannot remove `testfile': Operation not permitted
|
|||
.br
|
||||
If the blocked system calls would also block Firejail from operating,
|
||||
they are handled by adding a preloaded library which performs seccomp
|
||||
system calls later.
|
||||
system calls later. However, this is incompatible with 32 bit seccomp
|
||||
filters.
|
||||
.br
|
||||
|
||||
.br
|
||||
|
|
@ -1912,7 +1919,10 @@ domain with personality(2) system call.
|
|||
|
||||
.TP
|
||||
\fB\-\-seccomp.drop=syscall,@group
|
||||
Enable seccomp filter, and blacklist the syscalls or the syscall groups specified by the command.
|
||||
Enable seccomp filter, and blacklist the syscalls or the syscall
|
||||
groups specified by the command. On a 64 bit architecture, an
|
||||
additional filter for 32 bit system calls can be installed with
|
||||
\-\-seccomp.32.drop.
|
||||
.br
|
||||
|
||||
.br
|
||||
|
|
@ -1950,7 +1960,9 @@ rm: cannot remove `testfile': Operation not permitted
|
|||
\fB\-\-seccomp.keep=syscall,@group,!syscall2
|
||||
Enable seccomp filter, blacklist all syscall not listed and "syscall2".
|
||||
The system calls needed by Firejail (group @default-keep: prctl, execve)
|
||||
are handled with the preload library.
|
||||
are handled with the preload library. On a 64 bit architecture, an
|
||||
additional filter for 32 bit system calls can be installed with
|
||||
\-\-seccomp.32.keep.
|
||||
.br
|
||||
|
||||
.br
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue