mirror of
https://github.com/netblue30/firejail.git
synced 2026-05-15 22:01:33 -06:00
Add support for SELinux labeling
Running `firejail --noprofile --private-bin=bash,ls ls -1Za /usr/bin`
shows that the SELinux labels are not correct:
```
user_u:object_r:user_tmpfs_t:s0 .
system_u:object_r:usr_t:s0 ..
user_u:object_r:user_tmpfs_t:s0 bash
user_u:object_r:user_tmpfs_t:s0 ls
```
After fixing this:
```
system_u:object_r:bin_t:s0 .
system_u:object_r:usr_t:s0 ..
system_u:object_r:shell_exec_t:s0 bash
system_u:object_r:bin_t:s0 ls
```
Most copied files and created directories should now have correct
labels (bind mounted objects keep their labels). This is useful to
avoid having to change the SELinux rules when using Firejail.
This commit is contained in:
parent
12c361b32f
commit
1ad2d54c01
20 changed files with 224 additions and 17 deletions
2
README
2
README
|
|
@ -29,7 +29,7 @@ development libraries and pkg-config are required when using --apparmor
|
|||
|
||||
$ sudo apt-get install git build-essential libapparmor-dev pkg-config
|
||||
|
||||
|
||||
For --selinux option, add libselinux1-dev (libselinux-devel for Fedora).
|
||||
|
||||
Maintainer:
|
||||
- netblue30 (netblue30@yahoo.com)
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ development libraries and pkg-config are required when using --apparmor
|
|||
`````
|
||||
$ sudo apt-get install git build-essential libapparmor-dev pkg-config
|
||||
`````
|
||||
|
||||
For --selinux option, add libselinux1-dev (libselinux-devel for Fedora).
|
||||
|
||||
## Running the sandbox
|
||||
|
||||
|
|
|
|||
18
configure
vendored
18
configure
vendored
|
|
@ -628,6 +628,7 @@ HAVE_SECCOMP_H
|
|||
EGREP
|
||||
GREP
|
||||
CPP
|
||||
HAVE_SELINUX
|
||||
HAVE_CONTRIB_INSTALL
|
||||
HAVE_GCOV
|
||||
BUSYBOX_WORKAROUND
|
||||
|
|
@ -721,6 +722,7 @@ enable_fatal_warnings
|
|||
enable_busybox_workaround
|
||||
enable_gcov
|
||||
enable_contrib_install
|
||||
enable_selinux
|
||||
'
|
||||
ac_precious_vars='build_alias
|
||||
host_alias
|
||||
|
|
@ -1365,6 +1367,7 @@ Optional Features:
|
|||
--enable-gcov Gcov instrumentation
|
||||
--enable-contrib-install
|
||||
install contrib scripts
|
||||
--enable-selinux SELinux labeling support
|
||||
|
||||
Some influential environment variables:
|
||||
CC C compiler command
|
||||
|
|
@ -3695,6 +3698,20 @@ else
|
|||
fi
|
||||
|
||||
|
||||
HAVE_SELINUX=""
|
||||
# Check whether --enable-selinux was given.
|
||||
if test "${enable_selinux+set}" = set; then :
|
||||
enableval=$enable_selinux;
|
||||
fi
|
||||
|
||||
if test "x$enable_selinux" = "xyes"; then :
|
||||
|
||||
HAVE_SELINUX="-DHAVE_SELINUX"
|
||||
EXTRA_LDFLAGS+=" -lselinux "
|
||||
|
||||
|
||||
fi
|
||||
|
||||
# checking pthread library
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lpthread" >&5
|
||||
$as_echo_n "checking for main in -lpthread... " >&6; }
|
||||
|
|
@ -5364,5 +5381,6 @@ echo " EXTRA_CFLAGS: $EXTRA_CFLAGS"
|
|||
echo " fatal warnings: $HAVE_FATAL_WARNINGS"
|
||||
echo " Gcov instrumentation: $HAVE_GCOV"
|
||||
echo " Install contrib scripts: $HAVE_CONTRIB_INSTALL"
|
||||
echo " SELinux labeling support: $HAVE_SELINUX"
|
||||
echo " Install as a SUID executable: $HAVE_SUID"
|
||||
echo
|
||||
|
|
|
|||
10
configure.ac
10
configure.ac
|
|
@ -184,6 +184,15 @@ AS_IF([test "x$enable_contrib_install" = "xno"],
|
|||
)
|
||||
AC_SUBST(HAVE_CONTRIB_INSTALL)
|
||||
|
||||
HAVE_SELINUX=""
|
||||
AC_ARG_ENABLE([selinux],
|
||||
AS_HELP_STRING([--enable-selinux], [SELinux labeling support]))
|
||||
AS_IF([test "x$enable_selinux" = "xyes"], [
|
||||
HAVE_SELINUX="-DHAVE_SELINUX"
|
||||
EXTRA_LDFLAGS+=" -lselinux "
|
||||
AC_SUBST(HAVE_SELINUX)
|
||||
])
|
||||
|
||||
# checking pthread library
|
||||
AC_CHECK_LIB([pthread], [main], [], AC_MSG_ERROR([*** POSIX thread support not installed ***]))
|
||||
AC_CHECK_HEADER(pthread.h,,AC_MSG_ERROR([*** POSIX thread support not installed ***]))
|
||||
|
|
@ -223,5 +232,6 @@ echo " EXTRA_CFLAGS: $EXTRA_CFLAGS"
|
|||
echo " fatal warnings: $HAVE_FATAL_WARNINGS"
|
||||
echo " Gcov instrumentation: $HAVE_GCOV"
|
||||
echo " Install contrib scripts: $HAVE_CONTRIB_INSTALL"
|
||||
echo " SELinux labeling support: $HAVE_SELINUX"
|
||||
echo " Install as a SUID executable: $HAVE_SUID"
|
||||
echo
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ HAVE_OVERLAYFS=@HAVE_OVERLAYFS@
|
|||
HAVE_FIRETUNNEL=@HAVE_FIRETUNNEL@
|
||||
HAVE_PRIVATE_HOME=@HAVE_PRIVATE_HOME@
|
||||
HAVE_GCOV=@HAVE_GCOV@
|
||||
HAVE_SELINUX=@HAVE_SELINUX@
|
||||
|
||||
H_FILE_LIST = $(sort $(wildcard *.[h]))
|
||||
C_FILE_LIST = $(sort $(wildcard *.c))
|
||||
|
|
@ -32,7 +33,7 @@ BINOBJS = $(foreach file, $(OBJS), $file)
|
|||
|
||||
CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' $(HAVE_GCOV)
|
||||
CFLAGS += -DPREFIX='"$(prefix)"' -DSYSCONFDIR='"$(sysconfdir)/firejail"' -DLIBDIR='"$(libdir)"' -DBINDIR='"$(bindir)"'
|
||||
CFLAGS += $(HAVE_X11) $(HAVE_PRIVATE_HOME) $(HAVE_APPARMOR) $(HAVE_OVERLAYFS) $(HAVE_FIRETUNNEL) $(HAVE_SECCOMP) $(HAVE_GLOBALCFG) $(HAVE_SECCOMP_H) $(HAVE_CHROOT) $(HAVE_NETWORK) $(HAVE_USERNS) $(HAVE_FILE_TRANSFER) $(HAVE_WHITELIST)
|
||||
CFLAGS += $(HAVE_X11) $(HAVE_PRIVATE_HOME) $(HAVE_APPARMOR) $(HAVE_OVERLAYFS) $(HAVE_FIRETUNNEL) $(HAVE_SECCOMP) $(HAVE_GLOBALCFG) $(HAVE_SECCOMP_H) $(HAVE_CHROOT) $(HAVE_NETWORK) $(HAVE_USERNS) $(HAVE_FILE_TRANSFER) $(HAVE_WHITELIST) $(HAVE_SELINUX)
|
||||
CFLAGS += -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security
|
||||
LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now -lpthread
|
||||
EXTRA_LDFLAGS +=@EXTRA_LDFLAGS@
|
||||
|
|
|
|||
|
|
@ -24,6 +24,15 @@
|
|||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#if HAVE_SELINUX
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <selinux/context.h>
|
||||
#include <selinux/label.h>
|
||||
#include <selinux/selinux.h>
|
||||
#endif
|
||||
|
||||
int arg_quiet = 0;
|
||||
int arg_debug = 0;
|
||||
static int arg_follow_link = 0;
|
||||
|
|
@ -36,6 +45,52 @@ static unsigned file_cnt = 0;
|
|||
static char *outpath = NULL;
|
||||
static char *inpath = NULL;
|
||||
|
||||
#if HAVE_SELINUX
|
||||
static struct selabel_handle *label_hnd = NULL;
|
||||
static int selinux_enabled = -1;
|
||||
#endif
|
||||
|
||||
// copy from firejail/selinux.c
|
||||
static void selinux_relabel_path(const char *path, const char *inside_path)
|
||||
{
|
||||
#if HAVE_SELINUX
|
||||
char procfs_path[64];
|
||||
char *fcon = NULL;
|
||||
int fd;
|
||||
struct stat st;
|
||||
|
||||
if (selinux_enabled == -1)
|
||||
selinux_enabled = is_selinux_enabled();
|
||||
|
||||
if (!selinux_enabled)
|
||||
return;
|
||||
|
||||
if (!label_hnd)
|
||||
label_hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0);
|
||||
|
||||
/* Open the file as O_PATH, to pin it while we determine and adjust the label */
|
||||
fd = open(path, O_NOFOLLOW|O_CLOEXEC|O_PATH);
|
||||
if (fd < 0)
|
||||
return;
|
||||
if (fstat(fd, &st) < 0)
|
||||
goto close;
|
||||
|
||||
if (selabel_lookup_raw(label_hnd, &fcon, inside_path, st.st_mode) == 0) {
|
||||
sprintf(procfs_path, "/proc/self/fd/%i", fd);
|
||||
if (arg_debug)
|
||||
printf("Relabeling %s as %s (%s)\n", path, inside_path, fcon);
|
||||
|
||||
setfilecon_raw(procfs_path, fcon);
|
||||
}
|
||||
freecon(fcon);
|
||||
close:
|
||||
close(fd);
|
||||
#else
|
||||
(void) path;
|
||||
(void) inside_path;
|
||||
#endif
|
||||
}
|
||||
|
||||
// modified version of the function from util.c
|
||||
static void copy_file(const char *srcname, const char *destname, mode_t mode, uid_t uid, gid_t gid) {
|
||||
assert(srcname);
|
||||
|
|
@ -87,6 +142,8 @@ static void copy_file(const char *srcname, const char *destname, mode_t mode, ui
|
|||
close(src);
|
||||
close(dst);
|
||||
|
||||
selinux_relabel_path(destname, srcname);
|
||||
|
||||
return;
|
||||
|
||||
errexit:
|
||||
|
|
|
|||
|
|
@ -833,4 +833,7 @@ extern pid_t dhclient4_pid;
|
|||
extern pid_t dhclient6_pid;
|
||||
void dhcp_start(void);
|
||||
|
||||
// selinux.c
|
||||
void selinux_relabel_path(const char *path, const char *inside_path);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -309,5 +309,6 @@ void fs_private_bin_list(void) {
|
|||
}
|
||||
i++;
|
||||
}
|
||||
selinux_relabel_path(RUN_BIN_DIR, "/bin");
|
||||
fmessage("%d %s installed in %0.2f ms\n", prog_cnt, (prog_cnt == 1)? "program": "programs", timetrace_end());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -167,6 +167,7 @@ static void create_link(const char *oldpath, const char *newpath) {
|
|||
static void empty_dev_shm(void) {
|
||||
// create an empty /dev/shm directory
|
||||
mkdir_attr("/dev/shm", 01777, 0, 0);
|
||||
selinux_relabel_path("/dev/shm", "/dev/shm");
|
||||
fs_logger("mkdir /dev/shm");
|
||||
fs_logger("create /dev/shm");
|
||||
}
|
||||
|
|
@ -276,10 +277,13 @@ void fs_private_dev(void){
|
|||
// pseudo-terminal
|
||||
mkdir_attr("/dev/pts", 0755, 0, 0);
|
||||
fs_logger("mkdir /dev/pts");
|
||||
selinux_relabel_path("/dev/pts", "/dev/pts");
|
||||
fs_logger("create /dev/pts");
|
||||
create_char_dev("/dev/pts/ptmx", 0666, 5, 2); //"mknod -m 666 /dev/pts/ptmx c 5 2");
|
||||
selinux_relabel_path("/dev/pts/ptmx", "/dev/pts/ptmx");
|
||||
fs_logger("mknod /dev/pts/ptmx");
|
||||
create_link("/dev/pts/ptmx", "/dev/ptmx");
|
||||
selinux_relabel_path("/dev/ptmx", "/dev/ptmx");
|
||||
|
||||
// code before github issue #351
|
||||
// mount -vt devpts -o newinstance -o ptmxmode=0666 devpts //dev/pts
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ void fs_machineid(void) {
|
|||
if (set_perms(RUN_MACHINEID, 0, 0, 0444))
|
||||
errExit("set_perms");
|
||||
|
||||
selinux_relabel_path(RUN_MACHINEID, "/etc/machine-id");
|
||||
|
||||
struct stat s;
|
||||
if (stat("/etc/machine-id", &s) == 0) {
|
||||
|
|
@ -154,6 +155,7 @@ void fs_private_dir_list(const char *private_dir, const char *private_run_dir, c
|
|||
|
||||
// create /run/firejail/mnt/etc directory
|
||||
mkdir_attr(private_run_dir, 0755, 0, 0);
|
||||
selinux_relabel_path(private_run_dir, private_dir);
|
||||
fs_logger2("tmpfs", private_dir);
|
||||
|
||||
fs_logger_print(); // save the current log
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
|
|||
touch_file_as_user(fname, 0644);
|
||||
fs_logger2("touch", fname);
|
||||
}
|
||||
selinux_relabel_path(fname, fname);
|
||||
free(fname);
|
||||
}
|
||||
// csh
|
||||
|
|
@ -85,6 +86,7 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
|
|||
touch_file_as_user(fname, 0644);
|
||||
fs_logger2("touch", fname);
|
||||
}
|
||||
selinux_relabel_path(fname, fname);
|
||||
free(fname);
|
||||
}
|
||||
// bash etc.
|
||||
|
|
@ -105,6 +107,7 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
|
|||
fs_logger("clone /etc/skel/.bashrc");
|
||||
fs_logger2("clone", fname);
|
||||
}
|
||||
selinux_relabel_path(fname, fname);
|
||||
free(fname);
|
||||
}
|
||||
}
|
||||
|
|
@ -139,6 +142,7 @@ static int store_xauthority(void) {
|
|||
|
||||
copy_file_as_user(src, dest, getuid(), getgid(), 0600); // regular user
|
||||
fs_logger2("clone", dest);
|
||||
selinux_relabel_path(dest, src);
|
||||
free(src);
|
||||
return 1; // file copied
|
||||
}
|
||||
|
|
@ -185,6 +189,7 @@ static int store_asoundrc(void) {
|
|||
errExit("fopen");
|
||||
|
||||
copy_file_as_user(src, dest, getuid(), getgid(), 0644); // regular user
|
||||
selinux_relabel_path(dest, src);
|
||||
fs_logger2("clone", dest);
|
||||
free(src);
|
||||
return 1; // file copied
|
||||
|
|
@ -208,6 +213,7 @@ static void copy_xauthority(void) {
|
|||
}
|
||||
|
||||
copy_file_as_user(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR); // regular user
|
||||
selinux_relabel_path(dest, src);
|
||||
fs_logger2("clone", dest);
|
||||
free(dest);
|
||||
|
||||
|
|
@ -313,6 +319,7 @@ void fs_private_homedir(void) {
|
|||
printf("Mounting a new /root directory\n");
|
||||
if (mount("tmpfs", "/root", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_STRICTATIME, "mode=700,gid=0") < 0)
|
||||
errExit("mounting /root directory");
|
||||
selinux_relabel_path("/root", "/root");
|
||||
fs_logger("tmpfs /root");
|
||||
}
|
||||
if (u == 0 && !arg_allusers) {
|
||||
|
|
@ -321,6 +328,7 @@ void fs_private_homedir(void) {
|
|||
printf("Mounting a new /home directory\n");
|
||||
if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_STRICTATIME, "mode=755,gid=0") < 0)
|
||||
errExit("mounting /home directory");
|
||||
selinux_relabel_path("/home", "/home");
|
||||
fs_logger("tmpfs /home");
|
||||
}
|
||||
|
||||
|
|
@ -355,6 +363,7 @@ void fs_private(void) {
|
|||
fwarning("allusers option disabled by private or whitelist option\n");
|
||||
if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_STRICTATIME, "mode=755,gid=0") < 0)
|
||||
errExit("mounting /home directory");
|
||||
selinux_relabel_path("/home", "/home");
|
||||
fs_logger("tmpfs /home");
|
||||
}
|
||||
|
||||
|
|
@ -378,6 +387,8 @@ void fs_private(void) {
|
|||
}
|
||||
if (chown(homedir, u, g) < 0)
|
||||
errExit("chown");
|
||||
selinux_relabel_path(homedir, homedir);
|
||||
|
||||
fs_logger2("mkdir", homedir);
|
||||
fs_logger2("tmpfs", homedir);
|
||||
}
|
||||
|
|
@ -542,6 +553,7 @@ void fs_private_home_list(void) {
|
|||
|
||||
// create /run/firejail/mnt/home directory
|
||||
mkdir_attr(RUN_HOME_DIR, 0755, uid, gid);
|
||||
selinux_relabel_path(RUN_HOME_DIR, "/home");
|
||||
fs_logger_print(); // save the current log
|
||||
|
||||
if (arg_debug)
|
||||
|
|
@ -604,6 +616,7 @@ void fs_private_home_list(void) {
|
|||
printf("Mounting a new /root directory\n");
|
||||
if (mount("tmpfs", "/root", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, "mode=700,gid=0") < 0)
|
||||
errExit("mounting /root directory");
|
||||
selinux_relabel_path("/root", "/root");
|
||||
fs_logger("tmpfs /root");
|
||||
}
|
||||
if (uid == 0 && !arg_allusers) {
|
||||
|
|
@ -612,6 +625,7 @@ void fs_private_home_list(void) {
|
|||
printf("Mounting a new /home directory\n");
|
||||
if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, "mode=755,gid=0") < 0)
|
||||
errExit("mounting /home directory");
|
||||
selinux_relabel_path("/home", "/home");
|
||||
fs_logger("tmpfs /home");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ void fs_resolvconf(void) {
|
|||
printf("mirroring /etc directory\n");
|
||||
if (mkdir(RUN_DNS_ETC, 0755))
|
||||
errExit("mkdir");
|
||||
selinux_relabel_path(RUN_DNS_ETC, "/etc");
|
||||
fs_logger("tmpfs /etc");
|
||||
|
||||
DIR *dir = opendir("/etc");
|
||||
|
|
|
|||
|
|
@ -326,6 +326,7 @@ void fs_private_lib(void) {
|
|||
|
||||
// create /run/firejail/mnt/lib directory
|
||||
mkdir_attr(RUN_LIB_DIR, 0755, 0, 0);
|
||||
selinux_relabel_path(RUN_LIB_DIR, "/usr/lib");
|
||||
|
||||
// install standard C libraries
|
||||
if (arg_debug || arg_debug_private_lib)
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@ void fslib_install_stdc(void) {
|
|||
|
||||
if (stat("/lib/x86_64-linux-gnu", &s) == 0) { // Debian & friends
|
||||
mkdir_attr(RUN_LIB_DIR "/x86_64-linux-gnu", 0755, 0, 0);
|
||||
selinux_relabel_path(RUN_LIB_DIR "/x86_64-linux-gnu", "/lib/x86_64-linux-gnu");
|
||||
stdclib = "/lib/x86_64-linux-gnu";
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -223,9 +223,11 @@ void fs_var_cache(void) {
|
|||
}
|
||||
|
||||
mkdir_attr("/var/cache/lighttpd/compress", 0755, uid, gid);
|
||||
selinux_relabel_path("/var/cache/lighttpd/compress", "/var/cache/lighttpd/compress");
|
||||
fs_logger("mkdir /var/cache/lighttpd/compress");
|
||||
|
||||
mkdir_attr("/var/cache/lighttpd/uploads", 0755, uid, gid);
|
||||
selinux_relabel_path("/var/cache/lighttpd/uploads", "/var/cache/lighttpd/uploads");
|
||||
fs_logger("/var/cache/lighttpd/uploads");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -734,6 +734,7 @@ void fs_whitelist(void) {
|
|||
printf("Mounting tmpfs on /tmp directory\n");
|
||||
if (mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=1777,gid=0") < 0)
|
||||
errExit("mounting tmpfs on /tmp");
|
||||
selinux_relabel_path("/tmp", "/tmp");
|
||||
fs_logger("tmpfs /tmp");
|
||||
|
||||
// pam-tmpdir - issue #2685
|
||||
|
|
@ -745,8 +746,10 @@ void fs_whitelist(void) {
|
|||
if (strcmp(env, pamtmpdir) == 0) {
|
||||
// create empty user-owned /tmp/user/$uid directory
|
||||
mkdir_attr("/tmp/user", 0711, 0, 0);
|
||||
selinux_relabel_path("/tmp/user", "/tmp/user");
|
||||
fs_logger("mkdir /tmp/user");
|
||||
mkdir_attr(pamtmpdir, 0700, getuid(), 0);
|
||||
selinux_relabel_path(pamtmpdir, pamtmpdir);
|
||||
fs_logger2("mkdir", pamtmpdir);
|
||||
}
|
||||
free(pamtmpdir);
|
||||
|
|
@ -774,6 +777,7 @@ void fs_whitelist(void) {
|
|||
printf("Mounting tmpfs on /media directory\n");
|
||||
if (mount("tmpfs", "/media", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0)
|
||||
errExit("mounting tmpfs on /media");
|
||||
selinux_relabel_path("/media", "/media");
|
||||
fs_logger("tmpfs /media");
|
||||
|
||||
// autowhitelist home directory if it is masked by the tmpfs
|
||||
|
|
@ -798,6 +802,7 @@ void fs_whitelist(void) {
|
|||
printf("Mounting tmpfs on /mnt directory\n");
|
||||
if (mount("tmpfs", "/mnt", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0)
|
||||
errExit("mounting tmpfs on /mnt");
|
||||
selinux_relabel_path("/mnt", "/mnt");
|
||||
fs_logger("tmpfs /mnt");
|
||||
|
||||
// autowhitelist home directory if it is masked by the tmpfs
|
||||
|
|
@ -822,6 +827,7 @@ void fs_whitelist(void) {
|
|||
printf("Mounting tmpfs on /var directory\n");
|
||||
if (mount("tmpfs", "/var", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0)
|
||||
errExit("mounting tmpfs on /var");
|
||||
selinux_relabel_path("/var", "/var");
|
||||
fs_logger("tmpfs /var");
|
||||
|
||||
// autowhitelist home directory if it is masked by the tmpfs
|
||||
|
|
@ -846,6 +852,7 @@ void fs_whitelist(void) {
|
|||
printf("Mounting tmpfs on /dev directory\n");
|
||||
if (mount("tmpfs", "/dev", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0)
|
||||
errExit("mounting tmpfs on /dev");
|
||||
selinux_relabel_path("/dev", "/dev");
|
||||
fs_logger("tmpfs /dev");
|
||||
|
||||
// autowhitelist home directory if it is masked by the tmpfs
|
||||
|
|
@ -870,6 +877,7 @@ void fs_whitelist(void) {
|
|||
printf("Mounting tmpfs on /opt directory\n");
|
||||
if (mount("tmpfs", "/opt", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0)
|
||||
errExit("mounting tmpfs on /opt");
|
||||
selinux_relabel_path("/opt", "/opt");
|
||||
fs_logger("tmpfs /opt");
|
||||
|
||||
// autowhitelist home directory if it is masked by the tmpfs
|
||||
|
|
@ -894,6 +902,7 @@ void fs_whitelist(void) {
|
|||
printf("Mounting tmpfs on /srv directory\n");
|
||||
if (mount("tmpfs", "/srv", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0)
|
||||
errExit("mounting tmpfs on /srv");
|
||||
selinux_relabel_path("/srv", "/srv");
|
||||
fs_logger("tmpfs /srv");
|
||||
|
||||
// autowhitelist home directory if it is masked by the tmpfs
|
||||
|
|
@ -918,6 +927,7 @@ void fs_whitelist(void) {
|
|||
printf("Mounting tmpfs on /etc directory\n");
|
||||
if (mount("tmpfs", "/etc", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0)
|
||||
errExit("mounting tmpfs on /etc");
|
||||
selinux_relabel_path("/etc", "/etc");
|
||||
fs_logger("tmpfs /etc");
|
||||
|
||||
// autowhitelist home directory if it is masked by the tmpfs
|
||||
|
|
@ -942,6 +952,7 @@ void fs_whitelist(void) {
|
|||
printf("Mounting tmpfs on /usr/share directory\n");
|
||||
if (mount("tmpfs", "/usr/share", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0)
|
||||
errExit("mounting tmpfs on /usr/share");
|
||||
selinux_relabel_path("/usr/share", "/usr/share");
|
||||
fs_logger("tmpfs /usr/share");
|
||||
|
||||
// autowhitelist home directory if it is masked by the tmpfs
|
||||
|
|
@ -966,6 +977,7 @@ void fs_whitelist(void) {
|
|||
printf("Mounting tmpfs on /sys/module directory\n");
|
||||
if (mount("tmpfs", "/sys/module", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0)
|
||||
errExit("mounting tmpfs on /sys/module");
|
||||
selinux_relabel_path("/sys/module", "/sys/module");
|
||||
fs_logger("tmpfs /sys/module");
|
||||
}
|
||||
else
|
||||
|
|
@ -989,6 +1001,7 @@ void fs_whitelist(void) {
|
|||
errExit("asprintf");
|
||||
if (mount("tmpfs", runuser, "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, options) < 0)
|
||||
errExit("mounting tmpfs on /run/user/<uid>");
|
||||
selinux_relabel_path(runuser, runuser);
|
||||
free(options);
|
||||
fs_logger2("tmpfs", runuser);
|
||||
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ void pulseaudio_init(void) {
|
|||
// create the new user pulseaudio directory
|
||||
if (mkdir(RUN_PULSE_DIR, 0700) == -1)
|
||||
errExit("mkdir");
|
||||
selinux_relabel_path(RUN_PULSE_DIR, RUN_PULSE_DIR);
|
||||
// mount it nosuid, noexec, nodev
|
||||
fs_remount(RUN_PULSE_DIR, MOUNT_NOEXEC, 0);
|
||||
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ static void sanitize_home(void) {
|
|||
// mount tmpfs in the new home
|
||||
if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, "mode=755,gid=0") < 0)
|
||||
errExit("mount tmpfs");
|
||||
selinux_relabel_path("/home", "/home");
|
||||
fs_logger("tmpfs /home");
|
||||
|
||||
// create user home directory
|
||||
|
|
@ -105,6 +106,7 @@ static void sanitize_home(void) {
|
|||
errExit("mkpath");
|
||||
if (mkdir(cfg.homedir, 0755) == -1)
|
||||
errExit("mkdir");
|
||||
selinux_relabel_path(cfg.homedir, cfg.homedir);
|
||||
}
|
||||
fs_logger2("mkdir", cfg.homedir);
|
||||
|
||||
|
|
@ -152,11 +154,13 @@ static void sanitize_run(void) {
|
|||
// mount tmpfs on /run/user
|
||||
if (mount("tmpfs", "/run/user", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, "mode=755,gid=0") < 0)
|
||||
errExit("mount tmpfs");
|
||||
selinux_relabel_path("/run/user", "/run/user");
|
||||
fs_logger("tmpfs /run/user");
|
||||
|
||||
// create new user directory
|
||||
if (mkdir(runuser, 0700) == -1)
|
||||
errExit("mkdir");
|
||||
selinux_relabel_path(runuser, runuser);
|
||||
fs_logger2("mkdir", runuser);
|
||||
|
||||
// set mode and ownership
|
||||
|
|
|
|||
|
|
@ -848,20 +848,6 @@ int sandbox(void* sandbox_arg) {
|
|||
if (arg_private_dev)
|
||||
fs_private_dev();
|
||||
|
||||
if (arg_private_etc) {
|
||||
if (cfg.chrootdir)
|
||||
fwarning("private-etc feature is disabled in chroot\n");
|
||||
else if (arg_overlay)
|
||||
fwarning("private-etc feature is disabled in overlay\n");
|
||||
else {
|
||||
fs_private_dir_list("/etc", RUN_ETC_DIR, cfg.etc_private_keep);
|
||||
fs_private_dir_list("/usr/etc", RUN_USR_ETC_DIR, cfg.etc_private_keep); // openSUSE
|
||||
// create /etc/ld.so.preload file again
|
||||
if (need_preload)
|
||||
fs_trace_preload();
|
||||
}
|
||||
}
|
||||
|
||||
if (arg_private_opt) {
|
||||
if (cfg.chrootdir)
|
||||
fwarning("private-opt feature is disabled in chroot\n");
|
||||
|
|
@ -964,6 +950,21 @@ int sandbox(void* sandbox_arg) {
|
|||
else if (arg_disable_mnt)
|
||||
fs_mnt(0);
|
||||
|
||||
// Install new /etc last, so we can use it as long as possible
|
||||
if (arg_private_etc) {
|
||||
if (cfg.chrootdir)
|
||||
fwarning("private-etc feature is disabled in chroot\n");
|
||||
else if (arg_overlay)
|
||||
fwarning("private-etc feature is disabled in overlay\n");
|
||||
else {
|
||||
fs_private_dir_list("/etc", RUN_ETC_DIR, cfg.etc_private_keep);
|
||||
fs_private_dir_list("/usr/etc", RUN_USR_ETC_DIR, cfg.etc_private_keep); // openSUSE
|
||||
// create /etc/ld.so.preload file again
|
||||
if (need_preload)
|
||||
fs_trace_preload();
|
||||
}
|
||||
}
|
||||
|
||||
//****************************
|
||||
// apply the profile file
|
||||
//****************************
|
||||
|
|
|
|||
73
src/firejail/selinux.c
Normal file
73
src/firejail/selinux.c
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Firejail and systemd authors
|
||||
*
|
||||
* This file is part of firejail project, from systemd selinux-util.c
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#if HAVE_SELINUX
|
||||
#include "firejail.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <selinux/context.h>
|
||||
#include <selinux/label.h>
|
||||
#include <selinux/selinux.h>
|
||||
|
||||
static struct selabel_handle *label_hnd = NULL;
|
||||
static int selinux_enabled = -1;
|
||||
#endif
|
||||
|
||||
void selinux_relabel_path(const char *path, const char *inside_path)
|
||||
{
|
||||
#if HAVE_SELINUX
|
||||
char procfs_path[64];
|
||||
char *fcon = NULL;
|
||||
int fd;
|
||||
struct stat st;
|
||||
|
||||
if (selinux_enabled == -1)
|
||||
selinux_enabled = is_selinux_enabled();
|
||||
|
||||
if (!selinux_enabled && arg_debug)
|
||||
return;
|
||||
|
||||
if (!label_hnd)
|
||||
label_hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0);
|
||||
|
||||
/* Open the file as O_PATH, to pin it while we determine and adjust the label */
|
||||
fd = open(path, O_NOFOLLOW|O_CLOEXEC|O_PATH);
|
||||
if (fd < 0)
|
||||
return;
|
||||
if (fstat(fd, &st) < 0)
|
||||
goto close;
|
||||
|
||||
if (selabel_lookup_raw(label_hnd, &fcon, inside_path, st.st_mode) == 0) {
|
||||
sprintf(procfs_path, "/proc/self/fd/%i", fd);
|
||||
if (arg_debug)
|
||||
printf("Relabeling %s as %s (%s)\n", path, inside_path, fcon);
|
||||
|
||||
setfilecon_raw(procfs_path, fcon);
|
||||
}
|
||||
freecon(fcon);
|
||||
close:
|
||||
close(fd);
|
||||
#else
|
||||
(void) path;
|
||||
(void) inside_path;
|
||||
#endif
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue