aboutsummaryrefslogtreecommitdiffstats
path: root/src/firejail/fs_home.c
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2016-11-18 09:11:30 -0500
committerLibravatar netblue30 <netblue30@yahoo.com>2016-11-18 09:11:30 -0500
commit8c2b460d143d8dda4a86b826c0920918aa15f1f7 (patch)
treeeae4c3a6f4805f0940e487299ccad8804665c843 /src/firejail/fs_home.c
parenttesting appimage (diff)
downloadfirejail-8c2b460d143d8dda4a86b826c0920918aa15f1f7.tar.gz
firejail-8c2b460d143d8dda4a86b826c0920918aa15f1f7.tar.zst
firejail-8c2b460d143d8dda4a86b826c0920918aa15f1f7.zip
fcopy part 4
Diffstat (limited to 'src/firejail/fs_home.c')
-rw-r--r--src/firejail/fs_home.c67
1 files changed, 35 insertions, 32 deletions
diff --git a/src/firejail/fs_home.c b/src/firejail/fs_home.c
index d8cd9ce4d..1612da5d3 100644
--- a/src/firejail/fs_home.c
+++ b/src/firejail/fs_home.c
@@ -212,12 +212,6 @@ void fs_private_homedir(void) {
212 212
213 uid_t u = getuid(); 213 uid_t u = getuid();
214 gid_t g = getgid(); 214 gid_t g = getgid();
215 struct stat s;
216 if (stat(homedir, &s) == -1) {
217 fprintf(stderr, "Error: cannot find user home directory\n");
218 exit(1);
219 }
220
221 215
222 // mount bind private_homedir on top of homedir 216 // mount bind private_homedir on top of homedir
223 if (arg_debug) 217 if (arg_debug)
@@ -351,11 +345,9 @@ void fs_check_private_dir(void) {
351//*********************************************************************************** 345//***********************************************************************************
352static char *check_dir_or_file(const char *name) { 346static char *check_dir_or_file(const char *name) {
353 assert(name); 347 assert(name);
354 struct stat s;
355 348
356 // basic checks 349 // basic checks
357 invalid_filename(name); 350 invalid_filename(name);
358
359 if (arg_debug) 351 if (arg_debug)
360 printf("Private home: checking %s\n", name); 352 printf("Private home: checking %s\n", name);
361 353
@@ -372,28 +364,44 @@ static char *check_dir_or_file(const char *name) {
372 fname = tmp; 364 fname = tmp;
373 } 365 }
374 366
375 // check the file is in user home directory, a full home directory is not allowed 367 // we allow only files in user home directory or symbolic links to files or directories owned by the user
376 char *rname = realpath(fname, NULL); 368 struct stat s;
377 if (!rname || 369 if (lstat(fname, &s) == 0 && S_ISLNK(s.st_mode)) {
378 strncmp(rname, cfg.homedir, strlen(cfg.homedir)) != 0 || 370 if (stat(fname, &s) == 0) {
379 strcmp(rname, cfg.homedir) == 0) { 371 if (s.st_uid != getuid()) {
380 fprintf(stderr, "Error: invalid file %s\n", name); 372 fprintf(stderr, "Error: symbolic link %s to file or directory not owned by the user\n", fname);
381 exit(1); 373 exit(1);
374 }
375 return fname;
376 }
377 else {
378 fprintf(stderr, "Error: invalid file %s\n", name);
379 exit(1);
380 }
382 } 381 }
383 382 else {
384 // only top files and directories in user home are allowed 383 // check the file is in user home directory, a full home directory is not allowed
385 char *ptr = rname + strlen(cfg.homedir); 384 char *rname = realpath(fname, NULL);
386 assert(*ptr != '\0'); 385 if (!rname ||
387 ptr = strchr(++ptr, '/'); 386 strncmp(rname, cfg.homedir, strlen(cfg.homedir)) != 0 ||
388 if (ptr) { 387 strcmp(rname, cfg.homedir) == 0) {
389 if (*ptr != '\0') { 388 fprintf(stderr, "Error: invalid file %s\n", name);
390 fprintf(stderr, "Error: only top files and directories in user home are allowed\n");
391 exit(1); 389 exit(1);
392 } 390 }
391
392 // only top files and directories in user home are allowed
393 char *ptr = rname + strlen(cfg.homedir);
394 assert(*ptr != '\0');
395 ptr = strchr(++ptr, '/');
396 if (ptr) {
397 if (*ptr != '\0') {
398 fprintf(stderr, "Error: only top files and directories in user home are allowed\n");
399 exit(1);
400 }
401 }
402 free(fname);
403 return rname;
393 } 404 }
394
395 free(fname);
396 return rname;
397} 405}
398 406
399static void duplicate(char *name) { 407static void duplicate(char *name) {
@@ -405,7 +413,7 @@ static void duplicate(char *name) {
405 assert(strncmp(fname, cfg.homedir, strlen(cfg.homedir)) == 0); 413 assert(strncmp(fname, cfg.homedir, strlen(cfg.homedir)) == 0);
406 414
407 struct stat s; 415 struct stat s;
408 if (stat(fname, &s) == -1) { 416 if (lstat(fname, &s) == -1) {
409 free(fname); 417 free(fname);
410 return; 418 return;
411 } 419 }
@@ -445,11 +453,6 @@ void fs_private_home_list(void) {
445 453
446 uid_t uid = getuid(); 454 uid_t uid = getuid();
447 gid_t gid = getgid(); 455 gid_t gid = getgid();
448 struct stat s;
449 if (stat(homedir, &s) == -1) {
450 fprintf(stderr, "Error: cannot find user home directory\n");
451 exit(1);
452 }
453 456
454 // create /run/firejail/mnt/home directory 457 // create /run/firejail/mnt/home directory
455 mkdir_attr(RUN_HOME_DIR, 0755, uid, gid); 458 mkdir_attr(RUN_HOME_DIR, 0755, uid, gid);