diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/firecfg/firecfg.config | 23 | ||||
-rw-r--r-- | src/firejail/main.c | 189 | ||||
-rw-r--r-- | src/firejail/no_sandbox.c | 3 | ||||
-rw-r--r-- | src/firejail/output.c | 12 | ||||
-rw-r--r-- | src/firejail/util.c | 5 |
5 files changed, 120 insertions, 112 deletions
diff --git a/src/firecfg/firecfg.config b/src/firecfg/firecfg.config index 7052f7509..3b0ad0aed 100644 --- a/src/firecfg/firecfg.config +++ b/src/firecfg/firecfg.config | |||
@@ -45,8 +45,8 @@ amule | |||
45 | amuled | 45 | amuled |
46 | android-studio | 46 | android-studio |
47 | anydesk | 47 | anydesk |
48 | apostrophe | ||
49 | apktool | 48 | apktool |
49 | apostrophe | ||
50 | # ar - disable until we fix CLI archivers for makepkg on Arch (see discussion in #3095) | 50 | # ar - disable until we fix CLI archivers for makepkg on Arch (see discussion in #3095) |
51 | arch-audit | 51 | arch-audit |
52 | archaudit-report | 52 | archaudit-report |
@@ -143,8 +143,8 @@ clawsker | |||
143 | clementine | 143 | clementine |
144 | clion | 144 | clion |
145 | clion-eap | 145 | clion-eap |
146 | clipit | ||
147 | clipgrab | 146 | clipgrab |
147 | clipit | ||
148 | cliqz | 148 | cliqz |
149 | clocks | 149 | clocks |
150 | cmus | 150 | cmus |
@@ -168,6 +168,7 @@ crow | |||
168 | cryptocat | 168 | cryptocat |
169 | cvlc | 169 | cvlc |
170 | cyberfox | 170 | cyberfox |
171 | d-feet | ||
171 | darktable | 172 | darktable |
172 | dconf-editor | 173 | dconf-editor |
173 | ddgr | 174 | ddgr |
@@ -198,13 +199,12 @@ dragon | |||
198 | drawio | 199 | drawio |
199 | drill | 200 | drill |
200 | dropbox | 201 | dropbox |
201 | d-feet | ||
202 | easystroke | 202 | easystroke |
203 | ebook-viewer | ||
204 | ebook-convert | 203 | ebook-convert |
205 | ebook-edit | 204 | ebook-edit |
206 | ebook-meta | 205 | ebook-meta |
207 | ebook-polish | 206 | ebook-polish |
207 | ebook-viewer | ||
208 | electron-mail | 208 | electron-mail |
209 | electrum | 209 | electrum |
210 | element-desktop | 210 | element-desktop |
@@ -295,8 +295,8 @@ gimp-2.10 | |||
295 | gimp-2.8 | 295 | gimp-2.8 |
296 | gist | 296 | gist |
297 | gist-paste | 297 | gist-paste |
298 | gitg | ||
299 | git-cola | 298 | git-cola |
299 | gitg | ||
300 | github-desktop | 300 | github-desktop |
301 | gitter | 301 | gitter |
302 | # gjs -- https://github.com/netblue30/firejail/issues/3333#issuecomment-612601102 | 302 | # gjs -- https://github.com/netblue30/firejail/issues/3333#issuecomment-612601102 |
@@ -387,14 +387,15 @@ icecat | |||
387 | icedove | 387 | icedove |
388 | iceweasel | 388 | iceweasel |
389 | idea | 389 | idea |
390 | ideaIC | ||
391 | idea.sh | 390 | idea.sh |
391 | ideaIC | ||
392 | imagej | 392 | imagej |
393 | img2txt | 393 | img2txt |
394 | impressive | 394 | impressive |
395 | inkscape | 395 | inkscape |
396 | inkview | 396 | inkview |
397 | inox | 397 | inox |
398 | io.github.lainsce.Notejot | ||
398 | ipcalc | 399 | ipcalc |
399 | ipcalc-ng | 400 | ipcalc-ng |
400 | iridium | 401 | iridium |
@@ -453,6 +454,7 @@ librecad | |||
453 | libreoffice | 454 | libreoffice |
454 | librewolf | 455 | librewolf |
455 | librewolf-nightly | 456 | librewolf-nightly |
457 | lifeograph | ||
456 | liferea | 458 | liferea |
457 | lightsoff | 459 | lightsoff |
458 | lincity-ng | 460 | lincity-ng |
@@ -508,6 +510,7 @@ mendeleydesktop | |||
508 | menulibre | 510 | menulibre |
509 | meteo-qt | 511 | meteo-qt |
510 | microsoft-edge | 512 | microsoft-edge |
513 | microsoft-edge-beta | ||
511 | microsoft-edge-dev | 514 | microsoft-edge-dev |
512 | midori | 515 | midori |
513 | min | 516 | min |
@@ -524,7 +527,6 @@ mp3splt-gtk | |||
524 | mp3wrap | 527 | mp3wrap |
525 | mpDris2 | 528 | mpDris2 |
526 | mpg123 | 529 | mpg123 |
527 | mpg123.bin | ||
528 | mpg123-alsa | 530 | mpg123-alsa |
529 | mpg123-id3dump | 531 | mpg123-id3dump |
530 | mpg123-jack | 532 | mpg123-jack |
@@ -534,6 +536,7 @@ mpg123-oss | |||
534 | mpg123-portaudio | 536 | mpg123-portaudio |
535 | mpg123-pulse | 537 | mpg123-pulse |
536 | mpg123-strip | 538 | mpg123-strip |
539 | mpg123.bin | ||
537 | mplayer | 540 | mplayer |
538 | mpsyt | 541 | mpsyt |
539 | mpv | 542 | mpv |
@@ -675,6 +678,7 @@ qupzilla | |||
675 | qutebrowser | 678 | qutebrowser |
676 | rambox | 679 | rambox |
677 | redeclipse | 680 | redeclipse |
681 | rednotebook | ||
678 | redshift | 682 | redshift |
679 | regextester | 683 | regextester |
680 | remmina | 684 | remmina |
@@ -735,8 +739,8 @@ steam | |||
735 | steam-native | 739 | steam-native |
736 | steam-runtime | 740 | steam-runtime |
737 | stellarium | 741 | stellarium |
738 | strawberry | ||
739 | straw-viewer | 742 | straw-viewer |
743 | strawberry | ||
740 | strings | 744 | strings |
741 | studio.sh | 745 | studio.sh |
742 | subdownloader | 746 | subdownloader |
@@ -863,10 +867,10 @@ wire-desktop | |||
863 | wireshark | 867 | wireshark |
864 | wireshark-gtk | 868 | wireshark-gtk |
865 | wireshark-qt | 869 | wireshark-qt |
870 | wordwarvi | ||
866 | wpp | 871 | wpp |
867 | wps | 872 | wps |
868 | wpspdf | 873 | wpspdf |
869 | wordwarvi | ||
870 | x2goclient | 874 | x2goclient |
871 | xbill | 875 | xbill |
872 | xcalc | 876 | xcalc |
@@ -908,6 +912,7 @@ zaproxy | |||
908 | zart | 912 | zart |
909 | zathura | 913 | zathura |
910 | zeal | 914 | zeal |
915 | zim | ||
911 | zoom | 916 | zoom |
912 | # zpaq - disable until we fix CLI archivers for makepkg on Arch (see discussion in #3095) | 917 | # zpaq - disable until we fix CLI archivers for makepkg on Arch (see discussion in #3095) |
913 | # zstd - disable until we fix CLI archivers for makepkg on Arch (see discussion in #3095) | 918 | # zstd - disable until we fix CLI archivers for makepkg on Arch (see discussion in #3095) |
diff --git a/src/firejail/main.c b/src/firejail/main.c index f64994e02..655e6e9d0 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -985,24 +985,16 @@ int main(int argc, char **argv, char **envp) { | |||
985 | int arg_caps_cmdline = 0; // caps requested on command line (used to break out of --chroot) | 985 | int arg_caps_cmdline = 0; // caps requested on command line (used to break out of --chroot) |
986 | char **ptr; | 986 | char **ptr; |
987 | 987 | ||
988 | #ifndef HAVE_SUID | ||
989 | if (geteuid() != 0) { | ||
990 | fprintf(stderr, "Error: Firejail needs to be SUID.\n"); | ||
991 | fprintf(stderr, "Assuming firejail is installed in /usr/bin, execute the following command as root:\n"); | ||
992 | fprintf(stderr, " chmod u+s /usr/bin/firejail\n"); | ||
993 | } | ||
994 | #endif | ||
995 | |||
996 | // sanitize the umask | 988 | // sanitize the umask |
997 | orig_umask = umask(022); | 989 | orig_umask = umask(022); |
998 | 990 | ||
999 | // check standard streams before printing anything | ||
1000 | fix_std_streams(); | ||
1001 | |||
1002 | // drop permissions by default and rise them when required | 991 | // drop permissions by default and rise them when required |
1003 | EUID_INIT(); | 992 | EUID_INIT(); |
1004 | EUID_USER(); | 993 | EUID_USER(); |
1005 | 994 | ||
995 | // check standard streams before opening any file | ||
996 | fix_std_streams(); | ||
997 | |||
1006 | // argument count should be larger than 0 | 998 | // argument count should be larger than 0 |
1007 | if (argc == 0 || !argv || strlen(argv[0]) == 0) { | 999 | if (argc == 0 || !argv || strlen(argv[0]) == 0) { |
1008 | fprintf(stderr, "Error: argv is invalid\n"); | 1000 | fprintf(stderr, "Error: argv is invalid\n"); |
@@ -1012,16 +1004,6 @@ int main(int argc, char **argv, char **envp) { | |||
1012 | exit(1); | 1004 | exit(1); |
1013 | } | 1005 | } |
1014 | 1006 | ||
1015 | // Stash environment variables | ||
1016 | for (i = 0, ptr = envp; ptr && *ptr && i < MAX_ENVS; i++, ptr++) | ||
1017 | env_store(*ptr, SETENV); | ||
1018 | |||
1019 | // sanity check for environment variables | ||
1020 | if (i >= MAX_ENVS) { | ||
1021 | fprintf(stderr, "Error: too many environment variables\n"); | ||
1022 | exit(1); | ||
1023 | } | ||
1024 | |||
1025 | // sanity check for arguments | 1007 | // sanity check for arguments |
1026 | for (i = 0; i < argc; i++) { | 1008 | for (i = 0; i < argc; i++) { |
1027 | if (*argv[i] == 0) { | 1009 | if (*argv[i] == 0) { |
@@ -1034,82 +1016,29 @@ int main(int argc, char **argv, char **envp) { | |||
1034 | } | 1016 | } |
1035 | } | 1017 | } |
1036 | 1018 | ||
1019 | // Stash environment variables | ||
1020 | for (i = 0, ptr = envp; ptr && *ptr && i < MAX_ENVS; i++, ptr++) | ||
1021 | env_store(*ptr, SETENV); | ||
1022 | |||
1023 | // sanity check for environment variables | ||
1024 | if (i >= MAX_ENVS) { | ||
1025 | fprintf(stderr, "Error: too many environment variables\n"); | ||
1026 | exit(1); | ||
1027 | } | ||
1028 | |||
1037 | // Reapply a minimal set of environment variables | 1029 | // Reapply a minimal set of environment variables |
1038 | env_apply_whitelist(); | 1030 | env_apply_whitelist(); |
1039 | 1031 | ||
1040 | // check if the user is allowed to use firejail | 1032 | // process --quiet |
1041 | init_cfg(argc, argv); | ||
1042 | |||
1043 | // get starting timestamp, process --quiet | ||
1044 | timetrace_start(); | ||
1045 | const char *env_quiet = env_get("FIREJAIL_QUIET"); | 1033 | const char *env_quiet = env_get("FIREJAIL_QUIET"); |
1046 | if (check_arg(argc, argv, "--quiet", 1) || (env_quiet && strcmp(env_quiet, "yes") == 0)) | 1034 | if (check_arg(argc, argv, "--quiet", 1) || (env_quiet && strcmp(env_quiet, "yes") == 0)) |
1047 | arg_quiet = 1; | 1035 | arg_quiet = 1; |
1048 | 1036 | ||
1049 | // cleanup at exit | 1037 | // check if the user is allowed to use firejail |
1050 | EUID_ROOT(); | 1038 | init_cfg(argc, argv); |
1051 | atexit(clear_atexit); | ||
1052 | |||
1053 | // build /run/firejail directory structure | ||
1054 | preproc_build_firejail_dir(); | ||
1055 | const char *container_name = env_get("container"); | ||
1056 | if (!container_name || strcmp(container_name, "firejail")) { | ||
1057 | lockfd_directory = open(RUN_DIRECTORY_LOCK_FILE, O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR); | ||
1058 | if (lockfd_directory != -1) { | ||
1059 | int rv = fchown(lockfd_directory, 0, 0); | ||
1060 | (void) rv; | ||
1061 | flock(lockfd_directory, LOCK_EX); | ||
1062 | } | ||
1063 | preproc_clean_run(); | ||
1064 | flock(lockfd_directory, LOCK_UN); | ||
1065 | close(lockfd_directory); | ||
1066 | } | ||
1067 | EUID_USER(); | ||
1068 | |||
1069 | // --ip=dhcp - we need access to /sbin and /usr/sbin directories in order to run ISC DHCP client (dhclient) | ||
1070 | // these paths are disabled in disable-common.inc | ||
1071 | if ((i = check_arg(argc, argv, "--ip", 0)) != 0) { | ||
1072 | if (strncmp(argv[i] + 4, "=dhcp", 5) == 0) { | ||
1073 | profile_add("noblacklist /sbin"); | ||
1074 | profile_add("noblacklist /usr/sbin"); | ||
1075 | } | ||
1076 | } | ||
1077 | |||
1078 | // for appimages we need to remove "include disable-shell.inc from the profile | ||
1079 | // a --profile command can show up before --appimage | ||
1080 | if (check_arg(argc, argv, "--appimage", 1)) | ||
1081 | arg_appimage = 1; | ||
1082 | |||
1083 | // process allow-debuggers | ||
1084 | if (check_arg(argc, argv, "--allow-debuggers", 1)) { | ||
1085 | // check kernel version | ||
1086 | struct utsname u; | ||
1087 | int rv = uname(&u); | ||
1088 | if (rv != 0) | ||
1089 | errExit("uname"); | ||
1090 | int major; | ||
1091 | int minor; | ||
1092 | if (2 != sscanf(u.release, "%d.%d", &major, &minor)) { | ||
1093 | fprintf(stderr, "Error: cannot extract Linux kernel version: %s\n", u.version); | ||
1094 | exit(1); | ||
1095 | } | ||
1096 | if (major < 4 || (major == 4 && minor < 8)) { | ||
1097 | fprintf(stderr, "Error: --allow-debuggers is disabled on Linux kernels prior to 4.8. " | ||
1098 | "A bug in ptrace call allows a full bypass of the seccomp filter. " | ||
1099 | "Your current kernel version is %d.%d.\n", major, minor); | ||
1100 | exit(1); | ||
1101 | } | ||
1102 | |||
1103 | arg_allow_debuggers = 1; | ||
1104 | char *cmd = strdup("noblacklist ${PATH}/strace"); | ||
1105 | if (!cmd) | ||
1106 | errExit("strdup"); | ||
1107 | profile_add(cmd); | ||
1108 | } | ||
1109 | 1039 | ||
1110 | // profile builder | 1040 | // get starting timestamp |
1111 | if (check_arg(argc, argv, "--build", 0)) // supports both --build and --build=filename | 1041 | timetrace_start(); |
1112 | run_builder(argc, argv); // this function will not return | ||
1113 | 1042 | ||
1114 | // check argv[0] symlink wrapper if this is not a login shell | 1043 | // check argv[0] symlink wrapper if this is not a login shell |
1115 | if (*argv[0] != '-') | 1044 | if (*argv[0] != '-') |
@@ -1134,15 +1063,40 @@ int main(int argc, char **argv, char **envp) { | |||
1134 | __builtin_unreachable(); | 1063 | __builtin_unreachable(); |
1135 | } | 1064 | } |
1136 | } | 1065 | } |
1137 | EUID_ASSERT(); | ||
1138 | 1066 | ||
1067 | // profile builder | ||
1068 | if (check_arg(argc, argv, "--build", 0)) // supports both --build and --build=filename | ||
1069 | run_builder(argc, argv); // this function will not return | ||
1139 | 1070 | ||
1140 | // check firejail directories | ||
1141 | EUID_ROOT(); | 1071 | EUID_ROOT(); |
1142 | delete_run_files(sandbox_pid); | 1072 | #ifndef HAVE_SUID |
1073 | if (geteuid() != 0) { | ||
1074 | fprintf(stderr, "Error: Firejail needs to be SUID.\n"); | ||
1075 | fprintf(stderr, "Assuming firejail is installed in /usr/bin, execute the following command as root:\n"); | ||
1076 | fprintf(stderr, " chmod u+s /usr/bin/firejail\n"); | ||
1077 | } | ||
1078 | #endif | ||
1079 | |||
1080 | // build /run/firejail directory structure | ||
1081 | preproc_build_firejail_dir(); | ||
1082 | const char *container_name = env_get("container"); | ||
1083 | if (!container_name || strcmp(container_name, "firejail")) { | ||
1084 | lockfd_directory = open(RUN_DIRECTORY_LOCK_FILE, O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR); | ||
1085 | if (lockfd_directory != -1) { | ||
1086 | int rv = fchown(lockfd_directory, 0, 0); | ||
1087 | (void) rv; | ||
1088 | flock(lockfd_directory, LOCK_EX); | ||
1089 | } | ||
1090 | preproc_clean_run(); | ||
1091 | flock(lockfd_directory, LOCK_UN); | ||
1092 | close(lockfd_directory); | ||
1093 | } | ||
1094 | |||
1095 | delete_run_files(getpid()); | ||
1096 | atexit(clear_atexit); | ||
1143 | EUID_USER(); | 1097 | EUID_USER(); |
1144 | 1098 | ||
1145 | //check if the parent is sshd daemon | 1099 | // check if the parent is sshd daemon |
1146 | int parent_sshd = 0; | 1100 | int parent_sshd = 0; |
1147 | { | 1101 | { |
1148 | pid_t ppid = getppid(); | 1102 | pid_t ppid = getppid(); |
@@ -1199,7 +1153,8 @@ int main(int argc, char **argv, char **envp) { | |||
1199 | } | 1153 | } |
1200 | EUID_ASSERT(); | 1154 | EUID_ASSERT(); |
1201 | 1155 | ||
1202 | // is this a login shell, or a command passed by sshd, insert command line options from /etc/firejail/login.users | 1156 | // is this a login shell, or a command passed by sshd, |
1157 | // insert command line options from /etc/firejail/login.users | ||
1203 | if (*argv[0] == '-' || parent_sshd) { | 1158 | if (*argv[0] == '-' || parent_sshd) { |
1204 | if (argc == 1) | 1159 | if (argc == 1) |
1205 | login_shell = 1; | 1160 | login_shell = 1; |
@@ -1251,6 +1206,47 @@ int main(int argc, char **argv, char **envp) { | |||
1251 | #endif | 1206 | #endif |
1252 | EUID_ASSERT(); | 1207 | EUID_ASSERT(); |
1253 | 1208 | ||
1209 | // --ip=dhcp - we need access to /sbin and /usr/sbin directories in order to run ISC DHCP client (dhclient) | ||
1210 | // these paths are disabled in disable-common.inc | ||
1211 | if ((i = check_arg(argc, argv, "--ip", 0)) != 0) { | ||
1212 | if (strncmp(argv[i] + 4, "=dhcp", 5) == 0) { | ||
1213 | profile_add("noblacklist /sbin"); | ||
1214 | profile_add("noblacklist /usr/sbin"); | ||
1215 | } | ||
1216 | } | ||
1217 | |||
1218 | // process allow-debuggers | ||
1219 | if (check_arg(argc, argv, "--allow-debuggers", 1)) { | ||
1220 | // check kernel version | ||
1221 | struct utsname u; | ||
1222 | int rv = uname(&u); | ||
1223 | if (rv != 0) | ||
1224 | errExit("uname"); | ||
1225 | int major; | ||
1226 | int minor; | ||
1227 | if (2 != sscanf(u.release, "%d.%d", &major, &minor)) { | ||
1228 | fprintf(stderr, "Error: cannot extract Linux kernel version: %s\n", u.version); | ||
1229 | exit(1); | ||
1230 | } | ||
1231 | if (major < 4 || (major == 4 && minor < 8)) { | ||
1232 | fprintf(stderr, "Error: --allow-debuggers is disabled on Linux kernels prior to 4.8. " | ||
1233 | "A bug in ptrace call allows a full bypass of the seccomp filter. " | ||
1234 | "Your current kernel version is %d.%d.\n", major, minor); | ||
1235 | exit(1); | ||
1236 | } | ||
1237 | |||
1238 | arg_allow_debuggers = 1; | ||
1239 | char *cmd = strdup("noblacklist ${PATH}/strace"); | ||
1240 | if (!cmd) | ||
1241 | errExit("strdup"); | ||
1242 | profile_add(cmd); | ||
1243 | } | ||
1244 | |||
1245 | // for appimages we need to remove "include disable-shell.inc from the profile | ||
1246 | // a --profile command can show up before --appimage | ||
1247 | if (check_arg(argc, argv, "--appimage", 1)) | ||
1248 | arg_appimage = 1; | ||
1249 | |||
1254 | // check for force-nonewprivs in /etc/firejail/firejail.config file | 1250 | // check for force-nonewprivs in /etc/firejail/firejail.config file |
1255 | if (checkcfg(CFG_FORCE_NONEWPRIVS)) | 1251 | if (checkcfg(CFG_FORCE_NONEWPRIVS)) |
1256 | arg_nonewprivs = 1; | 1252 | arg_nonewprivs = 1; |
@@ -2680,8 +2676,9 @@ int main(int argc, char **argv, char **envp) { | |||
2680 | //************************************* | 2676 | //************************************* |
2681 | else if (strncmp(argv[i], "--timeout=", 10) == 0) | 2677 | else if (strncmp(argv[i], "--timeout=", 10) == 0) |
2682 | cfg.timeout = extract_timeout(argv[i] + 10); | 2678 | cfg.timeout = extract_timeout(argv[i] + 10); |
2683 | else if (strcmp(argv[i], "--appimage") == 0) | 2679 | else if (strcmp(argv[i], "--appimage") == 0) { |
2684 | arg_appimage = 1; | 2680 | // already handled |
2681 | } | ||
2685 | else if (strcmp(argv[i], "--shell=none") == 0) { | 2682 | else if (strcmp(argv[i], "--shell=none") == 0) { |
2686 | arg_shell_none = 1; | 2683 | arg_shell_none = 1; |
2687 | if (cfg.shell) { | 2684 | if (cfg.shell) { |
diff --git a/src/firejail/no_sandbox.c b/src/firejail/no_sandbox.c index 665bef73d..0e5562d90 100644 --- a/src/firejail/no_sandbox.c +++ b/src/firejail/no_sandbox.c | |||
@@ -49,6 +49,7 @@ int check_namespace_virt(void) { | |||
49 | // check PID 1 container environment variable | 49 | // check PID 1 container environment variable |
50 | EUID_ROOT(); | 50 | EUID_ROOT(); |
51 | FILE *fp = fopen("/proc/1/environ", "re"); | 51 | FILE *fp = fopen("/proc/1/environ", "re"); |
52 | EUID_USER(); | ||
52 | if (fp) { | 53 | if (fp) { |
53 | int c = 0; | 54 | int c = 0; |
54 | while (c != EOF) { | 55 | while (c != EOF) { |
@@ -69,7 +70,6 @@ int check_namespace_virt(void) { | |||
69 | // found it | 70 | // found it |
70 | if (is_container(buf + 10)) { | 71 | if (is_container(buf + 10)) { |
71 | fclose(fp); | 72 | fclose(fp); |
72 | EUID_USER(); | ||
73 | return 1; | 73 | return 1; |
74 | } | 74 | } |
75 | } | 75 | } |
@@ -79,7 +79,6 @@ int check_namespace_virt(void) { | |||
79 | fclose(fp); | 79 | fclose(fp); |
80 | } | 80 | } |
81 | 81 | ||
82 | EUID_USER(); | ||
83 | return 0; | 82 | return 0; |
84 | } | 83 | } |
85 | 84 | ||
diff --git a/src/firejail/output.c b/src/firejail/output.c index 835dff2db..ce10ab157 100644 --- a/src/firejail/output.c +++ b/src/firejail/output.c | |||
@@ -50,13 +50,21 @@ void check_output(int argc, char **argv) { | |||
50 | if (!outindex) | 50 | if (!outindex) |
51 | return; | 51 | return; |
52 | 52 | ||
53 | |||
54 | // check filename | ||
55 | drop_privs(0); | 53 | drop_privs(0); |
56 | char *outfile = argv[outindex]; | 54 | char *outfile = argv[outindex]; |
57 | outfile += (enable_stderr)? 16:9; | 55 | outfile += (enable_stderr)? 16:9; |
56 | |||
57 | // check filename | ||
58 | invalid_filename(outfile, 0); // no globbing | 58 | invalid_filename(outfile, 0); // no globbing |
59 | 59 | ||
60 | // expand user home directory | ||
61 | if (outfile[0] == '~') { | ||
62 | char *full; | ||
63 | if (asprintf(&full, "%s%s", cfg.homedir, outfile + 1) == -1) | ||
64 | errExit("asprintf"); | ||
65 | outfile = full; | ||
66 | } | ||
67 | |||
60 | // do not accept directories, links, and files with ".." | 68 | // do not accept directories, links, and files with ".." |
61 | if (strstr(outfile, "..") || is_link(outfile) || is_dir(outfile)) { | 69 | if (strstr(outfile, "..") || is_link(outfile) || is_dir(outfile)) { |
62 | fprintf(stderr, "Error: invalid output file. Links, directories and files with \"..\" are not allowed.\n"); | 70 | fprintf(stderr, "Error: invalid output file. Links, directories and files with \"..\" are not allowed.\n"); |
diff --git a/src/firejail/util.c b/src/firejail/util.c index de31ebdd6..094a68c60 100644 --- a/src/firejail/util.c +++ b/src/firejail/util.c | |||
@@ -1513,8 +1513,7 @@ void check_homedir(const char *dir) { | |||
1513 | exit(1); | 1513 | exit(1); |
1514 | } | 1514 | } |
1515 | // symlinks are rejected in many places | 1515 | // symlinks are rejected in many places |
1516 | if (has_link(dir)) { | 1516 | if (has_link(dir)) |
1517 | fprintf(stderr, "No full support for symbolic links in path of user directory.\n" | 1517 | fmessage("No full support for symbolic links in path of user directory.\n" |
1518 | "Please provide resolved path in password database (/etc/passwd).\n\n"); | 1518 | "Please provide resolved path in password database (/etc/passwd).\n\n"); |
1519 | } | ||
1520 | } | 1519 | } |