Commit d01216de authored by Topi Miettinen's avatar Topi Miettinen

Feature: switch/config option to block secondary architectures

Add a feature for a new (opt-in) command line switch and config file
option to block secondary architectures entirely. Also block changing
Linux execution domain with personality() system call for the primary
architecture.

Closes #1479
parent 0b768c04
...@@ -30,4 +30,5 @@ seccomp ...@@ -30,4 +30,5 @@ seccomp
seccomp.debug seccomp.debug
seccomp.i386 seccomp.i386
seccomp.amd64 seccomp.amd64
seccomp.block_secondary
seccomp.mdwx seccomp.mdwx
...@@ -2,7 +2,7 @@ all: apps man filters ...@@ -2,7 +2,7 @@ all: apps man filters
MYLIBS = src/lib MYLIBS = src/lib
APPS = src/firejail src/firemon src/firecfg src/libtrace src/libtracelog src/ftee src/faudit src/fnet src/fseccomp src/fcopy src/fldd src/libpostexecseccomp APPS = src/firejail src/firemon src/firecfg src/libtrace src/libtracelog src/ftee src/faudit src/fnet src/fseccomp src/fcopy src/fldd src/libpostexecseccomp
MANPAGES = firejail.1 firemon.1 firecfg.1 firejail-profile.5 firejail-login.5 MANPAGES = firejail.1 firemon.1 firecfg.1 firejail-profile.5 firejail-login.5
SECCOMP_FILTERS = seccomp seccomp.i386 seccomp.amd64 SECCOMP_FILTERS = seccomp seccomp.debug seccomp.i386 seccomp.amd64 seccomp.block_secondary seccomp.mwdx
prefix=@prefix@ prefix=@prefix@
exec_prefix=@exec_prefix@ exec_prefix=@exec_prefix@
...@@ -45,6 +45,7 @@ ifeq ($(HAVE_SECCOMP),-DHAVE_SECCOMP) ...@@ -45,6 +45,7 @@ ifeq ($(HAVE_SECCOMP),-DHAVE_SECCOMP)
src/fseccomp/fseccomp default seccomp.debug allow-debuggers src/fseccomp/fseccomp default seccomp.debug allow-debuggers
src/fseccomp/fseccomp secondary 32 seccomp.i386 src/fseccomp/fseccomp secondary 32 seccomp.i386
src/fseccomp/fseccomp secondary 64 seccomp.amd64 src/fseccomp/fseccomp secondary 64 seccomp.amd64
src/fseccomp/fseccomp secondary block seccomp.block_secondary
src/fseccomp/fseccomp memory-deny-write-execute seccomp.mdwx src/fseccomp/fseccomp memory-deny-write-execute seccomp.mdwx
endif endif
...@@ -53,7 +54,7 @@ clean: ...@@ -53,7 +54,7 @@ clean:
$(MAKE) -C $$dir clean; \ $(MAKE) -C $$dir clean; \
done done
rm -f $(MANPAGES) $(MANPAGES:%=%.gz) firejail*.rpm rm -f $(MANPAGES) $(MANPAGES:%=%.gz) firejail*.rpm
rm -f seccomp seccomp.debug seccomp.i386 seccomp.amd64 seccomp.mdwx rm -f $(SECCOMP_FILTERS)
rm -f test/utils/index.html* rm -f test/utils/index.html*
rm -f test/utils/wget-log rm -f test/utils/wget-log
rm -f test/utils/lstesting rm -f test/utils/lstesting
...@@ -104,6 +105,7 @@ ifeq ($(HAVE_SECCOMP),-DHAVE_SECCOMP) ...@@ -104,6 +105,7 @@ ifeq ($(HAVE_SECCOMP),-DHAVE_SECCOMP)
install -c -m 0644 seccomp.debug $(DESTDIR)/$(libdir)/firejail/. install -c -m 0644 seccomp.debug $(DESTDIR)/$(libdir)/firejail/.
install -c -m 0644 seccomp.i386 $(DESTDIR)/$(libdir)/firejail/. install -c -m 0644 seccomp.i386 $(DESTDIR)/$(libdir)/firejail/.
install -c -m 0644 seccomp.amd64 $(DESTDIR)/$(libdir)/firejail/. install -c -m 0644 seccomp.amd64 $(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 $(DESTDIR)/$(libdir)/firejail/.
endif endif
ifeq ($(HAVE_CONTRIB_INSTALL),yes) ifeq ($(HAVE_CONTRIB_INSTALL),yes)
......
...@@ -57,12 +57,14 @@ ...@@ -57,12 +57,14 @@
#define RUN_SECCOMP_AMD64 "/run/firejail/mnt/seccomp.amd64" // amd64 filter installed on i386 architectures #define RUN_SECCOMP_AMD64 "/run/firejail/mnt/seccomp.amd64" // amd64 filter installed on i386 architectures
#define RUN_SECCOMP_I386 "/run/firejail/mnt/seccomp.i386" // i386 filter installed on amd64 architectures #define RUN_SECCOMP_I386 "/run/firejail/mnt/seccomp.i386" // i386 filter installed on amd64 architectures
#define RUN_SECCOMP_MDWX "/run/firejail/mnt/seccomp.mdwx" // filter for memory-deny-write-execute #define RUN_SECCOMP_MDWX "/run/firejail/mnt/seccomp.mdwx" // filter for memory-deny-write-execute
#define RUN_SECCOMP_BLOCK_SECONDARY "/run/firejail/mnt/seccomp.block_secondary" // secondary arch blocking filter
#define RUN_SECCOMP_POSTEXEC "/run/firejail/mnt/seccomp.postexec" // filter for post-exec library #define RUN_SECCOMP_POSTEXEC "/run/firejail/mnt/seccomp.postexec" // filter for post-exec library
#define PATH_SECCOMP_DEFAULT (LIBDIR "/firejail/seccomp") // default filter built during make #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") // default filter built during make
#define PATH_SECCOMP_AMD64 (LIBDIR "/firejail/seccomp.amd64") // amd64 filter built during make #define PATH_SECCOMP_AMD64 (LIBDIR "/firejail/seccomp.amd64") // amd64 filter built during make
#define PATH_SECCOMP_I386 (LIBDIR "/firejail/seccomp.i386") // i386 filter built during make #define PATH_SECCOMP_I386 (LIBDIR "/firejail/seccomp.i386") // i386 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 (LIBDIR "/firejail/seccomp.mdwx") // filter for memory-deny-write-execute built during make
#define PATH_SECCOMP_BLOCK_SECONDARY (LIBDIR "/firejail/seccomp.block_secondary") // secondary arch blocking filter built during make
#define RUN_DEV_DIR "/run/firejail/mnt/dev" #define RUN_DEV_DIR "/run/firejail/mnt/dev"
...@@ -307,6 +309,7 @@ extern int arg_overlay_reuse; // allow the reuse of overlays ...@@ -307,6 +309,7 @@ extern int arg_overlay_reuse; // allow the reuse of overlays
extern int arg_seccomp; // enable default seccomp filter extern int arg_seccomp; // enable default seccomp filter
extern int arg_seccomp_postexec; // need postexec ld.preload library? extern int arg_seccomp_postexec; // need postexec ld.preload library?
extern int arg_seccomp_block_secondary; // block any secondary architectures
extern int arg_caps_default_filter; // enable default capabilities filter extern int arg_caps_default_filter; // enable default capabilities filter
extern int arg_caps_drop; // drop list extern int arg_caps_drop; // drop list
...@@ -538,8 +541,6 @@ void fs_private_home_list(void); ...@@ -538,8 +541,6 @@ void fs_private_home_list(void);
char *seccomp_check_list(const char *str); char *seccomp_check_list(const char *str);
int seccomp_install_filters(void); int seccomp_install_filters(void);
int seccomp_load(const char *fname); int seccomp_load(const char *fname);
void seccomp_filter_32(void);
void seccomp_filter_64(void);
int seccomp_filter_drop(int enforce_seccomp); int seccomp_filter_drop(int enforce_seccomp);
int seccomp_filter_keep(void); int seccomp_filter_keep(void);
void seccomp_print_filter(pid_t pid); void seccomp_print_filter(pid_t pid);
......
...@@ -57,6 +57,7 @@ int arg_overlay_reuse = 0; // allow the reuse of overlays ...@@ -57,6 +57,7 @@ int arg_overlay_reuse = 0; // allow the reuse of overlays
int arg_seccomp = 0; // enable default seccomp filter int arg_seccomp = 0; // enable default seccomp filter
int arg_seccomp_postexec = 0; // need postexec ld.preload library? int arg_seccomp_postexec = 0; // need postexec ld.preload library?
int arg_seccomp_block_secondary = 0; // block any secondary architectures
int arg_caps_default_filter = 0; // enable default capabilities filter int arg_caps_default_filter = 0; // enable default capabilities filter
int arg_caps_drop = 0; // drop list int arg_caps_drop = 0; // drop list
...@@ -1147,6 +1148,13 @@ int main(int argc, char **argv) { ...@@ -1147,6 +1148,13 @@ int main(int argc, char **argv) {
else else
exit_err_feature("seccomp"); exit_err_feature("seccomp");
} }
else if (strcmp(argv[i], "--seccomp.block-secondary") == 0) {
if (checkcfg(CFG_SECCOMP)) {
arg_seccomp_block_secondary = 1;
}
else
exit_err_feature("seccomp");
}
else if (strcmp(argv[i], "--memory-deny-write-execute") == 0) { else if (strcmp(argv[i], "--memory-deny-write-execute") == 0) {
if (checkcfg(CFG_SECCOMP)) if (checkcfg(CFG_SECCOMP))
arg_memory_deny_write_execute = 1; arg_memory_deny_write_execute = 1;
...@@ -2239,6 +2247,10 @@ int main(int argc, char **argv) { ...@@ -2239,6 +2247,10 @@ int main(int argc, char **argv) {
} }
} }
// enable seccomp if only seccomp.block-secondary was specified
if (arg_seccomp_block_secondary)
arg_seccomp = 1;
// log command // log command
logargs(argc, argv); logargs(argc, argv);
if (fullargc) { if (fullargc) {
......
...@@ -75,9 +75,13 @@ void preproc_mount_mnt_dir(void) { ...@@ -75,9 +75,13 @@ void preproc_mount_mnt_dir(void) {
tmpfs_mounted = 1; tmpfs_mounted = 1;
fs_logger2("tmpfs", RUN_MNT_DIR); fs_logger2("tmpfs", RUN_MNT_DIR);
//copy defaultl seccomp files if (arg_seccomp_block_secondary)
copy_file(PATH_SECCOMP_I386, RUN_SECCOMP_I386, getuid(), getgid(), 0644); // root needed copy_file(PATH_SECCOMP_BLOCK_SECONDARY, RUN_SECCOMP_BLOCK_SECONDARY, getuid(), getgid(), 0644); // root needed
copy_file(PATH_SECCOMP_AMD64, RUN_SECCOMP_AMD64, getuid(), getgid(), 0644); // root needed else {
//copy default seccomp files
copy_file(PATH_SECCOMP_I386, RUN_SECCOMP_I386, getuid(), getgid(), 0644); // root needed
copy_file(PATH_SECCOMP_AMD64, RUN_SECCOMP_AMD64, 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 copy_file(PATH_SECCOMP_DEFAULT_DEBUG, RUN_SECCOMP_CFG, getuid(), getgid(), 0644); // root needed
else else
......
...@@ -577,6 +577,16 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { ...@@ -577,6 +577,16 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
return 0; return 0;
} }
if (strcmp(ptr, "seccomp.block-secondary") == 0) {
#ifdef HAVE_SECCOMP
if (checkcfg(CFG_SECCOMP)) {
arg_seccomp_block_secondary = 1;
}
else
warning_feature_disabled("seccomp");
#endif
return 0;
}
// seccomp drop list without default list // seccomp drop list without default list
if (strncmp(ptr, "seccomp.drop ", 13) == 0) { if (strncmp(ptr, "seccomp.drop ", 13) == 0) {
#ifdef HAVE_SECCOMP #ifdef HAVE_SECCOMP
......
...@@ -118,7 +118,7 @@ errexit: ...@@ -118,7 +118,7 @@ errexit:
} }
// i386 filter installed on amd64 architectures // i386 filter installed on amd64 architectures
void seccomp_filter_32(void) { static void seccomp_filter_32(void) {
if (seccomp_load(RUN_SECCOMP_I386) == 0) { if (seccomp_load(RUN_SECCOMP_I386) == 0) {
if (arg_debug) if (arg_debug)
printf("Dual i386/amd64 seccomp filter configured\n"); printf("Dual i386/amd64 seccomp filter configured\n");
...@@ -126,13 +126,20 @@ void seccomp_filter_32(void) { ...@@ -126,13 +126,20 @@ void seccomp_filter_32(void) {
} }
// amd64 filter installed on i386 architectures // amd64 filter installed on i386 architectures
void seccomp_filter_64(void) { static void seccomp_filter_64(void) {
if (seccomp_load(RUN_SECCOMP_AMD64) == 0) { if (seccomp_load(RUN_SECCOMP_AMD64) == 0) {
if (arg_debug) if (arg_debug)
printf("Dual i386/amd64 seccomp filter configured\n"); printf("Dual i386/amd64 seccomp filter configured\n");
} }
} }
static void seccomp_filter_block_secondary(void) {
if (seccomp_load(RUN_SECCOMP_BLOCK_SECONDARY) == 0) {
if (arg_debug)
printf("Secondary arch blocking seccomp filter configured\n");
}
}
// drop filter for seccomp option // drop filter for seccomp option
int seccomp_filter_drop(int enforce_seccomp) { int seccomp_filter_drop(int enforce_seccomp) {
// if we have multiple seccomp commands, only one of them is executed // if we have multiple seccomp commands, only one of them is executed
...@@ -143,21 +150,29 @@ int seccomp_filter_drop(int enforce_seccomp) { ...@@ -143,21 +150,29 @@ int seccomp_filter_drop(int enforce_seccomp) {
if (cfg.seccomp_list_drop == NULL) { if (cfg.seccomp_list_drop == NULL) {
// default seccomp // default seccomp
if (cfg.seccomp_list == NULL) { if (cfg.seccomp_list == NULL) {
if (arg_seccomp_block_secondary)
seccomp_filter_block_secondary();
else {
#if defined(__x86_64__) #if defined(__x86_64__)
seccomp_filter_32(); seccomp_filter_32();
#endif #endif
#if defined(__i386__) #if defined(__i386__)
seccomp_filter_64(); seccomp_filter_64();
#endif #endif
}
} }
// default seccomp filter with additional drop list // default seccomp filter with additional drop list
else { // cfg.seccomp_list != NULL else { // cfg.seccomp_list != NULL
if (arg_seccomp_block_secondary)
seccomp_filter_block_secondary();
else {
#if defined(__x86_64__) #if defined(__x86_64__)
seccomp_filter_32(); seccomp_filter_32();
#endif #endif
#if defined(__i386__) #if defined(__i386__)
seccomp_filter_64(); seccomp_filter_64();
#endif #endif
}
if (arg_debug) if (arg_debug)
printf("Build default+drop seccomp filter\n"); printf("Build default+drop seccomp filter\n");
...@@ -175,7 +190,10 @@ int seccomp_filter_drop(int enforce_seccomp) { ...@@ -175,7 +190,10 @@ int seccomp_filter_drop(int enforce_seccomp) {
} }
// drop list without defaults - secondary filters are not installed // drop list without defaults - secondary filters are not installed
// except when secondary architectures are explicitly blocked
else { // cfg.seccomp_list_drop != NULL else { // cfg.seccomp_list_drop != NULL
if (arg_seccomp_block_secondary)
seccomp_filter_block_secondary();
if (arg_debug) if (arg_debug)
printf("Build drop seccomp filter\n"); printf("Build drop seccomp filter\n");
...@@ -216,6 +234,11 @@ int seccomp_filter_drop(int enforce_seccomp) { ...@@ -216,6 +234,11 @@ int seccomp_filter_drop(int enforce_seccomp) {
// keep filter for seccomp option // keep filter for seccomp option
int seccomp_filter_keep(void) { int seccomp_filter_keep(void) {
// secondary filters are not installed except when secondary
// architectures are explicitly blocked
if (arg_seccomp_block_secondary)
seccomp_filter_block_secondary();
if (arg_debug) if (arg_debug)
printf("Build drop seccomp filter\n"); printf("Build drop seccomp filter\n");
......
...@@ -46,6 +46,7 @@ void protocol_build_filter(const char *prlist, const char *fname); ...@@ -46,6 +46,7 @@ void protocol_build_filter(const char *prlist, const char *fname);
// seccomp_secondary.c // seccomp_secondary.c
void seccomp_secondary_64(const char *fname); void seccomp_secondary_64(const char *fname);
void seccomp_secondary_32(const char *fname); void seccomp_secondary_32(const char *fname);
void seccomp_secondary_block(const char *fname);
// seccomp_file.c // seccomp_file.c
void write_to_file(int fd, const void *data, int size); void write_to_file(int fd, const void *data, int size);
......
...@@ -28,6 +28,7 @@ static void usage(void) { ...@@ -28,6 +28,7 @@ static void usage(void) {
printf("\tfseccomp protocol build list file\n"); printf("\tfseccomp protocol build list file\n");
printf("\tfseccomp secondary 64 file\n"); printf("\tfseccomp secondary 64 file\n");
printf("\tfseccomp secondary 32 file\n"); printf("\tfseccomp secondary 32 file\n");
printf("\tfseccomp secondary block file\n");
printf("\tfseccomp default file\n"); printf("\tfseccomp default file\n");
printf("\tfseccomp default file allow-debuggers\n"); printf("\tfseccomp default file allow-debuggers\n");
printf("\tfseccomp drop file1 file2 list\n"); printf("\tfseccomp drop file1 file2 list\n");
...@@ -74,6 +75,8 @@ printf("\n"); ...@@ -74,6 +75,8 @@ printf("\n");
seccomp_secondary_64(argv[3]); seccomp_secondary_64(argv[3]);
else if (argc == 4 && strcmp(argv[1], "secondary") == 0 && strcmp(argv[2], "32") == 0) else if (argc == 4 && strcmp(argv[1], "secondary") == 0 && strcmp(argv[2], "32") == 0)
seccomp_secondary_32(argv[3]); seccomp_secondary_32(argv[3]);
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) else if (argc == 3 && strcmp(argv[1], "default") == 0)
seccomp_default(argv[2], 0); seccomp_default(argv[2], 0);
else if (argc == 4 && strcmp(argv[1], "default") == 0 && strcmp(argv[3], "allow-debuggers") == 0) else if (argc == 4 && strcmp(argv[1], "default") == 0 && strcmp(argv[3], "allow-debuggers") == 0)
......
...@@ -113,6 +113,25 @@ static int detect_filter_type(void) { ...@@ -113,6 +113,25 @@ static int detect_filter_type(void) {
printf(" EXAMINE_SYSCALL\n"); printf(" EXAMINE_SYSCALL\n");
return sizeof(start_secondary_32) / sizeof(struct sock_filter); return sizeof(start_secondary_32) / sizeof(struct sock_filter);
} }
const struct sock_filter start_secondary_block[] = {
VALIDATE_ARCHITECTURE_KILL,
#if defined(__x86_64__)
EXAMINE_SYSCALL,
HANDLE_X32_KILL,
#else
EXAMINE_SYSCALL
#endif
};
if (memcmp(&start_secondary_block[0], filter, sizeof(start_secondary_block)) == 0) {
printf(" VALIDATE_ARCHITECTURE_KILL\n");
printf(" EXAMINE_SYSCALL\n");
#if defined(__x86_64__)
printf(" HANDLE_X32_KILL\n");
#endif
return sizeof(start_secondary_block) / sizeof(struct sock_filter);
}
return 0; // filter unrecognized return 0; // filter unrecognized
} }
......
...@@ -19,8 +19,29 @@ ...@@ -19,8 +19,29 @@
*/ */
#include "fseccomp.h" #include "fseccomp.h"
#include "../include/seccomp.h" #include "../include/seccomp.h"
#include <sys/personality.h>
#include <sys/syscall.h> #include <sys/syscall.h>
static void write_filter(const char *fname, size_t size, const void *filter) {
// save filter to file
int dst = open(fname, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (dst < 0) {
fprintf(stderr, "Error fseccomp: cannot open %s file\n", fname);
exit(1);
}
size_t written = 0;
while (written < size) {
ssize_t rv = write(dst, (unsigned char *) filter + written, size - written);
if (rv == -1) {
fprintf(stderr, "Error fseccomp: cannot write %s file\n", fname);
exit(1);
}
written += rv;
}
close(dst);
}
void seccomp_secondary_64(const char *fname) { void seccomp_secondary_64(const char *fname) {
// hardcoded syscall values // hardcoded syscall values
struct sock_filter filter[] = { struct sock_filter filter[] = {
...@@ -84,23 +105,7 @@ void seccomp_secondary_64(const char *fname) { ...@@ -84,23 +105,7 @@ void seccomp_secondary_64(const char *fname) {
}; };
// save filter to file // save filter to file
int dst = open(fname, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); write_filter(fname, sizeof(filter), filter);
if (dst < 0) {
fprintf(stderr, "Error fseccomp: cannot open %s file\n", fname);
exit(1);
}
int size = (int) sizeof(filter);
int written = 0;
while (written < size) {
int rv = write(dst, (unsigned char *) filter + written, size - written);
if (rv == -1) {
fprintf(stderr, "Error fseccomp: cannot write %s file\n", fname);
exit(1);
}
written += rv;
}
close(dst);
} }
// i386 filter installed on amd64 architectures // i386 filter installed on amd64 architectures
...@@ -166,21 +171,47 @@ void seccomp_secondary_32(const char *fname) { ...@@ -166,21 +171,47 @@ void seccomp_secondary_32(const char *fname) {
}; };
// save filter to file // save filter to file
int dst = open(fname, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); write_filter(fname, sizeof(filter), filter);
if (dst < 0) { }
fprintf(stderr, "Error fseccomp: cannot open %s file\n", fname);
exit(1);
}
int size = (int) sizeof(filter); #define jmp_from_to(from_addr, to_addr) ((to_addr) - (from_addr) - 1)
int written = 0;
while (written < size) { #if __BYTE_ORDER == __BIG_ENDIAN
int rv = write(dst, (unsigned char *) filter + written, size - written); #define MSW 0
if (rv == -1) { #define LSW (sizeof(int))
fprintf(stderr, "Error fseccomp: cannot write %s file\n", fname); #else
exit(1); #define MSW (sizeof(int))
} #define LSW 0
written += rv; #endif
}
close(dst); void seccomp_secondary_block(const char *fname) {
struct sock_filter filter[] = {
// block other architectures
VALIDATE_ARCHITECTURE_KILL,
EXAMINE_SYSCALL,
#if defined(__x86_64__)
// block x32
HANDLE_X32_KILL,
#endif
// block personality(2) where domain != PER_LINUX or 0xffffffff (query current personality)
// 0: if personality(2), continue to 1, else goto 7 (allow)
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, SYS_personality, 0, jmp_from_to(0, 7)),
// 1: get LSW of system call argument 0
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, (offsetof(struct seccomp_data, args[0])) + LSW),
// 2: if LSW(arg0) == PER_LINUX, goto step 4, else continue to 3
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, PER_LINUX, jmp_from_to(2, 4), 0),
// 3: if LSW(arg0) == 0xffffffff, continue to 4, else goto 6 (kill)
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0xffffffff, 0, jmp_from_to(3, 6)),
// 4: get MSW of system call argument 0
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, (offsetof(struct seccomp_data, args[0])) + MSW),
// 5: if MSW(arg0) == 0, goto 7 (allow) else continue to 6 (kill)
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, jmp_from_to(5, 7), 0),
// 6:
KILL_PROCESS,
// 7:
RETURN_ALLOW
};
// save filter to file
write_filter(fname, sizeof(filter), filter);
} }
...@@ -105,6 +105,11 @@ struct seccomp_data { ...@@ -105,6 +105,11 @@ struct seccomp_data {
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ARCH_NR, 1, 0), \ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ARCH_NR, 1, 0), \
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW) BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW)
#define VALIDATE_ARCHITECTURE_KILL \
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, (offsetof(struct seccomp_data, arch))), \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ARCH_NR, 1, 0), \
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL)
#define VALIDATE_ARCHITECTURE_64 \ #define VALIDATE_ARCHITECTURE_64 \
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, (offsetof(struct seccomp_data, arch))), \ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, (offsetof(struct seccomp_data, arch))), \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, AUDIT_ARCH_X86_64, 1, 0), \ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, AUDIT_ARCH_X86_64, 1, 0), \
...@@ -122,6 +127,10 @@ struct seccomp_data { ...@@ -122,6 +127,10 @@ struct seccomp_data {
BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, X32_SYSCALL_BIT, 1, 0), \ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, X32_SYSCALL_BIT, 1, 0), \
BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 0, 1, 0), \ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 0, 1, 0), \
RETURN_ERRNO(EPERM) RETURN_ERRNO(EPERM)
#define HANDLE_X32_KILL \
BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, X32_SYSCALL_BIT, 1, 0), \
BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 0, 1, 0), \
KILL_PROCESS
#endif #endif
#define EXAMINE_SYSCALL BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ #define EXAMINE_SYSCALL BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \
......
...@@ -310,6 +310,10 @@ Enable seccomp filter and blacklist the syscalls in the default list. See man 1 ...@@ -310,6 +310,10 @@ Enable seccomp filter and blacklist the syscalls in the default list. See man 1
\fBseccomp syscall,syscall,syscall \fBseccomp syscall,syscall,syscall
Enable seccomp filter and blacklist the system calls in the list on top of default seccomp filter. Enable seccomp filter and blacklist the system calls in the list on top of default seccomp filter.
.TP .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 \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 .TP
......
...@@ -1572,9 +1572,10 @@ system call can be specified by its number instead of name with prefix ...@@ -1572,9 +1572,10 @@ system call can be specified by its number instead of name with prefix
$, so for example $165 would be equal to mount on i386. $, so for example $165 would be equal to mount on i386.
.br .br
System architecture is not strictly imposed. The filter is applied System architecture is strictly imposed only if flag
at run time only if the correct architecture was detected. For the case of I386 and AMD64 \-\-seccomp.block_secondary is used. The filter is applied at run time
both 32-bit and 64-bit filters are installed. only if the correct architecture was detected. For the case of I386
and AMD64 both 32-bit and 64-bit filters are installed.
.br .br
.br .br
...@@ -1645,6 +1646,14 @@ $ ls ...@@ -1645,6 +1646,14 @@ $ ls
Bad system call Bad system call
.br .br
.TP
\fB\-\-seccomp.block_secondary
Enable seccomp filter and filter system call architectures so that
only the native architecture is allowed. For example, on amd64, i386
and x32 system calls are blocked as well as changing the execution
domain with personality(2) system call.
.br
.TP .TP
\fB\-\-seccomp.drop=syscall,syscall,syscall \fB\-\-seccomp.drop=syscall,syscall,syscall
Enable seccomp filter, and blacklist the syscalls specified by the command. Enable seccomp filter, and blacklist the syscalls specified by the command.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment