diff --git a/configure b/configure index 2649f5fc2..22227cb92 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for firejail 0.9.32-rc1. +# Generated by GNU Autoconf 2.69 for firejail 0.9.32-rc2. # # Report bugs to . # @@ -580,8 +580,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='firejail' PACKAGE_TARNAME='firejail' -PACKAGE_VERSION='0.9.32-rc1' -PACKAGE_STRING='firejail 0.9.32-rc1' +PACKAGE_VERSION='0.9.32-rc2' +PACKAGE_STRING='firejail 0.9.32-rc2' PACKAGE_BUGREPORT='netblue30@yahoo.com' PACKAGE_URL='http://github.com/netblue30/firejail' @@ -1238,7 +1238,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures firejail 0.9.32-rc1 to adapt to many kinds of systems. +\`configure' configures firejail 0.9.32-rc2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1299,7 +1299,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of firejail 0.9.32-rc1:";; + short | recursive ) echo "Configuration of firejail 0.9.32-rc2:";; esac cat <<\_ACEOF @@ -1389,7 +1389,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -firejail configure 0.9.32-rc1 +firejail configure 0.9.32-rc2 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1691,7 +1691,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by firejail $as_me 0.9.32-rc1, which was +It was created by firejail $as_me 0.9.32-rc2, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -4102,7 +4102,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by firejail $as_me 0.9.32-rc1, which was +This file was extended by firejail $as_me 0.9.32-rc2, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4156,7 +4156,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -firejail config.status 0.9.32-rc1 +firejail config.status 0.9.32-rc2 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 971951798..1f33dc35c 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ AC_PREREQ([2.68]) -AC_INIT(firejail, 0.9.32-rc1, netblue30@yahoo.com, , http://github.com/netblue30/firejail) +AC_INIT(firejail, 0.9.32-rc2, netblue30@yahoo.com, , http://github.com/netblue30/firejail) AC_CONFIG_SRCDIR([src/firejail/main.c]) #AC_CONFIG_HEADERS([config.h]) diff --git a/src/firejail/seccomp.c b/src/firejail/seccomp.c index 76e8fc81e..7366c1268 100644 --- a/src/firejail/seccomp.c +++ b/src/firejail/seccomp.c @@ -490,7 +490,7 @@ int seccomp_filter_drop(void) { filter_add_blacklist(SYS_process_vm_writev, 0); #endif -// mknod removed in 0.9.29 +// mknod removed in 0.9.29 - it brakes Zotero extension //#ifdef SYS_mknod // filter_add_blacklist(SYS_mknod, 0); //#endif @@ -520,6 +520,87 @@ int seccomp_filter_drop(void) { #ifdef SYS_kcmp filter_add_blacklist(SYS_kcmp, 0); #endif + +// 0.9.32 +#ifdef SYS_add_key + filter_add_blacklist(SYS_add_key, 0); +#endif +#ifdef SYS_request_key + filter_add_blacklist(SYS_request_key, 0); +#endif +#ifdef SYS_keyctl + filter_add_blacklist(SYS_keyctl, 0); +#endif +#ifdef SYS_uselib + filter_add_blacklist(SYS_uselib, 0); +#endif +#ifdef SYS_acct + filter_add_blacklist(SYS_acct, 0); +#endif +#ifdef SYS_modify_ldt + filter_add_blacklist(SYS_modify_ldt, 0); +#endif + //#ifdef SYS_unshare + // filter_add_blacklist(SYS_unshare, 0); + //#endif +#ifdef SYS_pivot_root + filter_add_blacklist(SYS_pivot_root, 0); +#endif + //#ifdef SYS_quotactl + // filter_add_blacklist(SYS_quotactl, 0); + //#endif +#ifdef SYS_io_setup + filter_add_blacklist(SYS_io_setup, 0); +#endif +#ifdef SYS_io_destroy + filter_add_blacklist(SYS_io_destroy, 0); +#endif +#ifdef SYS_io_getevents + filter_add_blacklist(SYS_io_getevents, 0); +#endif +#ifdef SYS_io_submit + filter_add_blacklist(SYS_io_submit, 0); +#endif +#ifdef SYS_io_cancel + filter_add_blacklist(SYS_io_cancel, 0); +#endif +#ifdef SYS_remap_file_pages + filter_add_blacklist(SYS_remap_file_pages, 0); +#endif +#ifdef SYS_mbind + filter_add_blacklist(SYS_mbind, 0); +#endif +#ifdef SYS_get_mempolicy + filter_add_blacklist(SYS_get_mempolicy, 0); +#endif +#ifdef SYS_set_mempolicy + filter_add_blacklist(SYS_set_mempolicy, 0); +#endif +#ifdef SYS_migrate_pages + filter_add_blacklist(SYS_migrate_pages, 0); +#endif +#ifdef SYS_move_pages + filter_add_blacklist(SYS_move_pages, 0); +#endif +#ifdef SYS_vmsplice + filter_add_blacklist(SYS_vmsplice, 0); +#endif + //#ifdef SYS_set_robust_list + // filter_add_blacklist(SYS_set_robust_list, 0); + //#endif + //#ifdef SYS_get_robust_list + // filter_add_blacklist(SYS_get_robust_list, 0); + //#endif +#ifdef SYS_perf_event_open + filter_add_blacklist(SYS_perf_event_open, 0); +#endif + + // CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(clone), 1, + // SCMP_A0(SCMP_CMP_MASKED_EQ, CLONE_NEWUSER, CLONE_NEWUSER))); + +// 32bit +// filter_add_blacklist(SYS_personality, 0); // test wine +// filter_add_blacklist(SYS_set_thread_area, 0); // test wine } // default seccomp filter with additional drop list diff --git a/todo b/todo index b2c98014c..e8fa68928 100644 --- a/todo +++ b/todo @@ -45,3 +45,137 @@ make[1]: *** [seccomp.o] Error 1 7. Add IRC clients: KVIrc (KDE), BitchX (CLI), Smuxi, Konversation (KDE), HexChat, Irssi (CLI), WeeChat (CLI) RSS: Liferea, akregator (KDE), newsbeuter (CLI), rawdog, + +8. To investigate +void SupervisorMain::setupSeccomp() { + // Install a rudimentary seccomp blacklist. + // TODO(security): Change this to a whitelist. + + scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_ALLOW); + if (ctx == nullptr) + KJ_FAIL_SYSCALL("seccomp_init", 0); // No real error code + KJ_DEFER(seccomp_release(ctx)); + +#define CHECK_SECCOMP(call) \ + do { \ + if (auto result = (call)) { \ + KJ_FAIL_SYSCALL(#call, -result); \ + } \ + } while (0) + + // Native code only for now, so there are no seccomp_arch_add calls. + + // Redundant, but this is standard and harmless. + CHECK_SECCOMP(seccomp_attr_set(ctx, SCMP_FLTATR_CTL_NNP, 1)); + + // It's easy to inadvertently issue an x32 syscall (e.g. syscall(-1)). Such syscalls + // should fail, but there's no need to kill the issuer. + CHECK_SECCOMP(seccomp_attr_set(ctx, SCMP_FLTATR_ACT_BADARCH, SCMP_ACT_ERRNO(ENOSYS))); + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" // SCMP_* macros produce these + // Disable some things that seem scary. + if (!devmode) { + // ptrace is scary + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(ptrace), 0)); + } else { + // Try to be somewhat safe with ptrace in dev mode. Note that the ability to modify + // orig_ax using ptrace allows a complete seccomp bypass. + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(ptrace), 1, + SCMP_A0(SCMP_CMP_EQ, PTRACE_POKEUSER))); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(ptrace), 1, + SCMP_A0(SCMP_CMP_EQ, PTRACE_SETREGS))); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(ptrace), 1, + SCMP_A0(SCMP_CMP_EQ, PTRACE_SETFPREGS))); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(ptrace), 1, + SCMP_A0(SCMP_CMP_EQ, PTRACE_SETREGSET))); + } + + // Restrict the set of allowable network protocol families + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, + SCMP_A0(SCMP_CMP_GE, AF_NETLINK + 1))); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, + SCMP_A0(SCMP_CMP_EQ, AF_AX25))); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, + SCMP_A0(SCMP_CMP_EQ, AF_IPX))); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, + SCMP_A0(SCMP_CMP_EQ, AF_APPLETALK))); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, + SCMP_A0(SCMP_CMP_EQ, AF_NETROM))); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, + SCMP_A0(SCMP_CMP_EQ, AF_BRIDGE))); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, + SCMP_A0(SCMP_CMP_EQ, AF_ATMPVC))); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, + SCMP_A0(SCMP_CMP_EQ, AF_X25))); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, + SCMP_A0(SCMP_CMP_EQ, AF_ROSE))); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, + SCMP_A0(SCMP_CMP_EQ, AF_DECnet))); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, + SCMP_A0(SCMP_CMP_EQ, AF_NETBEUI))); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, + SCMP_A0(SCMP_CMP_EQ, AF_SECURITY))); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, + SCMP_A0(SCMP_CMP_EQ, AF_KEY))); +#pragma GCC diagnostic pop + + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(add_key), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(request_key), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(keyctl), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(syslog), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(uselib), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(personality), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(acct), 0)); + + // 16-bit code is unnecessary in the sandbox, and modify_ldt is a historic source + // of interesting information leaks. + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(modify_ldt), 0)); + + // Despite existing at a 64-bit syscall, set_thread_area is only useful + // for 32-bit programs. 64-bit programs use arch_prctl instead. + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(set_thread_area), 0)); + + // Disable namespaces. Nested sandboxing could be useful but the attack surface is large. + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(unshare), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(mount), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(pivot_root), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(quotactl), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(clone), 1, + SCMP_A0(SCMP_CMP_MASKED_EQ, CLONE_NEWUSER, CLONE_NEWUSER))); + + // AIO is scary. + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(io_setup), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(io_destroy), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(io_getevents), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(io_submit), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(io_cancel), 0)); + + // Scary vm syscalls + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(remap_file_pages), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(mbind), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(get_mempolicy), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(set_mempolicy), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(migrate_pages), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(move_pages), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(vmsplice), 0)); + + // Scary futex operations + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(set_robust_list), 0)); + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(get_robust_list), 0)); + + // Utterly terrifying profiling operations + CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOSYS), SCMP_SYS(perf_event_open), 0)); + + // TOOD(someday): See if we can get away with turning off mincore, madvise, sysinfo etc. + + // TODO(someday): Turn off POSIX message queues and other such esoteric features. + + if (seccompDumpPfc) { + seccomp_export_pfc(ctx, 1); + } + + CHECK_SECCOMP(seccomp_load(ctx)); + +#undef CHECK_SECCOMP +}