diff options
Diffstat (limited to 'src/fcopy/main.c')
-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: |