aboutsummaryrefslogtreecommitdiffstats
path: root/src/fcopy
diff options
context:
space:
mode:
authorLibravatar Topi Miettinen <toiwoton@gmail.com>2020-02-18 20:38:00 +0200
committerLibravatar Topi Miettinen <topimiettinen@users.noreply.github.com>2020-02-22 08:27:24 +0000
commit1ad2d54c014a49f6ad0b487dd0d9b361cb4d299e (patch)
tree415eb19d90e2ed1de7236c784c1e28d3acfbcaab /src/fcopy
parentWhitelist more /usr/share for okular and others (diff)
downloadfirejail-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.c57
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
27int arg_quiet = 0; 36int arg_quiet = 0;
28int arg_debug = 0; 37int arg_debug = 0;
29static int arg_follow_link = 0; 38static int arg_follow_link = 0;
@@ -36,6 +45,52 @@ static unsigned file_cnt = 0;
36static char *outpath = NULL; 45static char *outpath = NULL;
37static char *inpath = NULL; 46static char *inpath = NULL;
38 47
48#if HAVE_SELINUX
49static struct selabel_handle *label_hnd = NULL;
50static int selinux_enabled = -1;
51#endif
52
53// copy from firejail/selinux.c
54static 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
40static void copy_file(const char *srcname, const char *destname, mode_t mode, uid_t uid, gid_t gid) { 95static 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
92errexit: 149errexit: