diff options
author | Topi Miettinen <toiwoton@gmail.com> | 2020-02-18 20:38:00 +0200 |
---|---|---|
committer | Topi Miettinen <topimiettinen@users.noreply.github.com> | 2020-02-22 08:27:24 +0000 |
commit | 1ad2d54c014a49f6ad0b487dd0d9b361cb4d299e (patch) | |
tree | 415eb19d90e2ed1de7236c784c1e28d3acfbcaab /src/fcopy | |
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/fcopy')
-rw-r--r-- | src/fcopy/main.c | 57 |
1 files changed, 57 insertions, 0 deletions
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: |