From 64a8d6a7f771e6457f7998335a8b88d60fe2b6ab Mon Sep 17 00:00:00 2001 From: netblue30 Date: Tue, 27 Oct 2020 09:35:41 -0400 Subject: compile time option to disable --private-cache and --tmpfs for regular user --- configure | 25 +++++++++++++++++++++---- configure.ac | 9 +++++++++ src/common.mk.in | 3 ++- src/firejail/checkcfg.c | 8 ++++++++ src/firejail/fs.c | 4 ++-- src/firejail/main.c | 2 ++ src/firejail/profile.c | 8 ++++++++ src/firejail/sandbox.c | 2 ++ 8 files changed, 54 insertions(+), 7 deletions(-) diff --git a/configure b/configure index 36890d837..75c2499a9 100755 --- a/configure +++ b/configure @@ -644,6 +644,7 @@ HAVE_PRIVATE_HOME HAVE_FIRETUNNEL HAVE_GAWK HAVE_MAN +HAVE_USERTMPFS HAVE_OVERLAYFS HAVE_DBUSPROXY EXTRA_LDFLAGS @@ -711,6 +712,7 @@ enable_analyzer enable_apparmor enable_dbusproxy enable_overlayfs +enable_usertmpfs enable_man enable_firetunnel enable_private_home @@ -1366,6 +1368,7 @@ Optional Features: --enable-apparmor enable apparmor --disable-dbusproxy disable dbus proxy --disable-overlayfs disable overlayfs + --disable-usertmpfs disable tmpfs as regular user --disable-man disable man pages --disable-firetunnel disable firetunnel --disable-private-home disable private home feature @@ -3417,8 +3420,8 @@ if test "x$enable_apparmor" = "xyes"; then : HAVE_APPARMOR="-DHAVE_APPARMOR" pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libapparmor" >&5 -$as_echo_n "checking for libapparmor... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for AA" >&5 +$as_echo_n "checking for AA... " >&6; } if test -n "$AA_CFLAGS"; then pkg_cv_AA_CFLAGS="$AA_CFLAGS" @@ -3458,7 +3461,7 @@ fi if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -3485,7 +3488,7 @@ Alternatively, you may set the environment variables AA_CFLAGS and AA_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} @@ -3538,6 +3541,19 @@ if test "x$enable_overlayfs" != "xno"; then : HAVE_OVERLAYFS="-DHAVE_OVERLAYFS" +fi + +HAVE_USERTMPS="" +# Check whether --enable-usertmpfs was given. +if test "${enable_usertmpfs+set}" = set; then : + enableval=$enable_usertmpfs; +fi + +if test "x$enable_usertmpfs" != "xno"; then : + + HAVE_USERTMPFS="-DHAVE_USERTMPFS" + + fi HAVE_MAN="no" @@ -5464,6 +5480,7 @@ echo " private home support: $HAVE_PRIVATE_HOME" echo " file transfer support: $HAVE_FILE_TRANSFER" echo " overlayfs support: $HAVE_OVERLAYFS" echo " DBUS proxy support: $HAVE_DBUSPROXY" +echo " allow tmpfs as regular user: $HAVE_USERTMPFS" echo " Manpage support: $HAVE_MAN" echo " firetunnel support: $HAVE_FIRETUNNEL" echo " busybox workaround: $BUSYBOX_WORKAROUND" diff --git a/configure.ac b/configure.ac index cefc302f9..e21e4a01f 100644 --- a/configure.ac +++ b/configure.ac @@ -74,6 +74,14 @@ AS_IF([test "x$enable_overlayfs" != "xno"], [ AC_SUBST(HAVE_OVERLAYFS) ]) +HAVE_USERTMPS="" +AC_ARG_ENABLE([usertmpfs], + AS_HELP_STRING([--disable-usertmpfs], [disable tmpfs as regular user])) +AS_IF([test "x$enable_usertmpfs" != "xno"], [ + HAVE_USERTMPFS="-DHAVE_USERTMPFS" + AC_SUBST(HAVE_USERTMPFS) +]) + HAVE_MAN="no" AC_ARG_ENABLE([man], AS_HELP_STRING([--disable-man], [disable man pages])) @@ -240,6 +248,7 @@ echo " private home support: $HAVE_PRIVATE_HOME" echo " file transfer support: $HAVE_FILE_TRANSFER" echo " overlayfs support: $HAVE_OVERLAYFS" echo " DBUS proxy support: $HAVE_DBUSPROXY" +echo " allow tmpfs as regular user: $HAVE_USERTMPFS" echo " Manpage support: $HAVE_MAN" echo " firetunnel support: $HAVE_FIRETUNNEL" echo " busybox workaround: $BUSYBOX_WORKAROUND" diff --git a/src/common.mk.in b/src/common.mk.in index c9ef455ed..b8a13cd1b 100644 --- a/src/common.mk.in +++ b/src/common.mk.in @@ -24,6 +24,7 @@ HAVE_PRIVATE_HOME=@HAVE_PRIVATE_HOME@ HAVE_GCOV=@HAVE_GCOV@ HAVE_SELINUX=@HAVE_SELINUX@ HAVE_DBUSPROXY=@HAVE_DBUSPROXY@ +HAVE_USERTMPFS=@HAVE_USERTMPFS@ H_FILE_LIST = $(sort $(wildcard *.[h])) C_FILE_LIST = $(sort $(wildcard *.c)) @@ -33,7 +34,7 @@ BINOBJS = $(foreach file, $(OBJS), $file) CFLAGS = @CFLAGS@ CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' $(HAVE_GCOV) CFLAGS += -DPREFIX='"$(prefix)"' -DSYSCONFDIR='"$(sysconfdir)/firejail"' -DLIBDIR='"$(libdir)"' -DBINDIR='"$(bindir)"' -MANFLAGS = $(HAVE_X11) $(HAVE_PRIVATE_HOME) $(HAVE_APPARMOR) $(HAVE_OVERLAYFS) $(HAVE_DBUSPROXY) $(HAVE_FIRETUNNEL) $(HAVE_GLOBALCFG) $(HAVE_CHROOT) $(HAVE_NETWORK) $(HAVE_USERNS) $(HAVE_FILE_TRANSFER) $(HAVE_WHITELIST) $(HAVE_SELINUX) +MANFLAGS = $(HAVE_X11) $(HAVE_PRIVATE_HOME) $(HAVE_APPARMOR) $(HAVE_OVERLAYFS) $(HAVE_USERTMPFS) $(HAVE_DBUSPROXY) $(HAVE_FIRETUNNEL) $(HAVE_GLOBALCFG) $(HAVE_CHROOT) $(HAVE_NETWORK) $(HAVE_USERNS) $(HAVE_FILE_TRANSFER) $(HAVE_WHITELIST) $(HAVE_SELINUX) CFLAGS += $(MANFLAGS) CFLAGS += -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -Wformat -Wformat-security LDFLAGS += -pie -fPIE -Wl,-z,relro -Wl,-z,now -lpthread diff --git a/src/firejail/checkcfg.c b/src/firejail/checkcfg.c index a0aa3138a..085221464 100644 --- a/src/firejail/checkcfg.c +++ b/src/firejail/checkcfg.c @@ -351,6 +351,14 @@ void print_compiletime_support(void) { #endif ); + printf("\t- private-cache and tmpfs as user %s\n", +#ifdef HAVE_USERTMPFS + "enabled" +#else + "disabled" +#endif + ); + printf("\t- SELinux support is %s\n", #ifdef HAVE_SELINUX "enabled" diff --git a/src/firejail/fs.c b/src/firejail/fs.c index 2f2bfdc79..76ec102c3 100644 --- a/src/firejail/fs.c +++ b/src/firejail/fs.c @@ -162,7 +162,7 @@ static void disable_file(OPERATION op, const char *filename) { } else if (op == MOUNT_TMPFS) { if (S_ISDIR(s.st_mode)) { - fs_tmpfs(fname, 0); + fs_tmpfs(fname, getuid()); last_disable = SUCCESSFUL; } else @@ -451,7 +451,7 @@ void fs_blacklist(void) { void fs_tmpfs(const char *dir, unsigned check_owner) { assert(dir); if (arg_debug) - printf("Mounting tmpfs on %s\n", dir); + printf("Mounting tmpfs on %s, check owner: %s\n", dir, (check_owner)? "yes": "no"); // get a file descriptor for dir, fails if there is any symlink int fd = safe_fd(dir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); if (fd == -1) diff --git a/src/firejail/main.c b/src/firejail/main.c index 0d67c2a64..b4c9ee294 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c @@ -2000,12 +2000,14 @@ int main(int argc, char **argv, char **envp) { else if (strcmp(argv[i], "--private-tmp") == 0) { arg_private_tmp = 1; } +#ifdef HAVE_USERTMPFS else if (strcmp(argv[i], "--private-cache") == 0) { if (checkcfg(CFG_PRIVATE_CACHE)) arg_private_cache = 1; else exit_err_feature("private-cache"); } +#endif else if (strcmp(argv[i], "--private-cwd") == 0) { cfg.cwd = NULL; arg_private_cwd = 1; diff --git a/src/firejail/profile.c b/src/firejail/profile.c index 869183e2f..4942f99ff 100644 --- a/src/firejail/profile.c +++ b/src/firejail/profile.c @@ -383,10 +383,12 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { return 0; } else if (strcmp(ptr, "private-cache") == 0) { +#ifdef HAVE_USERTMPFS if (checkcfg(CFG_PRIVATE_CACHE)) arg_private_cache = 1; else warning_feature_disabled("private-cache"); +#endif return 0; } else if (strcmp(ptr, "private-dev") == 0) { @@ -1570,6 +1572,12 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { else if (strncmp(ptr, "noexec ", 7) == 0) ptr += 7; else if (strncmp(ptr, "tmpfs ", 6) == 0) { +#ifndef HAVE_USERTMPFS + if (getuid() != 0) { + fprintf(stderr, "Error: tmpfs available only when running the sandbox as root\n"); + exit(1); + } +#endif ptr += 6; } else { diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index 3e8dbe5d9..8bfe76603 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c @@ -921,6 +921,7 @@ int sandbox(void* sandbox_arg) { } } +#ifdef HAVE_USERTMPFS if (arg_private_cache) { if (cfg.chrootdir) fwarning("private-cache feature is disabled in chroot\n"); @@ -929,6 +930,7 @@ int sandbox(void* sandbox_arg) { else fs_private_cache(); } +#endif if (arg_private_tmp) { // private-tmp is implemented as a whitelist -- cgit v1.2.3-70-g09d2