aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2018-04-29 09:21:16 -0400
committerLibravatar netblue30 <netblue30@yahoo.com>2018-04-29 09:21:16 -0400
commitf6100167d25ce0e1f53714c94d82da8fdfaf9975 (patch)
treeb28d83c788845bf8abb223584066b758c511e7d5
parentprivate-lib fixes (diff)
downloadfirejail-f6100167d25ce0e1f53714c94d82da8fdfaf9975.tar.gz
firejail-f6100167d25ce0e1f53714c94d82da8fdfaf9975.tar.zst
firejail-f6100167d25ce0e1f53714c94d82da8fdfaf9975.zip
whitelist haderning - based on an idea from smitsohu
-rw-r--r--src/firejail/firejail.h10
-rw-r--r--src/firejail/fs_whitelist.c19
-rw-r--r--src/firejail/util.c36
3 files changed, 65 insertions, 0 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index 0df832c09..14f87c36c 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -524,6 +524,16 @@ unsigned extract_timeout(const char *str);
524void disable_file_or_dir(const char *fname); 524void disable_file_or_dir(const char *fname);
525void disable_file_path(const char *path, const char *file); 525void disable_file_path(const char *path, const char *file);
526 526
527// Get info regarding the last kernel mount operation.
528// The return value points to a static area, and will be overwritten by subsequent calls.
529// The function does an exit(1) if anything goes wrong.
530typedef struct {
531 char *fsname;
532 char *dir;
533} MountData;
534MountData *get_last_mount(void);
535
536
527// fs_var.c 537// fs_var.c
528void fs_var_log(void); // mounting /var/log 538void fs_var_log(void); // mounting /var/log
529void fs_var_lib(void); // various other fixes for software in /var directory 539void fs_var_lib(void); // various other fixes for software in /var directory
diff --git a/src/firejail/fs_whitelist.c b/src/firejail/fs_whitelist.c
index 21fa8e624..2b63d949d 100644
--- a/src/firejail/fs_whitelist.c
+++ b/src/firejail/fs_whitelist.c
@@ -316,6 +316,16 @@ static void whitelist_path(ProfileEntry *entry) {
316 if (mount(wfile, path, NULL, MS_BIND|MS_REC, NULL) < 0) 316 if (mount(wfile, path, NULL, MS_BIND|MS_REC, NULL) < 0)
317 errExit("mount bind"); 317 errExit("mount bind");
318 318
319 // check the last mount operation
320 MountData *mptr = get_last_mount(); // will do exit(1) if the mount cannot be found
321
322 // No mounts are allowed on top level directories. A destination such as "/etc" is very bad!
323 // - there should be more than one '/' char in dest string
324 if (mptr->dir == strrchr(mptr->dir, '/')) {
325 fprintf(stderr, "Error: invalid mount on top of %s\n", mptr->dir);
326 exit(1);
327 }
328
319 free(wfile); 329 free(wfile);
320 return; 330 return;
321 331
@@ -856,6 +866,15 @@ void fs_whitelist(void) {
856 fprintf(stderr, "Warning cannot create symbolic link %s\n", entry->link); 866 fprintf(stderr, "Warning cannot create symbolic link %s\n", entry->link);
857 else if (arg_debug || arg_debug_whitelists) 867 else if (arg_debug || arg_debug_whitelists)
858 printf("Created symbolic link %s -> %s\n", entry->link, entry->data + 10); 868 printf("Created symbolic link %s -> %s\n", entry->link, entry->data + 10);
869
870 // check again for files in /tmp directory
871 if (strncmp(entry->link, "/tmp/", 5) == 0) {
872 char *path = realpath(entry->link, NULL);
873 if (path == NULL || strncmp(path, "/tmp/", 5) != 0) {
874 fprintf(stderr, "Error: invalid symbolic link %s\n", entry->link);
875 exit(1);
876 }
877 }
859 } 878 }
860 } 879 }
861 } 880 }
diff --git a/src/firejail/util.c b/src/firejail/util.c
index a44e52e98..f441f283f 100644
--- a/src/firejail/util.c
+++ b/src/firejail/util.c
@@ -1029,3 +1029,39 @@ void disable_file_path(const char *path, const char *file) {
1029 free(fname); 1029 free(fname);
1030} 1030}
1031 1031
1032#define MAX_BUF 4096
1033static char mbuf[MAX_BUF];
1034static MountData mdata;
1035
1036// Get info regarding the last kernel mount operation.
1037// The return value points to a static area, and will be overwritten by subsequent calls.
1038// The function does an exit(1) if anything goes wrong.
1039MountData *get_last_mount(void) {
1040 // open /proc/self/mounts
1041 FILE *fp = fopen("/proc/self/mounts", "r");
1042 if (!fp)
1043 goto errexit;
1044
1045 mbuf[0] = '\0';
1046 while (fgets(mbuf, MAX_BUF, fp));
1047 fclose(fp);
1048 if (arg_debug || arg_debug_whitelists)
1049 printf("%s", mbuf);
1050
1051 // there should be no reason to have a new mount on top of a top level directory
1052 mdata.fsname = mbuf;
1053 mdata.dir = strstr(mbuf, " ");
1054 if (!mdata.dir)
1055 goto errexit;
1056 mdata.dir++;
1057 char *end = strstr(mdata.dir, " ");
1058 if (!end)
1059 goto errexit;
1060 *end = '\0';
1061
1062 return &mdata;
1063
1064errexit:
1065 fprintf(stderr, "Error: cannot read /proc/self/mounts");
1066 exit(1);
1067}