diff options
author | 2020-02-18 20:38:00 +0200 | |
---|---|---|
committer | 2020-02-22 08:27:24 +0000 | |
commit | 1ad2d54c014a49f6ad0b487dd0d9b361cb4d299e (patch) | |
tree | 415eb19d90e2ed1de7236c784c1e28d3acfbcaab /src | |
parent | Whitelist more /usr/share for okular and others (diff) | |
download | firejail-1ad2d54c014a49f6ad0b487dd0d9b361cb4d299e.tar.gz firejail-1ad2d54c014a49f6ad0b487dd0d9b361cb4d299e.tar.zst firejail-1ad2d54c014a49f6ad0b487dd0d9b361cb4d299e.zip |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/common.mk.in | 3 | ||||
-rw-r--r-- | src/fcopy/main.c | 57 | ||||
-rw-r--r-- | src/firejail/firejail.h | 3 | ||||
-rw-r--r-- | src/firejail/fs_bin.c | 1 | ||||
-rw-r--r-- | src/firejail/fs_dev.c | 4 | ||||
-rw-r--r-- | src/firejail/fs_etc.c | 2 | ||||
-rw-r--r-- | src/firejail/fs_home.c | 14 | ||||
-rw-r--r-- | src/firejail/fs_hostname.c | 1 | ||||
-rw-r--r-- | src/firejail/fs_lib.c | 1 | ||||
-rw-r--r-- | src/firejail/fs_lib2.c | 1 | ||||
-rw-r--r-- | src/firejail/fs_var.c | 2 | ||||
-rw-r--r-- | src/firejail/fs_whitelist.c | 13 | ||||
-rw-r--r-- | src/firejail/pulseaudio.c | 1 | ||||
-rw-r--r-- | src/firejail/restrict_users.c | 4 | ||||
-rw-r--r-- | src/firejail/sandbox.c | 29 | ||||
-rw-r--r-- | src/firejail/selinux.c | 73 |
16 files changed, 194 insertions, 15 deletions
diff --git a/src/common.mk.in b/src/common.mk.in index 1464ab9b2..945815a40 100644 --- a/src/common.mk.in +++ b/src/common.mk.in | |||
@@ -24,6 +24,7 @@ HAVE_OVERLAYFS=@HAVE_OVERLAYFS@ | |||
24 | HAVE_FIRETUNNEL=@HAVE_FIRETUNNEL@ | 24 | HAVE_FIRETUNNEL=@HAVE_FIRETUNNEL@ |
25 | HAVE_PRIVATE_HOME=@HAVE_PRIVATE_HOME@ | 25 | HAVE_PRIVATE_HOME=@HAVE_PRIVATE_HOME@ |
26 | HAVE_GCOV=@HAVE_GCOV@ | 26 | HAVE_GCOV=@HAVE_GCOV@ |
27 | HAVE_SELINUX=@HAVE_SELINUX@ | ||
27 | 28 | ||
28 | H_FILE_LIST = $(sort $(wildcard *.[h])) | 29 | H_FILE_LIST = $(sort $(wildcard *.[h])) |
29 | C_FILE_LIST = $(sort $(wildcard *.c)) | 30 | C_FILE_LIST = $(sort $(wildcard *.c)) |
@@ -32,7 +33,7 @@ BINOBJS = $(foreach file, $(OBJS), $file) | |||
32 | 33 | ||
33 | CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' $(HAVE_GCOV) | 34 | CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' $(HAVE_GCOV) |
34 | CFLAGS += -DPREFIX='"$(prefix)"' -DSYSCONFDIR='"$(sysconfdir)/firejail"' -DLIBDIR='"$(libdir)"' -DBINDIR='"$(bindir)"' | 35 | CFLAGS += -DPREFIX='"$(prefix)"' -DSYSCONFDIR='"$(sysconfdir)/firejail"' -DLIBDIR='"$(libdir)"' -DBINDIR='"$(bindir)"' |
35 | 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) | 36 | 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) |
36 | CFLAGS += -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security | 37 | CFLAGS += -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security |
37 | LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now -lpthread | 38 | LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now -lpthread |
38 | EXTRA_LDFLAGS +=@EXTRA_LDFLAGS@ | 39 | EXTRA_LDFLAGS +=@EXTRA_LDFLAGS@ |
diff --git a/src/fcopy/main.c b/src/fcopy/main.c index 5c4a76753..83d9c17e6 100644 --- a/src/fcopy/main.c +++ b/src/fcopy/main.c | |||
@@ -24,6 +24,15 @@ | |||
24 | #include <errno.h> | 24 | #include <errno.h> |
25 | #include <pwd.h> | 25 | #include <pwd.h> |
26 | 26 | ||
27 | #if HAVE_SELINUX | ||
28 | #include <sys/stat.h> | ||
29 | #include <sys/types.h> | ||
30 | |||
31 | #include <selinux/context.h> | ||
32 | #include <selinux/label.h> | ||
33 | #include <selinux/selinux.h> | ||
34 | #endif | ||
35 | |||
27 | int arg_quiet = 0; | 36 | int arg_quiet = 0; |
28 | int arg_debug = 0; | 37 | int arg_debug = 0; |
29 | static int arg_follow_link = 0; | 38 | static int arg_follow_link = 0; |
@@ -36,6 +45,52 @@ static unsigned file_cnt = 0; | |||
36 | static char *outpath = NULL; | 45 | static char *outpath = NULL; |
37 | static char *inpath = NULL; | 46 | static char *inpath = NULL; |
38 | 47 | ||
48 | #if HAVE_SELINUX | ||
49 | static struct selabel_handle *label_hnd = NULL; | ||
50 | static int selinux_enabled = -1; | ||
51 | #endif | ||
52 | |||
53 | // copy from firejail/selinux.c | ||
54 | static void selinux_relabel_path(const char *path, const char *inside_path) | ||
55 | { | ||
56 | #if HAVE_SELINUX | ||
57 | char procfs_path[64]; | ||
58 | char *fcon = NULL; | ||
59 | int fd; | ||
60 | struct stat st; | ||
61 | |||
62 | if (selinux_enabled == -1) | ||
63 | selinux_enabled = is_selinux_enabled(); | ||
64 | |||
65 | if (!selinux_enabled) | ||
66 | return; | ||
67 | |||
68 | if (!label_hnd) | ||
69 | label_hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0); | ||
70 | |||
71 | /* Open the file as O_PATH, to pin it while we determine and adjust the label */ | ||
72 | fd = open(path, O_NOFOLLOW|O_CLOEXEC|O_PATH); | ||
73 | if (fd < 0) | ||
74 | return; | ||
75 | if (fstat(fd, &st) < 0) | ||
76 | goto close; | ||
77 | |||
78 | if (selabel_lookup_raw(label_hnd, &fcon, inside_path, st.st_mode) == 0) { | ||
79 | sprintf(procfs_path, "/proc/self/fd/%i", fd); | ||
80 | if (arg_debug) | ||
81 | printf("Relabeling %s as %s (%s)\n", path, inside_path, fcon); | ||
82 | |||
83 | setfilecon_raw(procfs_path, fcon); | ||
84 | } | ||
85 | freecon(fcon); | ||
86 | close: | ||
87 | close(fd); | ||
88 | #else | ||
89 | (void) path; | ||
90 | (void) inside_path; | ||
91 | #endif | ||
92 | } | ||
93 | |||
39 | // modified version of the function from util.c | 94 | // modified version of the function from util.c |
40 | static void copy_file(const char *srcname, const char *destname, mode_t mode, uid_t uid, gid_t gid) { | 95 | static void copy_file(const char *srcname, const char *destname, mode_t mode, uid_t uid, gid_t gid) { |
41 | assert(srcname); | 96 | assert(srcname); |
@@ -87,6 +142,8 @@ static void copy_file(const char *srcname, const char *destname, mode_t mode, ui | |||
87 | close(src); | 142 | close(src); |
88 | close(dst); | 143 | close(dst); |
89 | 144 | ||
145 | selinux_relabel_path(destname, srcname); | ||
146 | |||
90 | return; | 147 | return; |
91 | 148 | ||
92 | errexit: | 149 | errexit: |
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 4dc580a5e..66328a55e 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -833,4 +833,7 @@ extern pid_t dhclient4_pid; | |||
833 | extern pid_t dhclient6_pid; | 833 | extern pid_t dhclient6_pid; |
834 | void dhcp_start(void); | 834 | void dhcp_start(void); |
835 | 835 | ||
836 | // selinux.c | ||
837 | void selinux_relabel_path(const char *path, const char *inside_path); | ||
838 | |||
836 | #endif | 839 | #endif |
diff --git a/src/firejail/fs_bin.c b/src/firejail/fs_bin.c index 7150fd3eb..a48d6cf67 100644 --- a/src/firejail/fs_bin.c +++ b/src/firejail/fs_bin.c | |||
@@ -309,5 +309,6 @@ void fs_private_bin_list(void) { | |||
309 | } | 309 | } |
310 | i++; | 310 | i++; |
311 | } | 311 | } |
312 | selinux_relabel_path(RUN_BIN_DIR, "/bin"); | ||
312 | fmessage("%d %s installed in %0.2f ms\n", prog_cnt, (prog_cnt == 1)? "program": "programs", timetrace_end()); | 313 | fmessage("%d %s installed in %0.2f ms\n", prog_cnt, (prog_cnt == 1)? "program": "programs", timetrace_end()); |
313 | } | 314 | } |
diff --git a/src/firejail/fs_dev.c b/src/firejail/fs_dev.c index 63911ab9e..500b6bf1b 100644 --- a/src/firejail/fs_dev.c +++ b/src/firejail/fs_dev.c | |||
@@ -167,6 +167,7 @@ static void create_link(const char *oldpath, const char *newpath) { | |||
167 | static void empty_dev_shm(void) { | 167 | static void empty_dev_shm(void) { |
168 | // create an empty /dev/shm directory | 168 | // create an empty /dev/shm directory |
169 | mkdir_attr("/dev/shm", 01777, 0, 0); | 169 | mkdir_attr("/dev/shm", 01777, 0, 0); |
170 | selinux_relabel_path("/dev/shm", "/dev/shm"); | ||
170 | fs_logger("mkdir /dev/shm"); | 171 | fs_logger("mkdir /dev/shm"); |
171 | fs_logger("create /dev/shm"); | 172 | fs_logger("create /dev/shm"); |
172 | } | 173 | } |
@@ -276,10 +277,13 @@ void fs_private_dev(void){ | |||
276 | // pseudo-terminal | 277 | // pseudo-terminal |
277 | mkdir_attr("/dev/pts", 0755, 0, 0); | 278 | mkdir_attr("/dev/pts", 0755, 0, 0); |
278 | fs_logger("mkdir /dev/pts"); | 279 | fs_logger("mkdir /dev/pts"); |
280 | selinux_relabel_path("/dev/pts", "/dev/pts"); | ||
279 | fs_logger("create /dev/pts"); | 281 | fs_logger("create /dev/pts"); |
280 | create_char_dev("/dev/pts/ptmx", 0666, 5, 2); //"mknod -m 666 /dev/pts/ptmx c 5 2"); | 282 | create_char_dev("/dev/pts/ptmx", 0666, 5, 2); //"mknod -m 666 /dev/pts/ptmx c 5 2"); |
283 | selinux_relabel_path("/dev/pts/ptmx", "/dev/pts/ptmx"); | ||
281 | fs_logger("mknod /dev/pts/ptmx"); | 284 | fs_logger("mknod /dev/pts/ptmx"); |
282 | create_link("/dev/pts/ptmx", "/dev/ptmx"); | 285 | create_link("/dev/pts/ptmx", "/dev/ptmx"); |
286 | selinux_relabel_path("/dev/ptmx", "/dev/ptmx"); | ||
283 | 287 | ||
284 | // code before github issue #351 | 288 | // code before github issue #351 |
285 | // mount -vt devpts -o newinstance -o ptmxmode=0666 devpts //dev/pts | 289 | // mount -vt devpts -o newinstance -o ptmxmode=0666 devpts //dev/pts |
diff --git a/src/firejail/fs_etc.c b/src/firejail/fs_etc.c index 76bcb751e..271e46855 100644 --- a/src/firejail/fs_etc.c +++ b/src/firejail/fs_etc.c | |||
@@ -59,6 +59,7 @@ void fs_machineid(void) { | |||
59 | if (set_perms(RUN_MACHINEID, 0, 0, 0444)) | 59 | if (set_perms(RUN_MACHINEID, 0, 0, 0444)) |
60 | errExit("set_perms"); | 60 | errExit("set_perms"); |
61 | 61 | ||
62 | selinux_relabel_path(RUN_MACHINEID, "/etc/machine-id"); | ||
62 | 63 | ||
63 | struct stat s; | 64 | struct stat s; |
64 | if (stat("/etc/machine-id", &s) == 0) { | 65 | 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 | |||
154 | 155 | ||
155 | // create /run/firejail/mnt/etc directory | 156 | // create /run/firejail/mnt/etc directory |
156 | mkdir_attr(private_run_dir, 0755, 0, 0); | 157 | mkdir_attr(private_run_dir, 0755, 0, 0); |
158 | selinux_relabel_path(private_run_dir, private_dir); | ||
157 | fs_logger2("tmpfs", private_dir); | 159 | fs_logger2("tmpfs", private_dir); |
158 | 160 | ||
159 | fs_logger_print(); // save the current log | 161 | fs_logger_print(); // save the current log |
diff --git a/src/firejail/fs_home.c b/src/firejail/fs_home.c index bdfaba480..bec22e5a6 100644 --- a/src/firejail/fs_home.c +++ b/src/firejail/fs_home.c | |||
@@ -60,6 +60,7 @@ static void skel(const char *homedir, uid_t u, gid_t g) { | |||
60 | touch_file_as_user(fname, 0644); | 60 | touch_file_as_user(fname, 0644); |
61 | fs_logger2("touch", fname); | 61 | fs_logger2("touch", fname); |
62 | } | 62 | } |
63 | selinux_relabel_path(fname, fname); | ||
63 | free(fname); | 64 | free(fname); |
64 | } | 65 | } |
65 | // csh | 66 | // csh |
@@ -85,6 +86,7 @@ static void skel(const char *homedir, uid_t u, gid_t g) { | |||
85 | touch_file_as_user(fname, 0644); | 86 | touch_file_as_user(fname, 0644); |
86 | fs_logger2("touch", fname); | 87 | fs_logger2("touch", fname); |
87 | } | 88 | } |
89 | selinux_relabel_path(fname, fname); | ||
88 | free(fname); | 90 | free(fname); |
89 | } | 91 | } |
90 | // bash etc. | 92 | // bash etc. |
@@ -105,6 +107,7 @@ static void skel(const char *homedir, uid_t u, gid_t g) { | |||
105 | fs_logger("clone /etc/skel/.bashrc"); | 107 | fs_logger("clone /etc/skel/.bashrc"); |
106 | fs_logger2("clone", fname); | 108 | fs_logger2("clone", fname); |
107 | } | 109 | } |
110 | selinux_relabel_path(fname, fname); | ||
108 | free(fname); | 111 | free(fname); |
109 | } | 112 | } |
110 | } | 113 | } |
@@ -139,6 +142,7 @@ static int store_xauthority(void) { | |||
139 | 142 | ||
140 | copy_file_as_user(src, dest, getuid(), getgid(), 0600); // regular user | 143 | copy_file_as_user(src, dest, getuid(), getgid(), 0600); // regular user |
141 | fs_logger2("clone", dest); | 144 | fs_logger2("clone", dest); |
145 | selinux_relabel_path(dest, src); | ||
142 | free(src); | 146 | free(src); |
143 | return 1; // file copied | 147 | return 1; // file copied |
144 | } | 148 | } |
@@ -185,6 +189,7 @@ static int store_asoundrc(void) { | |||
185 | errExit("fopen"); | 189 | errExit("fopen"); |
186 | 190 | ||
187 | copy_file_as_user(src, dest, getuid(), getgid(), 0644); // regular user | 191 | copy_file_as_user(src, dest, getuid(), getgid(), 0644); // regular user |
192 | selinux_relabel_path(dest, src); | ||
188 | fs_logger2("clone", dest); | 193 | fs_logger2("clone", dest); |
189 | free(src); | 194 | free(src); |
190 | return 1; // file copied | 195 | return 1; // file copied |
@@ -208,6 +213,7 @@ static void copy_xauthority(void) { | |||
208 | } | 213 | } |
209 | 214 | ||
210 | copy_file_as_user(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR); // regular user | 215 | copy_file_as_user(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR); // regular user |
216 | selinux_relabel_path(dest, src); | ||
211 | fs_logger2("clone", dest); | 217 | fs_logger2("clone", dest); |
212 | free(dest); | 218 | free(dest); |
213 | 219 | ||
@@ -313,6 +319,7 @@ void fs_private_homedir(void) { | |||
313 | printf("Mounting a new /root directory\n"); | 319 | printf("Mounting a new /root directory\n"); |
314 | if (mount("tmpfs", "/root", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_STRICTATIME, "mode=700,gid=0") < 0) | 320 | if (mount("tmpfs", "/root", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_STRICTATIME, "mode=700,gid=0") < 0) |
315 | errExit("mounting /root directory"); | 321 | errExit("mounting /root directory"); |
322 | selinux_relabel_path("/root", "/root"); | ||
316 | fs_logger("tmpfs /root"); | 323 | fs_logger("tmpfs /root"); |
317 | } | 324 | } |
318 | if (u == 0 && !arg_allusers) { | 325 | if (u == 0 && !arg_allusers) { |
@@ -321,6 +328,7 @@ void fs_private_homedir(void) { | |||
321 | printf("Mounting a new /home directory\n"); | 328 | printf("Mounting a new /home directory\n"); |
322 | if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_STRICTATIME, "mode=755,gid=0") < 0) | 329 | if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_STRICTATIME, "mode=755,gid=0") < 0) |
323 | errExit("mounting /home directory"); | 330 | errExit("mounting /home directory"); |
331 | selinux_relabel_path("/home", "/home"); | ||
324 | fs_logger("tmpfs /home"); | 332 | fs_logger("tmpfs /home"); |
325 | } | 333 | } |
326 | 334 | ||
@@ -355,6 +363,7 @@ void fs_private(void) { | |||
355 | fwarning("allusers option disabled by private or whitelist option\n"); | 363 | fwarning("allusers option disabled by private or whitelist option\n"); |
356 | if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_STRICTATIME, "mode=755,gid=0") < 0) | 364 | if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_STRICTATIME, "mode=755,gid=0") < 0) |
357 | errExit("mounting /home directory"); | 365 | errExit("mounting /home directory"); |
366 | selinux_relabel_path("/home", "/home"); | ||
358 | fs_logger("tmpfs /home"); | 367 | fs_logger("tmpfs /home"); |
359 | } | 368 | } |
360 | 369 | ||
@@ -378,6 +387,8 @@ void fs_private(void) { | |||
378 | } | 387 | } |
379 | if (chown(homedir, u, g) < 0) | 388 | if (chown(homedir, u, g) < 0) |
380 | errExit("chown"); | 389 | errExit("chown"); |
390 | selinux_relabel_path(homedir, homedir); | ||
391 | |||
381 | fs_logger2("mkdir", homedir); | 392 | fs_logger2("mkdir", homedir); |
382 | fs_logger2("tmpfs", homedir); | 393 | fs_logger2("tmpfs", homedir); |
383 | } | 394 | } |
@@ -542,6 +553,7 @@ void fs_private_home_list(void) { | |||
542 | 553 | ||
543 | // create /run/firejail/mnt/home directory | 554 | // create /run/firejail/mnt/home directory |
544 | mkdir_attr(RUN_HOME_DIR, 0755, uid, gid); | 555 | mkdir_attr(RUN_HOME_DIR, 0755, uid, gid); |
556 | selinux_relabel_path(RUN_HOME_DIR, "/home"); | ||
545 | fs_logger_print(); // save the current log | 557 | fs_logger_print(); // save the current log |
546 | 558 | ||
547 | if (arg_debug) | 559 | if (arg_debug) |
@@ -604,6 +616,7 @@ void fs_private_home_list(void) { | |||
604 | printf("Mounting a new /root directory\n"); | 616 | printf("Mounting a new /root directory\n"); |
605 | if (mount("tmpfs", "/root", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, "mode=700,gid=0") < 0) | 617 | if (mount("tmpfs", "/root", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, "mode=700,gid=0") < 0) |
606 | errExit("mounting /root directory"); | 618 | errExit("mounting /root directory"); |
619 | selinux_relabel_path("/root", "/root"); | ||
607 | fs_logger("tmpfs /root"); | 620 | fs_logger("tmpfs /root"); |
608 | } | 621 | } |
609 | if (uid == 0 && !arg_allusers) { | 622 | if (uid == 0 && !arg_allusers) { |
@@ -612,6 +625,7 @@ void fs_private_home_list(void) { | |||
612 | printf("Mounting a new /home directory\n"); | 625 | printf("Mounting a new /home directory\n"); |
613 | if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, "mode=755,gid=0") < 0) | 626 | if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, "mode=755,gid=0") < 0) |
614 | errExit("mounting /home directory"); | 627 | errExit("mounting /home directory"); |
628 | selinux_relabel_path("/home", "/home"); | ||
615 | fs_logger("tmpfs /home"); | 629 | fs_logger("tmpfs /home"); |
616 | } | 630 | } |
617 | 631 | ||
diff --git a/src/firejail/fs_hostname.c b/src/firejail/fs_hostname.c index fd5e1bbd3..5d6fddf8e 100644 --- a/src/firejail/fs_hostname.c +++ b/src/firejail/fs_hostname.c | |||
@@ -96,6 +96,7 @@ void fs_resolvconf(void) { | |||
96 | printf("mirroring /etc directory\n"); | 96 | printf("mirroring /etc directory\n"); |
97 | if (mkdir(RUN_DNS_ETC, 0755)) | 97 | if (mkdir(RUN_DNS_ETC, 0755)) |
98 | errExit("mkdir"); | 98 | errExit("mkdir"); |
99 | selinux_relabel_path(RUN_DNS_ETC, "/etc"); | ||
99 | fs_logger("tmpfs /etc"); | 100 | fs_logger("tmpfs /etc"); |
100 | 101 | ||
101 | DIR *dir = opendir("/etc"); | 102 | DIR *dir = opendir("/etc"); |
diff --git a/src/firejail/fs_lib.c b/src/firejail/fs_lib.c index c539ce83c..64444bba2 100644 --- a/src/firejail/fs_lib.c +++ b/src/firejail/fs_lib.c | |||
@@ -326,6 +326,7 @@ void fs_private_lib(void) { | |||
326 | 326 | ||
327 | // create /run/firejail/mnt/lib directory | 327 | // create /run/firejail/mnt/lib directory |
328 | mkdir_attr(RUN_LIB_DIR, 0755, 0, 0); | 328 | mkdir_attr(RUN_LIB_DIR, 0755, 0, 0); |
329 | selinux_relabel_path(RUN_LIB_DIR, "/usr/lib"); | ||
329 | 330 | ||
330 | // install standard C libraries | 331 | // install standard C libraries |
331 | if (arg_debug || arg_debug_private_lib) | 332 | if (arg_debug || arg_debug_private_lib) |
diff --git a/src/firejail/fs_lib2.c b/src/firejail/fs_lib2.c index 2982c4cbb..b2ae07f3e 100644 --- a/src/firejail/fs_lib2.c +++ b/src/firejail/fs_lib2.c | |||
@@ -109,6 +109,7 @@ void fslib_install_stdc(void) { | |||
109 | 109 | ||
110 | if (stat("/lib/x86_64-linux-gnu", &s) == 0) { // Debian & friends | 110 | if (stat("/lib/x86_64-linux-gnu", &s) == 0) { // Debian & friends |
111 | mkdir_attr(RUN_LIB_DIR "/x86_64-linux-gnu", 0755, 0, 0); | 111 | mkdir_attr(RUN_LIB_DIR "/x86_64-linux-gnu", 0755, 0, 0); |
112 | selinux_relabel_path(RUN_LIB_DIR "/x86_64-linux-gnu", "/lib/x86_64-linux-gnu"); | ||
112 | stdclib = "/lib/x86_64-linux-gnu"; | 113 | stdclib = "/lib/x86_64-linux-gnu"; |
113 | } | 114 | } |
114 | 115 | ||
diff --git a/src/firejail/fs_var.c b/src/firejail/fs_var.c index 303d6f9aa..cafe9fa49 100644 --- a/src/firejail/fs_var.c +++ b/src/firejail/fs_var.c | |||
@@ -223,9 +223,11 @@ void fs_var_cache(void) { | |||
223 | } | 223 | } |
224 | 224 | ||
225 | mkdir_attr("/var/cache/lighttpd/compress", 0755, uid, gid); | 225 | mkdir_attr("/var/cache/lighttpd/compress", 0755, uid, gid); |
226 | selinux_relabel_path("/var/cache/lighttpd/compress", "/var/cache/lighttpd/compress"); | ||
226 | fs_logger("mkdir /var/cache/lighttpd/compress"); | 227 | fs_logger("mkdir /var/cache/lighttpd/compress"); |
227 | 228 | ||
228 | mkdir_attr("/var/cache/lighttpd/uploads", 0755, uid, gid); | 229 | mkdir_attr("/var/cache/lighttpd/uploads", 0755, uid, gid); |
230 | selinux_relabel_path("/var/cache/lighttpd/uploads", "/var/cache/lighttpd/uploads"); | ||
229 | fs_logger("/var/cache/lighttpd/uploads"); | 231 | fs_logger("/var/cache/lighttpd/uploads"); |
230 | } | 232 | } |
231 | } | 233 | } |
diff --git a/src/firejail/fs_whitelist.c b/src/firejail/fs_whitelist.c index be5bcc4c0..c5b066b12 100644 --- a/src/firejail/fs_whitelist.c +++ b/src/firejail/fs_whitelist.c | |||
@@ -734,6 +734,7 @@ void fs_whitelist(void) { | |||
734 | printf("Mounting tmpfs on /tmp directory\n"); | 734 | printf("Mounting tmpfs on /tmp directory\n"); |
735 | if (mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=1777,gid=0") < 0) | 735 | if (mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=1777,gid=0") < 0) |
736 | errExit("mounting tmpfs on /tmp"); | 736 | errExit("mounting tmpfs on /tmp"); |
737 | selinux_relabel_path("/tmp", "/tmp"); | ||
737 | fs_logger("tmpfs /tmp"); | 738 | fs_logger("tmpfs /tmp"); |
738 | 739 | ||
739 | // pam-tmpdir - issue #2685 | 740 | // pam-tmpdir - issue #2685 |
@@ -745,8 +746,10 @@ void fs_whitelist(void) { | |||
745 | if (strcmp(env, pamtmpdir) == 0) { | 746 | if (strcmp(env, pamtmpdir) == 0) { |
746 | // create empty user-owned /tmp/user/$uid directory | 747 | // create empty user-owned /tmp/user/$uid directory |
747 | mkdir_attr("/tmp/user", 0711, 0, 0); | 748 | mkdir_attr("/tmp/user", 0711, 0, 0); |
749 | selinux_relabel_path("/tmp/user", "/tmp/user"); | ||
748 | fs_logger("mkdir /tmp/user"); | 750 | fs_logger("mkdir /tmp/user"); |
749 | mkdir_attr(pamtmpdir, 0700, getuid(), 0); | 751 | mkdir_attr(pamtmpdir, 0700, getuid(), 0); |
752 | selinux_relabel_path(pamtmpdir, pamtmpdir); | ||
750 | fs_logger2("mkdir", pamtmpdir); | 753 | fs_logger2("mkdir", pamtmpdir); |
751 | } | 754 | } |
752 | free(pamtmpdir); | 755 | free(pamtmpdir); |
@@ -774,6 +777,7 @@ void fs_whitelist(void) { | |||
774 | printf("Mounting tmpfs on /media directory\n"); | 777 | printf("Mounting tmpfs on /media directory\n"); |
775 | if (mount("tmpfs", "/media", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0) | 778 | if (mount("tmpfs", "/media", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0) |
776 | errExit("mounting tmpfs on /media"); | 779 | errExit("mounting tmpfs on /media"); |
780 | selinux_relabel_path("/media", "/media"); | ||
777 | fs_logger("tmpfs /media"); | 781 | fs_logger("tmpfs /media"); |
778 | 782 | ||
779 | // autowhitelist home directory if it is masked by the tmpfs | 783 | // autowhitelist home directory if it is masked by the tmpfs |
@@ -798,6 +802,7 @@ void fs_whitelist(void) { | |||
798 | printf("Mounting tmpfs on /mnt directory\n"); | 802 | printf("Mounting tmpfs on /mnt directory\n"); |
799 | if (mount("tmpfs", "/mnt", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0) | 803 | if (mount("tmpfs", "/mnt", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0) |
800 | errExit("mounting tmpfs on /mnt"); | 804 | errExit("mounting tmpfs on /mnt"); |
805 | selinux_relabel_path("/mnt", "/mnt"); | ||
801 | fs_logger("tmpfs /mnt"); | 806 | fs_logger("tmpfs /mnt"); |
802 | 807 | ||
803 | // autowhitelist home directory if it is masked by the tmpfs | 808 | // autowhitelist home directory if it is masked by the tmpfs |
@@ -822,6 +827,7 @@ void fs_whitelist(void) { | |||
822 | printf("Mounting tmpfs on /var directory\n"); | 827 | printf("Mounting tmpfs on /var directory\n"); |
823 | if (mount("tmpfs", "/var", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0) | 828 | if (mount("tmpfs", "/var", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0) |
824 | errExit("mounting tmpfs on /var"); | 829 | errExit("mounting tmpfs on /var"); |
830 | selinux_relabel_path("/var", "/var"); | ||
825 | fs_logger("tmpfs /var"); | 831 | fs_logger("tmpfs /var"); |
826 | 832 | ||
827 | // autowhitelist home directory if it is masked by the tmpfs | 833 | // autowhitelist home directory if it is masked by the tmpfs |
@@ -846,6 +852,7 @@ void fs_whitelist(void) { | |||
846 | printf("Mounting tmpfs on /dev directory\n"); | 852 | printf("Mounting tmpfs on /dev directory\n"); |
847 | if (mount("tmpfs", "/dev", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0) | 853 | if (mount("tmpfs", "/dev", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0) |
848 | errExit("mounting tmpfs on /dev"); | 854 | errExit("mounting tmpfs on /dev"); |
855 | selinux_relabel_path("/dev", "/dev"); | ||
849 | fs_logger("tmpfs /dev"); | 856 | fs_logger("tmpfs /dev"); |
850 | 857 | ||
851 | // autowhitelist home directory if it is masked by the tmpfs | 858 | // autowhitelist home directory if it is masked by the tmpfs |
@@ -870,6 +877,7 @@ void fs_whitelist(void) { | |||
870 | printf("Mounting tmpfs on /opt directory\n"); | 877 | printf("Mounting tmpfs on /opt directory\n"); |
871 | if (mount("tmpfs", "/opt", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0) | 878 | if (mount("tmpfs", "/opt", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0) |
872 | errExit("mounting tmpfs on /opt"); | 879 | errExit("mounting tmpfs on /opt"); |
880 | selinux_relabel_path("/opt", "/opt"); | ||
873 | fs_logger("tmpfs /opt"); | 881 | fs_logger("tmpfs /opt"); |
874 | 882 | ||
875 | // autowhitelist home directory if it is masked by the tmpfs | 883 | // autowhitelist home directory if it is masked by the tmpfs |
@@ -894,6 +902,7 @@ void fs_whitelist(void) { | |||
894 | printf("Mounting tmpfs on /srv directory\n"); | 902 | printf("Mounting tmpfs on /srv directory\n"); |
895 | if (mount("tmpfs", "/srv", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0) | 903 | if (mount("tmpfs", "/srv", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0) |
896 | errExit("mounting tmpfs on /srv"); | 904 | errExit("mounting tmpfs on /srv"); |
905 | selinux_relabel_path("/srv", "/srv"); | ||
897 | fs_logger("tmpfs /srv"); | 906 | fs_logger("tmpfs /srv"); |
898 | 907 | ||
899 | // autowhitelist home directory if it is masked by the tmpfs | 908 | // autowhitelist home directory if it is masked by the tmpfs |
@@ -918,6 +927,7 @@ void fs_whitelist(void) { | |||
918 | printf("Mounting tmpfs on /etc directory\n"); | 927 | printf("Mounting tmpfs on /etc directory\n"); |
919 | if (mount("tmpfs", "/etc", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0) | 928 | if (mount("tmpfs", "/etc", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0) |
920 | errExit("mounting tmpfs on /etc"); | 929 | errExit("mounting tmpfs on /etc"); |
930 | selinux_relabel_path("/etc", "/etc"); | ||
921 | fs_logger("tmpfs /etc"); | 931 | fs_logger("tmpfs /etc"); |
922 | 932 | ||
923 | // autowhitelist home directory if it is masked by the tmpfs | 933 | // autowhitelist home directory if it is masked by the tmpfs |
@@ -942,6 +952,7 @@ void fs_whitelist(void) { | |||
942 | printf("Mounting tmpfs on /usr/share directory\n"); | 952 | printf("Mounting tmpfs on /usr/share directory\n"); |
943 | if (mount("tmpfs", "/usr/share", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0) | 953 | if (mount("tmpfs", "/usr/share", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0) |
944 | errExit("mounting tmpfs on /usr/share"); | 954 | errExit("mounting tmpfs on /usr/share"); |
955 | selinux_relabel_path("/usr/share", "/usr/share"); | ||
945 | fs_logger("tmpfs /usr/share"); | 956 | fs_logger("tmpfs /usr/share"); |
946 | 957 | ||
947 | // autowhitelist home directory if it is masked by the tmpfs | 958 | // autowhitelist home directory if it is masked by the tmpfs |
@@ -966,6 +977,7 @@ void fs_whitelist(void) { | |||
966 | printf("Mounting tmpfs on /sys/module directory\n"); | 977 | printf("Mounting tmpfs on /sys/module directory\n"); |
967 | if (mount("tmpfs", "/sys/module", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0) | 978 | if (mount("tmpfs", "/sys/module", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0) |
968 | errExit("mounting tmpfs on /sys/module"); | 979 | errExit("mounting tmpfs on /sys/module"); |
980 | selinux_relabel_path("/sys/module", "/sys/module"); | ||
969 | fs_logger("tmpfs /sys/module"); | 981 | fs_logger("tmpfs /sys/module"); |
970 | } | 982 | } |
971 | else | 983 | else |
@@ -989,6 +1001,7 @@ void fs_whitelist(void) { | |||
989 | errExit("asprintf"); | 1001 | errExit("asprintf"); |
990 | if (mount("tmpfs", runuser, "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, options) < 0) | 1002 | if (mount("tmpfs", runuser, "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, options) < 0) |
991 | errExit("mounting tmpfs on /run/user/<uid>"); | 1003 | errExit("mounting tmpfs on /run/user/<uid>"); |
1004 | selinux_relabel_path(runuser, runuser); | ||
992 | free(options); | 1005 | free(options); |
993 | fs_logger2("tmpfs", runuser); | 1006 | fs_logger2("tmpfs", runuser); |
994 | 1007 | ||
diff --git a/src/firejail/pulseaudio.c b/src/firejail/pulseaudio.c index 57095a53c..a8fb838ab 100644 --- a/src/firejail/pulseaudio.c +++ b/src/firejail/pulseaudio.c | |||
@@ -87,6 +87,7 @@ void pulseaudio_init(void) { | |||
87 | // create the new user pulseaudio directory | 87 | // create the new user pulseaudio directory |
88 | if (mkdir(RUN_PULSE_DIR, 0700) == -1) | 88 | if (mkdir(RUN_PULSE_DIR, 0700) == -1) |
89 | errExit("mkdir"); | 89 | errExit("mkdir"); |
90 | selinux_relabel_path(RUN_PULSE_DIR, RUN_PULSE_DIR); | ||
90 | // mount it nosuid, noexec, nodev | 91 | // mount it nosuid, noexec, nodev |
91 | fs_remount(RUN_PULSE_DIR, MOUNT_NOEXEC, 0); | 92 | fs_remount(RUN_PULSE_DIR, MOUNT_NOEXEC, 0); |
92 | 93 | ||
diff --git a/src/firejail/restrict_users.c b/src/firejail/restrict_users.c index b51172219..5ebb0e9ec 100644 --- a/src/firejail/restrict_users.c +++ b/src/firejail/restrict_users.c | |||
@@ -97,6 +97,7 @@ static void sanitize_home(void) { | |||
97 | // mount tmpfs in the new home | 97 | // mount tmpfs in the new home |
98 | if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, "mode=755,gid=0") < 0) | 98 | if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, "mode=755,gid=0") < 0) |
99 | errExit("mount tmpfs"); | 99 | errExit("mount tmpfs"); |
100 | selinux_relabel_path("/home", "/home"); | ||
100 | fs_logger("tmpfs /home"); | 101 | fs_logger("tmpfs /home"); |
101 | 102 | ||
102 | // create user home directory | 103 | // create user home directory |
@@ -105,6 +106,7 @@ static void sanitize_home(void) { | |||
105 | errExit("mkpath"); | 106 | errExit("mkpath"); |
106 | if (mkdir(cfg.homedir, 0755) == -1) | 107 | if (mkdir(cfg.homedir, 0755) == -1) |
107 | errExit("mkdir"); | 108 | errExit("mkdir"); |
109 | selinux_relabel_path(cfg.homedir, cfg.homedir); | ||
108 | } | 110 | } |
109 | fs_logger2("mkdir", cfg.homedir); | 111 | fs_logger2("mkdir", cfg.homedir); |
110 | 112 | ||
@@ -152,11 +154,13 @@ static void sanitize_run(void) { | |||
152 | // mount tmpfs on /run/user | 154 | // mount tmpfs on /run/user |
153 | if (mount("tmpfs", "/run/user", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, "mode=755,gid=0") < 0) | 155 | if (mount("tmpfs", "/run/user", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, "mode=755,gid=0") < 0) |
154 | errExit("mount tmpfs"); | 156 | errExit("mount tmpfs"); |
157 | selinux_relabel_path("/run/user", "/run/user"); | ||
155 | fs_logger("tmpfs /run/user"); | 158 | fs_logger("tmpfs /run/user"); |
156 | 159 | ||
157 | // create new user directory | 160 | // create new user directory |
158 | if (mkdir(runuser, 0700) == -1) | 161 | if (mkdir(runuser, 0700) == -1) |
159 | errExit("mkdir"); | 162 | errExit("mkdir"); |
163 | selinux_relabel_path(runuser, runuser); | ||
160 | fs_logger2("mkdir", runuser); | 164 | fs_logger2("mkdir", runuser); |
161 | 165 | ||
162 | // set mode and ownership | 166 | // set mode and ownership |
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index 4f53cafcc..d1d98f636 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c | |||
@@ -848,20 +848,6 @@ int sandbox(void* sandbox_arg) { | |||
848 | if (arg_private_dev) | 848 | if (arg_private_dev) |
849 | fs_private_dev(); | 849 | fs_private_dev(); |
850 | 850 | ||
851 | if (arg_private_etc) { | ||
852 | if (cfg.chrootdir) | ||
853 | fwarning("private-etc feature is disabled in chroot\n"); | ||
854 | else if (arg_overlay) | ||
855 | fwarning("private-etc feature is disabled in overlay\n"); | ||
856 | else { | ||
857 | fs_private_dir_list("/etc", RUN_ETC_DIR, cfg.etc_private_keep); | ||
858 | fs_private_dir_list("/usr/etc", RUN_USR_ETC_DIR, cfg.etc_private_keep); // openSUSE | ||
859 | // create /etc/ld.so.preload file again | ||
860 | if (need_preload) | ||
861 | fs_trace_preload(); | ||
862 | } | ||
863 | } | ||
864 | |||
865 | if (arg_private_opt) { | 851 | if (arg_private_opt) { |
866 | if (cfg.chrootdir) | 852 | if (cfg.chrootdir) |
867 | fwarning("private-opt feature is disabled in chroot\n"); | 853 | fwarning("private-opt feature is disabled in chroot\n"); |
@@ -964,6 +950,21 @@ int sandbox(void* sandbox_arg) { | |||
964 | else if (arg_disable_mnt) | 950 | else if (arg_disable_mnt) |
965 | fs_mnt(0); | 951 | fs_mnt(0); |
966 | 952 | ||
953 | // Install new /etc last, so we can use it as long as possible | ||
954 | if (arg_private_etc) { | ||
955 | if (cfg.chrootdir) | ||
956 | fwarning("private-etc feature is disabled in chroot\n"); | ||
957 | else if (arg_overlay) | ||
958 | fwarning("private-etc feature is disabled in overlay\n"); | ||
959 | else { | ||
960 | fs_private_dir_list("/etc", RUN_ETC_DIR, cfg.etc_private_keep); | ||
961 | fs_private_dir_list("/usr/etc", RUN_USR_ETC_DIR, cfg.etc_private_keep); // openSUSE | ||
962 | // create /etc/ld.so.preload file again | ||
963 | if (need_preload) | ||
964 | fs_trace_preload(); | ||
965 | } | ||
966 | } | ||
967 | |||
967 | //**************************** | 968 | //**************************** |
968 | // apply the profile file | 969 | // apply the profile file |
969 | //**************************** | 970 | //**************************** |
diff --git a/src/firejail/selinux.c b/src/firejail/selinux.c new file mode 100644 index 000000000..52d6788ef --- /dev/null +++ b/src/firejail/selinux.c | |||
@@ -0,0 +1,73 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2020 Firejail and systemd authors | ||
3 | * | ||
4 | * This file is part of firejail project, from systemd selinux-util.c | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | #if HAVE_SELINUX | ||
21 | #include "firejail.h" | ||
22 | |||
23 | #include <sys/types.h> | ||
24 | #include <sys/stat.h> | ||
25 | #include <fcntl.h> | ||
26 | |||
27 | #include <selinux/context.h> | ||
28 | #include <selinux/label.h> | ||
29 | #include <selinux/selinux.h> | ||
30 | |||
31 | static struct selabel_handle *label_hnd = NULL; | ||
32 | static int selinux_enabled = -1; | ||
33 | #endif | ||
34 | |||
35 | void selinux_relabel_path(const char *path, const char *inside_path) | ||
36 | { | ||
37 | #if HAVE_SELINUX | ||
38 | char procfs_path[64]; | ||
39 | char *fcon = NULL; | ||
40 | int fd; | ||
41 | struct stat st; | ||
42 | |||
43 | if (selinux_enabled == -1) | ||
44 | selinux_enabled = is_selinux_enabled(); | ||
45 | |||
46 | if (!selinux_enabled && arg_debug) | ||
47 | return; | ||
48 | |||
49 | if (!label_hnd) | ||
50 | label_hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0); | ||
51 | |||
52 | /* Open the file as O_PATH, to pin it while we determine and adjust the label */ | ||
53 | fd = open(path, O_NOFOLLOW|O_CLOEXEC|O_PATH); | ||
54 | if (fd < 0) | ||
55 | return; | ||
56 | if (fstat(fd, &st) < 0) | ||
57 | goto close; | ||
58 | |||
59 | if (selabel_lookup_raw(label_hnd, &fcon, inside_path, st.st_mode) == 0) { | ||
60 | sprintf(procfs_path, "/proc/self/fd/%i", fd); | ||
61 | if (arg_debug) | ||
62 | printf("Relabeling %s as %s (%s)\n", path, inside_path, fcon); | ||
63 | |||
64 | setfilecon_raw(procfs_path, fcon); | ||
65 | } | ||
66 | freecon(fcon); | ||
67 | close: | ||
68 | close(fd); | ||
69 | #else | ||
70 | (void) path; | ||
71 | (void) inside_path; | ||
72 | #endif | ||
73 | } | ||