diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/fcopy/main.c | 3 | ||||
-rw-r--r-- | src/firejail/fs.c | 12 | ||||
-rw-r--r-- | src/firejail/fs_dev.c | 2 | ||||
-rw-r--r-- | src/firejail/fs_home.c | 11 | ||||
-rw-r--r-- | src/firejail/fs_whitelist.c | 59 | ||||
-rw-r--r-- | src/firejail/sandbox.c | 2 | ||||
-rw-r--r-- | src/firejail/selinux.c | 21 | ||||
-rw-r--r-- | src/firejail/util.c | 14 |
8 files changed, 65 insertions, 59 deletions
diff --git a/src/fcopy/main.c b/src/fcopy/main.c index 31810de9a..f279af89f 100644 --- a/src/fcopy/main.c +++ b/src/fcopy/main.c | |||
@@ -88,7 +88,8 @@ static void selinux_relabel_path(const char *path, const char *inside_path) { | |||
88 | if (arg_debug) | 88 | if (arg_debug) |
89 | printf("Relabeling %s as %s (%s)\n", path, inside_path, fcon); | 89 | printf("Relabeling %s as %s (%s)\n", path, inside_path, fcon); |
90 | 90 | ||
91 | setfilecon_raw(procfs_path, fcon); | 91 | if (setfilecon_raw(procfs_path, fcon) != 0 && arg_debug) |
92 | printf("Cannot relabel %s: %s\n", path, strerror(errno)); | ||
92 | } | 93 | } |
93 | freecon(fcon); | 94 | freecon(fcon); |
94 | close: | 95 | close: |
diff --git a/src/firejail/fs.c b/src/firejail/fs.c index dd4c2139d..6d01b5e5d 100644 --- a/src/firejail/fs.c +++ b/src/firejail/fs.c | |||
@@ -200,8 +200,6 @@ static void disable_file(OPERATION op, const char *filename) { | |||
200 | } | 200 | } |
201 | 201 | ||
202 | fs_tmpfs(fname, uid); | 202 | fs_tmpfs(fname, uid); |
203 | EUID_USER(); // fs_tmpfs returns with EUID 0 | ||
204 | |||
205 | selinux_relabel_path(fname, fname); | 203 | selinux_relabel_path(fname, fname); |
206 | } | 204 | } |
207 | else | 205 | else |
@@ -282,6 +280,8 @@ static void globbing(OPERATION op, const char *pattern, const char *noblacklist[ | |||
282 | 280 | ||
283 | // blacklist files or directories by mounting empty files on top of them | 281 | // blacklist files or directories by mounting empty files on top of them |
284 | void fs_blacklist(void) { | 282 | void fs_blacklist(void) { |
283 | EUID_ASSERT(); | ||
284 | |||
285 | ProfileEntry *entry = cfg.profile; | 285 | ProfileEntry *entry = cfg.profile; |
286 | if (!entry) | 286 | if (!entry) |
287 | return; | 287 | return; |
@@ -293,7 +293,6 @@ void fs_blacklist(void) { | |||
293 | if (noblacklist == NULL) | 293 | if (noblacklist == NULL) |
294 | errExit("failed allocating memory for noblacklist entries"); | 294 | errExit("failed allocating memory for noblacklist entries"); |
295 | 295 | ||
296 | EUID_USER(); | ||
297 | while (entry) { | 296 | while (entry) { |
298 | OPERATION op = OPERATION_MAX; | 297 | OPERATION op = OPERATION_MAX; |
299 | char *ptr; | 298 | char *ptr; |
@@ -469,8 +468,6 @@ void fs_blacklist(void) { | |||
469 | for (i = 0; i < noblacklist_c; i++) | 468 | for (i = 0; i < noblacklist_c; i++) |
470 | free(noblacklist[i]); | 469 | free(noblacklist[i]); |
471 | free(noblacklist); | 470 | free(noblacklist); |
472 | |||
473 | EUID_ROOT(); | ||
474 | } | 471 | } |
475 | 472 | ||
476 | //*********************************************** | 473 | //*********************************************** |
@@ -479,7 +476,7 @@ void fs_blacklist(void) { | |||
479 | 476 | ||
480 | // mount a writable tmpfs on directory; requires a resolved path | 477 | // mount a writable tmpfs on directory; requires a resolved path |
481 | void fs_tmpfs(const char *dir, unsigned check_owner) { | 478 | void fs_tmpfs(const char *dir, unsigned check_owner) { |
482 | EUID_USER(); | 479 | EUID_ASSERT(); |
483 | assert(dir); | 480 | assert(dir); |
484 | if (arg_debug) | 481 | if (arg_debug) |
485 | printf("Mounting tmpfs on %s, check owner: %s\n", dir, (check_owner)? "yes": "no"); | 482 | printf("Mounting tmpfs on %s, check owner: %s\n", dir, (check_owner)? "yes": "no"); |
@@ -504,12 +501,13 @@ void fs_tmpfs(const char *dir, unsigned check_owner) { | |||
504 | errExit("fstatvfs"); | 501 | errExit("fstatvfs"); |
505 | unsigned long flags = buf.f_flag & ~(MS_RDONLY|MS_BIND|MS_REMOUNT); | 502 | unsigned long flags = buf.f_flag & ~(MS_RDONLY|MS_BIND|MS_REMOUNT); |
506 | // mount via the symbolic link in /proc/self/fd | 503 | // mount via the symbolic link in /proc/self/fd |
507 | EUID_ROOT(); | ||
508 | char *proc; | 504 | char *proc; |
509 | if (asprintf(&proc, "/proc/self/fd/%d", fd) == -1) | 505 | if (asprintf(&proc, "/proc/self/fd/%d", fd) == -1) |
510 | errExit("asprintf"); | 506 | errExit("asprintf"); |
507 | EUID_ROOT(); | ||
511 | if (mount("tmpfs", proc, "tmpfs", flags|MS_NOSUID|MS_NODEV, options) < 0) | 508 | if (mount("tmpfs", proc, "tmpfs", flags|MS_NOSUID|MS_NODEV, options) < 0) |
512 | errExit("mounting tmpfs"); | 509 | errExit("mounting tmpfs"); |
510 | EUID_USER(); | ||
513 | // check the last mount operation | 511 | // check the last mount operation |
514 | MountData *mdata = get_last_mount(); | 512 | MountData *mdata = get_last_mount(); |
515 | if (strcmp(mdata->fstype, "tmpfs") != 0 || strcmp(mdata->dir, dir) != 0) | 513 | if (strcmp(mdata->fstype, "tmpfs") != 0 || strcmp(mdata->dir, dir) != 0) |
diff --git a/src/firejail/fs_dev.c b/src/firejail/fs_dev.c index 8cc3ecc62..a43b18344 100644 --- a/src/firejail/fs_dev.c +++ b/src/firejail/fs_dev.c | |||
@@ -330,8 +330,10 @@ void fs_dev_disable_sound(void) { | |||
330 | } | 330 | } |
331 | 331 | ||
332 | // disable all jack sockets in /dev/shm | 332 | // disable all jack sockets in /dev/shm |
333 | EUID_USER(); | ||
333 | glob_t globbuf; | 334 | glob_t globbuf; |
334 | int globerr = glob("/dev/shm/jack*", GLOB_NOSORT, NULL, &globbuf); | 335 | int globerr = glob("/dev/shm/jack*", GLOB_NOSORT, NULL, &globbuf); |
336 | EUID_ROOT(); | ||
335 | if (globerr) | 337 | if (globerr) |
336 | return; | 338 | return; |
337 | 339 | ||
diff --git a/src/firejail/fs_home.c b/src/firejail/fs_home.c index 0ed476063..590337da1 100644 --- a/src/firejail/fs_home.c +++ b/src/firejail/fs_home.c | |||
@@ -395,14 +395,16 @@ void fs_private(void) { | |||
395 | } | 395 | } |
396 | if (chown(homedir, u, g) < 0) | 396 | if (chown(homedir, u, g) < 0) |
397 | errExit("chown"); | 397 | errExit("chown"); |
398 | |||
399 | fs_logger2("mkdir", homedir); | 398 | fs_logger2("mkdir", homedir); |
400 | fs_logger2("tmpfs", homedir); | 399 | fs_logger2("tmpfs", homedir); |
401 | } | 400 | } |
402 | else | 401 | else { |
403 | // mask user home directory | 402 | // mask user home directory |
404 | // the directory should be owned by the current user | 403 | // the directory should be owned by the current user |
404 | EUID_USER(); | ||
405 | fs_tmpfs(homedir, 1); | 405 | fs_tmpfs(homedir, 1); |
406 | EUID_ROOT(); | ||
407 | } | ||
406 | 408 | ||
407 | selinux_relabel_path(homedir, homedir); | 409 | selinux_relabel_path(homedir, homedir); |
408 | } | 410 | } |
@@ -564,12 +566,13 @@ void fs_private_home_list(void) { | |||
564 | int xflag = store_xauthority(); | 566 | int xflag = store_xauthority(); |
565 | int aflag = store_asoundrc(); | 567 | int aflag = store_asoundrc(); |
566 | 568 | ||
567 | // create /run/firejail/mnt/home directory | ||
568 | EUID_ROOT(); | 569 | EUID_ROOT(); |
570 | // create /run/firejail/mnt/home directory | ||
569 | mkdir_attr(RUN_HOME_DIR, 0755, uid, gid); | 571 | mkdir_attr(RUN_HOME_DIR, 0755, uid, gid); |
570 | selinux_relabel_path(RUN_HOME_DIR, homedir); | 572 | selinux_relabel_path(RUN_HOME_DIR, homedir); |
571 | 573 | ||
572 | fs_logger_print(); // save the current log | 574 | // save the current log |
575 | fs_logger_print(); | ||
573 | EUID_USER(); | 576 | EUID_USER(); |
574 | 577 | ||
575 | // copy the list of files in the new home directory | 578 | // copy the list of files in the new home directory |
diff --git a/src/firejail/fs_whitelist.c b/src/firejail/fs_whitelist.c index 943f275de..7afebed1f 100644 --- a/src/firejail/fs_whitelist.c +++ b/src/firejail/fs_whitelist.c | |||
@@ -105,6 +105,7 @@ static int whitelist_mkpath(const char* path, mode_t mode) { | |||
105 | } | 105 | } |
106 | 106 | ||
107 | static void whitelist_file(int dirfd, const char *relpath, const char *path) { | 107 | static void whitelist_file(int dirfd, const char *relpath, const char *path) { |
108 | EUID_ASSERT(); | ||
108 | assert(relpath && path); | 109 | assert(relpath && path); |
109 | 110 | ||
110 | // open mount source, using a file descriptor that refers to the | 111 | // open mount source, using a file descriptor that refers to the |
@@ -130,12 +131,9 @@ static void whitelist_file(int dirfd, const char *relpath, const char *path) { | |||
130 | } | 131 | } |
131 | 132 | ||
132 | // create mount target as root, except if inside home or run/user/$UID directory | 133 | // create mount target as root, except if inside home or run/user/$UID directory |
133 | int userprivs = 0; | 134 | if ((strncmp(path, cfg.homedir, homedir_len) != 0 || path[homedir_len] != '/') && |
134 | if ((strncmp(path, cfg.homedir, homedir_len) == 0 && path[homedir_len] == '/') || | 135 | (strncmp(path, runuser, runuser_len) != 0 || path[runuser_len] != '/')) |
135 | (strncmp(path, runuser, runuser_len) == 0 && path[runuser_len] == '/')) { | 136 | EUID_ROOT(); |
136 | EUID_USER(); | ||
137 | userprivs = 1; | ||
138 | } | ||
139 | 137 | ||
140 | // create path of the mount target | 138 | // create path of the mount target |
141 | int fd2 = whitelist_mkpath(path, 0755); | 139 | int fd2 = whitelist_mkpath(path, 0755); |
@@ -146,8 +144,7 @@ static void whitelist_file(int dirfd, const char *relpath, const char *path) { | |||
146 | if (arg_debug || arg_debug_whitelists) | 144 | if (arg_debug || arg_debug_whitelists) |
147 | printf("Debug %d: skip whitelist %s\n", __LINE__, path); | 145 | printf("Debug %d: skip whitelist %s\n", __LINE__, path); |
148 | close(fd); | 146 | close(fd); |
149 | if (userprivs) | 147 | EUID_USER(); |
150 | EUID_ROOT(); | ||
151 | return; | 148 | return; |
152 | } | 149 | } |
153 | 150 | ||
@@ -166,8 +163,7 @@ static void whitelist_file(int dirfd, const char *relpath, const char *path) { | |||
166 | } | 163 | } |
167 | close(fd); | 164 | close(fd); |
168 | close(fd2); | 165 | close(fd2); |
169 | if (userprivs) | 166 | EUID_USER(); |
170 | EUID_ROOT(); | ||
171 | return; | 167 | return; |
172 | } | 168 | } |
173 | fd3 = openat(fd2, file, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); | 169 | fd3 = openat(fd2, file, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); |
@@ -184,19 +180,17 @@ static void whitelist_file(int dirfd, const char *relpath, const char *path) { | |||
184 | } | 180 | } |
185 | close(fd); | 181 | close(fd); |
186 | close(fd2); | 182 | close(fd2); |
187 | if (userprivs) | 183 | EUID_USER(); |
188 | EUID_ROOT(); | ||
189 | return; | 184 | return; |
190 | } | 185 | } |
191 | |||
192 | close(fd2); | 186 | close(fd2); |
193 | if (userprivs) | ||
194 | EUID_ROOT(); | ||
195 | 187 | ||
196 | if (arg_debug || arg_debug_whitelists) | 188 | if (arg_debug || arg_debug_whitelists) |
197 | printf("Whitelisting %s\n", path); | 189 | printf("Whitelisting %s\n", path); |
190 | EUID_ROOT(); | ||
198 | if (bind_mount_by_fd(fd, fd3)) | 191 | if (bind_mount_by_fd(fd, fd3)) |
199 | errExit("mount bind"); | 192 | errExit("mount bind"); |
193 | EUID_USER(); | ||
200 | // check the last mount operation | 194 | // check the last mount operation |
201 | MountData *mptr = get_last_mount(); // will do exit(1) if the mount cannot be found | 195 | MountData *mptr = get_last_mount(); // will do exit(1) if the mount cannot be found |
202 | #ifdef TEST_MOUNTINFO | 196 | #ifdef TEST_MOUNTINFO |
@@ -219,22 +213,19 @@ static void whitelist_file(int dirfd, const char *relpath, const char *path) { | |||
219 | } | 213 | } |
220 | 214 | ||
221 | static void whitelist_symlink(const char *link, const char *target) { | 215 | static void whitelist_symlink(const char *link, const char *target) { |
216 | EUID_ASSERT(); | ||
222 | assert(link && target); | 217 | assert(link && target); |
223 | 218 | ||
224 | // create files as root, except if inside home or run/user/$UID directory | 219 | // create files as root, except if inside home or run/user/$UID directory |
225 | int userprivs = 0; | 220 | if ((strncmp(link, cfg.homedir, homedir_len) != 0 || link[homedir_len] != '/') && |
226 | if ((strncmp(link, cfg.homedir, homedir_len) == 0 && link[homedir_len] == '/') || | 221 | (strncmp(link, runuser, runuser_len) != 0 || link[runuser_len] != '/')) |
227 | (strncmp(link, runuser, runuser_len) == 0 && link[runuser_len] == '/')) { | 222 | EUID_ROOT(); |
228 | EUID_USER(); | ||
229 | userprivs = 1; | ||
230 | } | ||
231 | 223 | ||
232 | int fd = whitelist_mkpath(link, 0755); | 224 | int fd = whitelist_mkpath(link, 0755); |
233 | if (fd == -1) { | 225 | if (fd == -1) { |
234 | if (arg_debug || arg_debug_whitelists) | 226 | if (arg_debug || arg_debug_whitelists) |
235 | printf("Debug %d: cannot create symbolic link %s\n", __LINE__, link); | 227 | printf("Debug %d: cannot create symbolic link %s\n", __LINE__, link); |
236 | if (userprivs) | 228 | EUID_USER(); |
237 | EUID_ROOT(); | ||
238 | return; | 229 | return; |
239 | } | 230 | } |
240 | 231 | ||
@@ -252,8 +243,7 @@ static void whitelist_symlink(const char *link, const char *target) { | |||
252 | printf("Created symbolic link %s -> %s\n", link, target); | 243 | printf("Created symbolic link %s -> %s\n", link, target); |
253 | 244 | ||
254 | close(fd); | 245 | close(fd); |
255 | if (userprivs) | 246 | EUID_USER(); |
256 | EUID_ROOT(); | ||
257 | } | 247 | } |
258 | 248 | ||
259 | static void globbing(const char *pattern) { | 249 | static void globbing(const char *pattern) { |
@@ -330,10 +320,11 @@ static void tmpfs_topdirs(const TopDir *topdirs) { | |||
330 | // init tmpfs | 320 | // init tmpfs |
331 | if (strcmp(topdirs[i].path, "/run") == 0) { | 321 | if (strcmp(topdirs[i].path, "/run") == 0) { |
332 | // restore /run/firejail directory | 322 | // restore /run/firejail directory |
333 | if (mkdir(RUN_FIREJAIL_DIR, 0755) == -1) | 323 | EUID_ROOT(); |
334 | errExit("mkdir"); | 324 | mkdir_attr(RUN_FIREJAIL_DIR, 0755, 0, 0); |
335 | if (bind_mount_fd_to_path(fd, RUN_FIREJAIL_DIR)) | 325 | if (bind_mount_fd_to_path(fd, RUN_FIREJAIL_DIR)) |
336 | errExit("mount bind"); | 326 | errExit("mount bind"); |
327 | EUID_USER(); | ||
337 | close(fd); | 328 | close(fd); |
338 | fs_logger2("whitelist", RUN_FIREJAIL_DIR); | 329 | fs_logger2("whitelist", RUN_FIREJAIL_DIR); |
339 | 330 | ||
@@ -351,12 +342,14 @@ static void tmpfs_topdirs(const TopDir *topdirs) { | |||
351 | errExit("asprintf"); | 342 | errExit("asprintf"); |
352 | if (strcmp(env, pamtmpdir) == 0) { | 343 | if (strcmp(env, pamtmpdir) == 0) { |
353 | // create empty user-owned /tmp/user/$UID directory | 344 | // create empty user-owned /tmp/user/$UID directory |
345 | EUID_ROOT(); | ||
354 | mkdir_attr("/tmp/user", 0711, 0, 0); | 346 | mkdir_attr("/tmp/user", 0711, 0, 0); |
355 | selinux_relabel_path("/tmp/user", "/tmp/user"); | 347 | selinux_relabel_path("/tmp/user", "/tmp/user"); |
356 | fs_logger("mkdir /tmp/user"); | 348 | fs_logger("mkdir /tmp/user"); |
357 | mkdir_attr(pamtmpdir, 0700, getuid(), 0); | 349 | mkdir_attr(pamtmpdir, 0700, getuid(), 0); |
358 | selinux_relabel_path(pamtmpdir, pamtmpdir); | 350 | selinux_relabel_path(pamtmpdir, pamtmpdir); |
359 | fs_logger2("mkdir", pamtmpdir); | 351 | fs_logger2("mkdir", pamtmpdir); |
352 | EUID_USER(); | ||
360 | } | 353 | } |
361 | free(pamtmpdir); | 354 | free(pamtmpdir); |
362 | } | 355 | } |
@@ -374,11 +367,8 @@ static void tmpfs_topdirs(const TopDir *topdirs) { | |||
374 | } | 367 | } |
375 | 368 | ||
376 | // user home directory | 369 | // user home directory |
377 | if (tmpfs_home) { | 370 | if (tmpfs_home) |
378 | EUID_USER(); | ||
379 | fs_private(); // checks owner if outside /home | 371 | fs_private(); // checks owner if outside /home |
380 | EUID_ROOT(); | ||
381 | } | ||
382 | 372 | ||
383 | // /run/user/$UID directory | 373 | // /run/user/$UID directory |
384 | if (tmpfs_runuser) { | 374 | if (tmpfs_runuser) { |
@@ -402,6 +392,7 @@ static int reject_topdir(const char *dir) { | |||
402 | // keep track of whitelist top level directories by adding them to an array | 392 | // keep track of whitelist top level directories by adding them to an array |
403 | // open each directory | 393 | // open each directory |
404 | static TopDir *add_topdir(const char *dir, TopDir *topdirs, const char *path) { | 394 | static TopDir *add_topdir(const char *dir, TopDir *topdirs, const char *path) { |
395 | EUID_ASSERT(); | ||
405 | assert(dir && path); | 396 | assert(dir && path); |
406 | 397 | ||
407 | // /proc and /sys are not allowed | 398 | // /proc and /sys are not allowed |
@@ -516,6 +507,8 @@ static char *extract_topdir(const char *path) { | |||
516 | } | 507 | } |
517 | 508 | ||
518 | void fs_whitelist(void) { | 509 | void fs_whitelist(void) { |
510 | EUID_ASSERT(); | ||
511 | |||
519 | ProfileEntry *entry = cfg.profile; | 512 | ProfileEntry *entry = cfg.profile; |
520 | if (!entry) | 513 | if (!entry) |
521 | return; | 514 | return; |
@@ -536,7 +529,6 @@ void fs_whitelist(void) { | |||
536 | errExit("calloc"); | 529 | errExit("calloc"); |
537 | 530 | ||
538 | // verify whitelist files, extract symbolic links, etc. | 531 | // verify whitelist files, extract symbolic links, etc. |
539 | EUID_USER(); | ||
540 | while (entry) { | 532 | while (entry) { |
541 | int nowhitelist_flag = 0; | 533 | int nowhitelist_flag = 0; |
542 | 534 | ||
@@ -630,7 +622,7 @@ void fs_whitelist(void) { | |||
630 | if (!fname) { | 622 | if (!fname) { |
631 | if (arg_debug || arg_debug_whitelists) { | 623 | if (arg_debug || arg_debug_whitelists) { |
632 | printf("Removed path: %s\n", entry->data); | 624 | printf("Removed path: %s\n", entry->data); |
633 | printf("\texpanded: %s\n", new_name); | 625 | printf("\tnew_name: %s\n", new_name); |
634 | printf("\trealpath: (null)\n"); | 626 | printf("\trealpath: (null)\n"); |
635 | printf("\t%s\n", strerror(errno)); | 627 | printf("\t%s\n", strerror(errno)); |
636 | } | 628 | } |
@@ -712,7 +704,6 @@ void fs_whitelist(void) { | |||
712 | free(nowhitelist); | 704 | free(nowhitelist); |
713 | 705 | ||
714 | // mount tmpfs on all top level directories | 706 | // mount tmpfs on all top level directories |
715 | EUID_ROOT(); | ||
716 | tmpfs_topdirs(topdirs); | 707 | tmpfs_topdirs(topdirs); |
717 | 708 | ||
718 | // go through profile rules again, and interpret whitelist commands | 709 | // go through profile rules again, and interpret whitelist commands |
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index 995827fb7..83e50aee2 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c | |||
@@ -1004,10 +1004,12 @@ int sandbox(void* sandbox_arg) { | |||
1004 | // apply the profile file | 1004 | // apply the profile file |
1005 | //**************************** | 1005 | //**************************** |
1006 | // apply all whitelist commands ... | 1006 | // apply all whitelist commands ... |
1007 | EUID_USER(); | ||
1007 | fs_whitelist(); | 1008 | fs_whitelist(); |
1008 | 1009 | ||
1009 | // ... followed by blacklist commands | 1010 | // ... followed by blacklist commands |
1010 | fs_blacklist(); // mkdir and mkfile are processed all over again | 1011 | fs_blacklist(); // mkdir and mkfile are processed all over again |
1012 | EUID_ROOT(); | ||
1011 | 1013 | ||
1012 | //**************************** | 1014 | //**************************** |
1013 | // nosound/no3d/notv/novideo and fix for pulseaudio 7.0 | 1015 | // nosound/no3d/notv/novideo and fix for pulseaudio 7.0 |
diff --git a/src/firejail/selinux.c b/src/firejail/selinux.c index 6969e7a3d..fa59882ed 100644 --- a/src/firejail/selinux.c +++ b/src/firejail/selinux.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include "firejail.h" | 21 | #include "firejail.h" |
22 | #include <sys/types.h> | 22 | #include <sys/types.h> |
23 | #include <sys/stat.h> | 23 | #include <sys/stat.h> |
24 | #include <errno.h> | ||
24 | 25 | ||
25 | #include <fcntl.h> | 26 | #include <fcntl.h> |
26 | #ifndef O_PATH | 27 | #ifndef O_PATH |
@@ -57,7 +58,17 @@ void selinux_relabel_path(const char *path, const char *inside_path) | |||
57 | 58 | ||
58 | /* Open the file as O_PATH, to pin it while we determine and adjust the label | 59 | /* Open the file as O_PATH, to pin it while we determine and adjust the label |
59 | * Defeat symlink races by not allowing symbolic links */ | 60 | * Defeat symlink races by not allowing symbolic links */ |
61 | int called_as_root = 0; | ||
62 | if (geteuid() == 0) | ||
63 | called_as_root = 1; | ||
64 | if (called_as_root) | ||
65 | EUID_USER(); | ||
66 | |||
60 | fd = safer_openat(-1, path, O_NOFOLLOW|O_CLOEXEC|O_PATH); | 67 | fd = safer_openat(-1, path, O_NOFOLLOW|O_CLOEXEC|O_PATH); |
68 | |||
69 | if (called_as_root) | ||
70 | EUID_ROOT(); | ||
71 | |||
61 | if (fd < 0) | 72 | if (fd < 0) |
62 | return; | 73 | return; |
63 | if (fstat(fd, &st) < 0) | 74 | if (fstat(fd, &st) < 0) |
@@ -68,8 +79,16 @@ void selinux_relabel_path(const char *path, const char *inside_path) | |||
68 | if (arg_debug) | 79 | if (arg_debug) |
69 | printf("Relabeling %s as %s (%s)\n", path, inside_path, fcon); | 80 | printf("Relabeling %s as %s (%s)\n", path, inside_path, fcon); |
70 | 81 | ||
71 | setfilecon_raw(procfs_path, fcon); | 82 | if (!called_as_root) |
83 | EUID_ROOT(); | ||
84 | |||
85 | if (setfilecon_raw(procfs_path, fcon) != 0 && arg_debug) | ||
86 | printf("Cannot relabel %s: %s\n", path, strerror(errno)); | ||
87 | |||
88 | if (!called_as_root) | ||
89 | EUID_USER(); | ||
72 | } | 90 | } |
91 | |||
73 | freecon(fcon); | 92 | freecon(fcon); |
74 | close: | 93 | close: |
75 | close(fd); | 94 | close(fd); |
diff --git a/src/firejail/util.c b/src/firejail/util.c index 094a68c60..f0df45eb2 100644 --- a/src/firejail/util.c +++ b/src/firejail/util.c | |||
@@ -459,31 +459,21 @@ int is_dir(const char *fname) { | |||
459 | if (*fname == '\0') | 459 | if (*fname == '\0') |
460 | return 0; | 460 | return 0; |
461 | 461 | ||
462 | int called_as_root = 0; | ||
463 | if (geteuid() == 0) | ||
464 | called_as_root = 1; | ||
465 | |||
466 | if (called_as_root) | ||
467 | EUID_USER(); | ||
468 | |||
469 | // if fname doesn't end in '/', add one | 462 | // if fname doesn't end in '/', add one |
470 | int rv; | 463 | int rv; |
471 | struct stat s; | 464 | struct stat s; |
472 | if (fname[strlen(fname) - 1] == '/') | 465 | if (fname[strlen(fname) - 1] == '/') |
473 | rv = stat(fname, &s); | 466 | rv = stat_as_user(fname, &s); |
474 | else { | 467 | else { |
475 | char *tmp; | 468 | char *tmp; |
476 | if (asprintf(&tmp, "%s/", fname) == -1) { | 469 | if (asprintf(&tmp, "%s/", fname) == -1) { |
477 | fprintf(stderr, "Error: cannot allocate memory, %s:%d\n", __FILE__, __LINE__); | 470 | fprintf(stderr, "Error: cannot allocate memory, %s:%d\n", __FILE__, __LINE__); |
478 | errExit("asprintf"); | 471 | errExit("asprintf"); |
479 | } | 472 | } |
480 | rv = stat(tmp, &s); | 473 | rv = stat_as_user(tmp, &s); |
481 | free(tmp); | 474 | free(tmp); |
482 | } | 475 | } |
483 | 476 | ||
484 | if (called_as_root) | ||
485 | EUID_ROOT(); | ||
486 | |||
487 | if (rv == -1) | 477 | if (rv == -1) |
488 | return 0; | 478 | return 0; |
489 | 479 | ||