summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar smitsohu <smitsohu@gmail.com>2018-05-11 00:58:11 +0200
committerLibravatar smitsohu <smitsohu@gmail.com>2018-05-11 00:58:11 +0200
commit392bedba292d058052157d672129545fdcafdb83 (patch)
tree9cdd8cc653a0e204441f8a0378dd7e977dad80b3 /src
parentMerge branch 'master' of https://github.com/netblue30/firejail (diff)
downloadfirejail-392bedba292d058052157d672129545fdcafdb83.tar.gz
firejail-392bedba292d058052157d672129545fdcafdb83.tar.zst
firejail-392bedba292d058052157d672129545fdcafdb83.zip
harden read-write mounts, cleanup
Diffstat (limited to 'src')
-rw-r--r--src/firejail/fs.c57
-rw-r--r--src/firejail/pulseaudio.c8
-rw-r--r--src/firejail/x11.c9
3 files changed, 45 insertions, 29 deletions
diff --git a/src/firejail/fs.c b/src/firejail/fs.c
index 88f92ad74..f3ed67928 100644
--- a/src/firejail/fs.c
+++ b/src/firejail/fs.c
@@ -484,29 +484,44 @@ void fs_rdonly(const char *dir) {
484 484
485static void fs_rdwr(const char *dir) { 485static void fs_rdwr(const char *dir) {
486 assert(dir); 486 assert(dir);
487 // check directory exists 487 // check directory exists and ensure we have a resolved path
488 // the resolved path allows to run a sanity check after the mount
489 char *path = realpath(dir, NULL);
490 if (path == NULL)
491 return;
492 // allow only user owned directories, except the user is root
493 uid_t u = getuid();
488 struct stat s; 494 struct stat s;
489 int rv = stat(dir, &s); 495 int rv = stat(path, &s);
490 if (rv == 0) { 496 if (rv) {
491 // if the file is outside /home directory, allow only root user 497 free(path);
492 uid_t u = getuid(); 498 return;
493 if (u != 0 && s.st_uid != u) { 499 }
494 fwarning("you are not allowed to change %s to read-write\n", dir); 500 if (u != 0 && s.st_uid != u) {
495 return; 501 fwarning("you are not allowed to change %s to read-write\n", path);
496 } 502 free(path);
497 503 return;
498 // mount --bind /bin /bin 504 }
499 // mount --bind -o remount,rw /bin 505 // mount --bind /bin /bin
500 unsigned long flags = 0; 506 // mount --bind -o remount,rw /bin
501 get_mount_flags(dir, &flags); 507 unsigned long flags = 0;
502 if ((flags & MS_RDONLY) == 0) 508 get_mount_flags(path, &flags);
503 return; 509 if ((flags & MS_RDONLY) == 0) {
504 flags &= ~MS_RDONLY; 510 free(path);
505 if (mount(dir, dir, NULL, MS_BIND|MS_REC, NULL) < 0 || 511 return;
506 mount(NULL, dir, NULL, flags|MS_BIND|MS_REMOUNT|MS_REC, NULL) < 0)
507 errExit("mount read-write");
508 fs_logger2("read-write", dir);
509 } 512 }
513 flags &= ~MS_RDONLY;
514 if (mount(path, path, NULL, MS_BIND|MS_REC, NULL) < 0 ||
515 mount(NULL, path, NULL, flags|MS_BIND|MS_REMOUNT|MS_REC, NULL) < 0)
516 errExit("mount read-write");
517 fs_logger2("read-write", path);
518
519 // run a check on /proc/self/mountinfo to validate the mount
520 MountData *mptr = get_last_mount();
521 if (strncmp(mptr->dir, path, strlen(path)) != 0)
522 errLogExit("invalid read-write mount");
523
524 free(path);
510} 525}
511 526
512void fs_noexec(const char *dir) { 527void fs_noexec(const char *dir) {
diff --git a/src/firejail/pulseaudio.c b/src/firejail/pulseaudio.c
index eaaba86c0..15d44e4cc 100644
--- a/src/firejail/pulseaudio.c
+++ b/src/firejail/pulseaudio.c
@@ -178,10 +178,10 @@ void pulseaudio_init(void) {
178 178
179 // check /proc/self/mountinfo to confirm the mount is ok 179 // check /proc/self/mountinfo to confirm the mount is ok
180 MountData *mptr = get_last_mount(); 180 MountData *mptr = get_last_mount();
181 if (strncmp(mptr->dir, homeusercfg, strlen(homeusercfg)) != 0) 181 if (strcmp(mptr->dir, homeusercfg) != 0)
182 errLogExit("invalid mount on top of %s (should be %s)\n", mptr->dir, homeusercfg); 182 errLogExit("invalid pulseaudio mount");
183 if (strncmp(mptr->fstype, "tmpfs", 5) != 0) 183 if (strcmp(mptr->fstype, "tmpfs") != 0)
184 errLogExit("invalid mount on top of %s (filesystem type is %s)\n", mptr->dir, mptr->fstype); 184 errLogExit("invalid pulseaudio mount");
185 185
186 char *p; 186 char *p;
187 if (asprintf(&p, "%s/client.conf", homeusercfg) == -1) 187 if (asprintf(&p, "%s/client.conf", homeusercfg) == -1)
diff --git a/src/firejail/x11.c b/src/firejail/x11.c
index 0eace3215..ec8775370 100644
--- a/src/firejail/x11.c
+++ b/src/firejail/x11.c
@@ -1196,10 +1196,11 @@ void x11_xorg(void) {
1196 1196
1197 // check /proc/self/mountinfo to confirm the mount is ok 1197 // check /proc/self/mountinfo to confirm the mount is ok
1198 MountData *mptr = get_last_mount(); 1198 MountData *mptr = get_last_mount();
1199 if (strncmp(mptr->dir, dest, strlen(dest)) != 0) 1199 if (strcmp(mptr->dir, dest) != 0)
1200 errLogExit("invalid mount on top of %s (should be %s)\n", mptr->dir, dest); 1200 errLogExit("invalid .Xauthority mount");
1201 if (strncmp(mptr->fstype, "tmpfs", 5) != 0) 1201 if (strcmp(mptr->fstype, "tmpfs") != 0)
1202 errLogExit("invalid mount on top of %s (filesystem type is %s)\n", mptr->dir, mptr->fstype); 1202 errLogExit("invalid .Xauthority mount");
1203
1203 free(dest); 1204 free(dest);
1204#endif 1205#endif
1205} 1206}