Codebase list firejail / d686079
Cherry-pick upstream fix for fcopy usage with private-lib Closes: #973756 Reiner Herrmann 3 years ago
2 changed file(s) with 260 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 From: smitsohu <smitsohu@gmail.com>
1 Subject: [PATCH] add PATH_FCOPY to private-lib automatically
2 Bug: https://github.com/netblue30/firejail/issues/3741
3 Bug-Debian: https://bugs.debian.org/973756
4 Origin: upstream, commits a274ad1 and 04cdc12
5
6 restore 45304621a6c600d8e30e98bfbef05149caaf56c5, but now run
7 fldd as root user. This became necessary because in the meantime
8 read permission on helper executables was removed.
9
10 Puts infrastructure in place to add other helper binaries to
11 private-lib as well, should the need arise.
12
13 --- a/src/firejail/fs_lib.c
14 +++ b/src/firejail/fs_lib.c
15 @@ -28,6 +28,7 @@
16 #define MAXBUF 4096
17
18 extern void fslib_install_stdc(void);
19 +extern void fslib_install_firejail(void);
20 extern void fslib_install_system(void);
21
22 static int lib_cnt = 0;
23 @@ -137,33 +138,22 @@
24 lib_cnt++;
25 }
26
27 -
28 // requires full path for lib
29 // it could be a library or an executable
30 // lib is not copied, only libraries used by it
31 -void fslib_copy_libs(const char *full_path) {
32 - assert(full_path);
33 - if (arg_debug || arg_debug_private_lib)
34 - printf(" fslib_copy_libs %s\n", full_path);
35 -
36 - // if library/executable does not exist or the user does not have read access to it
37 - // print a warning and exit the function.
38 - if (access(full_path, R_OK)) {
39 - if (arg_debug || arg_debug_private_lib)
40 - printf("cannot find %s for private-lib, skipping...\n", full_path);
41 - return;
42 - }
43 -
44 +static void fslib_copy_libs(const char *full_path, unsigned mask) {
45 // create an empty RUN_LIB_FILE and allow the user to write to it
46 unlink(RUN_LIB_FILE); // in case is there
47 create_empty_file_as_root(RUN_LIB_FILE, 0644);
48 - if (chown(RUN_LIB_FILE, getuid(), getgid()))
49 - errExit("chown");
50 + if (mask & SBOX_USER) {
51 + if (chown(RUN_LIB_FILE, getuid(), getgid()))
52 + errExit("chown");
53 + }
54
55 // run fldd to extract the list of files
56 if (arg_debug || arg_debug_private_lib)
57 printf(" running fldd %s\n", full_path);
58 - sbox_run(SBOX_USER | SBOX_SECCOMP | SBOX_CAPS_NONE, 3, PATH_FLDD, full_path, RUN_LIB_FILE);
59 + sbox_run(mask | SBOX_SECCOMP | SBOX_CAPS_NONE, 3, PATH_FLDD, full_path, RUN_LIB_FILE);
60
61 // open the list of libraries and install them on by one
62 FILE *fp = fopen(RUN_LIB_FILE, "r");
63 @@ -182,6 +172,34 @@
64 unlink(RUN_LIB_FILE);
65 }
66
67 +void fslib_copy_libs_parse_as_root(const char *full_path) {
68 + assert(full_path);
69 + if (arg_debug || arg_debug_private_lib)
70 + printf(" fslib_copy_libs_parse_as_root %s\n", full_path);
71 +
72 + struct stat s;
73 + if (stat(full_path, &s)) {
74 + if (arg_debug || arg_debug_private_lib)
75 + printf("cannot find %s for private-lib, skipping...\n", full_path);
76 + return;
77 + }
78 + fslib_copy_libs(full_path, SBOX_ROOT);
79 +}
80 +
81 +// if library/executable does not exist or the user does not have read access to it
82 +// print a warning and exit the function.
83 +void fslib_copy_libs_parse_as_user(const char *full_path) {
84 + assert(full_path);
85 + if (arg_debug || arg_debug_private_lib)
86 + printf(" fslib_copy_libs_parse_as_user %s\n", full_path);
87 +
88 + if (access(full_path, R_OK)) {
89 + if (arg_debug || arg_debug_private_lib)
90 + printf("cannot find %s for private-lib, skipping...\n", full_path);
91 + return;
92 + }
93 + fslib_copy_libs(full_path, SBOX_USER);
94 +}
95
96 void fslib_copy_dir(const char *full_path) {
97 assert(full_path);
98 @@ -236,7 +254,7 @@
99 access(fname, X_OK) != 0) // don't duplicate executables, just install the libraries
100 fslib_duplicate(fname);
101
102 - fslib_copy_libs(fname);
103 + fslib_copy_libs_parse_as_user(fname);
104 }
105 }
106 }
107 @@ -379,25 +397,12 @@
108 printf("Installing standard C library\n");
109 fslib_install_stdc();
110
111 - // start timetrace
112 - timetrace_start();
113 -
114 - // bring in firejail executable libraries in case we are redirected here by a firejail symlink from /usr/local/bin/firejail
115 + // install other libraries needed by firejail
116 if (arg_debug || arg_debug_private_lib)
117 printf("Installing Firejail libraries\n");
118 - fslib_install_list(PATH_FIREJAIL);
119 -
120 - // bring in firejail directory
121 - fslib_install_list(LIBDIR "/firejail");
122 -
123 - // bring in dhclient libraries
124 - if (any_dhcp()) {
125 - if (arg_debug || arg_debug_private_lib)
126 - printf("Installing dhclient libraries\n");
127 - fslib_install_list(RUN_MNT_DIR "/dhclient");
128 - }
129 - fmessage("Firejail libraries installed in %0.2f ms\n", timetrace_end());
130 + fslib_install_firejail();
131
132 + // start timetrace
133 timetrace_start();
134
135 // copy the libs in the new lib directory for the main exe
136 --- a/src/firejail/fs_lib2.c
137 +++ b/src/firejail/fs_lib2.c
138 @@ -22,7 +22,8 @@
139 #include <sys/stat.h>
140
141 extern void fslib_duplicate(const char *full_path);
142 -extern void fslib_copy_libs(const char *full_path);
143 +extern void fslib_copy_libs_parse_as_user(const char *full_path);
144 +extern void fslib_copy_libs_parse_as_root(const char *full_path);
145 extern void fslib_copy_dir(const char *full_path);
146
147 //***************************************************************
148 @@ -123,6 +124,52 @@
149 fmessage("Standard C library installed in %0.2f ms\n", timetrace_end());
150 }
151
152 +//***************************************************************
153 +// Firejail libraries
154 +//***************************************************************
155 +
156 +static void fdir(void) {
157 + fslib_copy_dir(LIBDIR "/firejail");
158 +
159 + // executables and libraries from firejail directory
160 + static const char * const fbin[] = {
161 + PATH_FCOPY, // currently sufficient to find all needed libraries
162 + // PATH_FSECCOMP,
163 + // PATH_FSEC_OPTIMIZE,
164 + // PATH_FSEC_PRINT,
165 + // RUN_FIREJAIL_LIB_DIR "/libtrace.so",
166 + // RUN_FIREJAIL_LIB_DIR "/libtracelog.so",
167 + // RUN_FIREJAIL_LIB_DIR "/libpostexecseccomp.so",
168 + NULL,
169 + };
170 +
171 + // need to run fldd as root user, unprivileged users have no read permission on executables
172 + int i;
173 + for (i = 0; fbin[i]; i++)
174 + fslib_copy_libs_parse_as_root(fbin[i]);
175 +}
176 +
177 +void fslib_install_firejail(void) {
178 + timetrace_start();
179 + // bring in firejail executable libraries, in case we are redirected here
180 + // by a firejail symlink from /usr/local/bin/firejail
181 + fslib_copy_libs_parse_as_user(PATH_FIREJAIL);
182 +
183 + // bring in firejail directory
184 + fdir();
185 +
186 + // bring in dhclient libraries
187 + if (any_dhcp())
188 + fslib_copy_libs_parse_as_user(RUN_MNT_DIR "/dhclient");
189 +
190 +#ifdef HAVE_X11
191 + // bring in xauth libraries
192 + if (arg_x11_xorg)
193 + fslib_copy_libs_parse_as_user("/usr/bin/xauth");
194 +#endif
195 +
196 + fmessage("Firejail libraries installed in %0.2f ms\n", timetrace_end());
197 +}
198
199 //***************************************************************
200 // various system libraries
201 @@ -268,7 +315,7 @@
202 if (asprintf(&name, "/usr/lib/x86_64-linux-gnu/%s", ptr->dir1) == -1)
203 errExit("asprintf");
204 if (access(name, R_OK) == 0) {
205 - fslib_copy_libs(name);
206 + fslib_copy_libs_parse_as_user(name);
207 fslib_copy_dir(name);
208 }
209 else {
210 @@ -277,7 +324,7 @@
211 if (asprintf(&name, "/usr/lib64/%s", ptr->dir1) == -1)
212 errExit("asprintf");
213 if (access(name, R_OK) == 0) {
214 - fslib_copy_libs(name);
215 + fslib_copy_libs_parse_as_user(name);
216 fslib_copy_dir(name);
217 }
218 }
219 @@ -288,7 +335,7 @@
220 if (asprintf(&name, "/usr/lib/x86_64-linux-gnu/%s", ptr->dir2) == -1)
221 errExit("asprintf");
222 if (access(name, R_OK) == 0) {
223 - fslib_copy_libs(name);
224 + fslib_copy_libs_parse_as_user(name);
225 fslib_copy_dir(name);
226 }
227 else {
228 @@ -297,7 +344,7 @@
229 if (asprintf(&name, "/usr/lib64/%s", ptr->dir2) == -1)
230 errExit("asprintf");
231 if (access(name, R_OK) == 0) {
232 - fslib_copy_libs(name);
233 + fslib_copy_libs_parse_as_user(name);
234 fslib_copy_dir(name);
235 }
236 }
237 --- a/src/firejail/sbox.c
238 +++ b/src/firejail/sbox.c
239 @@ -203,15 +203,16 @@
240 }
241 }
242
243 - if (filtermask & SBOX_ROOT) {
244 + if (filtermask & SBOX_USER)
245 + drop_privs(1);
246 + else if (filtermask & SBOX_ROOT) {
247 // elevate privileges in order to get grsecurity working
248 if (setreuid(0, 0))
249 errExit("setreuid");
250 if (setregid(0, 0))
251 errExit("setregid");
252 }
253 - else if (filtermask & SBOX_USER)
254 - drop_privs(1);
255 + else assert(0);
256
257 if (arg[0]) { // get rid of scan-build warning
258 int fd = open(arg[0], O_PATH | O_CLOEXEC);
11 disable-terminal-tests.patch
22 config-hardening.patch
33 apparmor-override.patch
4 private-lib.patch