diff options
author | smitsohu <smitsohu@gmail.com> | 2018-06-12 01:57:01 +0200 |
---|---|---|
committer | smitsohu <smitsohu@gmail.com> | 2018-06-12 01:57:01 +0200 |
commit | 8db696600f6fd0f425e19f0f154ad6639e2f0a92 (patch) | |
tree | d5fefe65cd12d42928f0d5eb5c46049f75cf866d /src/firejail/x11.c | |
parent | removed CFG_CHROOT_DESKTOP config option (diff) | |
download | firejail-8db696600f6fd0f425e19f0f154ad6639e2f0a92.tar.gz firejail-8db696600f6fd0f425e19f0f154ad6639e2f0a92.tar.zst firejail-8db696600f6fd0f425e19f0f154ad6639e2f0a92.zip |
additional mount hardening (pulseaudio, Xauthority)
Diffstat (limited to 'src/firejail/x11.c')
-rw-r--r-- | src/firejail/x11.c | 46 |
1 files changed, 31 insertions, 15 deletions
diff --git a/src/firejail/x11.c b/src/firejail/x11.c index 4019e6001..62a769508 100644 --- a/src/firejail/x11.c +++ b/src/firejail/x11.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <sys/stat.h> | 22 | #include <sys/stat.h> |
23 | #include <sys/socket.h> | 23 | #include <sys/socket.h> |
24 | #include <sys/un.h> | 24 | #include <sys/un.h> |
25 | #include <fcntl.h> | ||
26 | #include <unistd.h> | 25 | #include <unistd.h> |
27 | #include <signal.h> | 26 | #include <signal.h> |
28 | #include <stdlib.h> | 27 | #include <stdlib.h> |
@@ -32,6 +31,13 @@ | |||
32 | #include <errno.h> | 31 | #include <errno.h> |
33 | #include <limits.h> | 32 | #include <limits.h> |
34 | 33 | ||
34 | // on Debian 7 we are missing O_PATH definition | ||
35 | #include <fcntl.h> | ||
36 | #ifndef O_PATH | ||
37 | #define O_PATH 010000000 | ||
38 | #endif | ||
39 | |||
40 | |||
35 | // Parse the DISPLAY environment variable and return a display number. | 41 | // Parse the DISPLAY environment variable and return a display number. |
36 | // Returns -1 if DISPLAY is not set, or is set to anything other than :ddd. | 42 | // Returns -1 if DISPLAY is not set, or is set to anything other than :ddd. |
37 | int x11_display(void) { | 43 | int x11_display(void) { |
@@ -1095,7 +1101,7 @@ void x11_xorg(void) { | |||
1095 | } | 1101 | } |
1096 | 1102 | ||
1097 | // temporarily mount a tempfs on top of /tmp directory | 1103 | // temporarily mount a tempfs on top of /tmp directory |
1098 | if (mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=777,gid=0") < 0) | 1104 | if (mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=1777,gid=0") < 0) |
1099 | errExit("mounting /tmp"); | 1105 | errExit("mounting /tmp"); |
1100 | 1106 | ||
1101 | // create the temporary .Xauthority file | 1107 | // create the temporary .Xauthority file |
@@ -1156,38 +1162,48 @@ void x11_xorg(void) { | |||
1156 | fprintf(stderr, "Error: cannot create the new .Xauthority file\n"); | 1162 | fprintf(stderr, "Error: cannot create the new .Xauthority file\n"); |
1157 | exit(1); | 1163 | exit(1); |
1158 | } | 1164 | } |
1159 | ASSERT_PERMS(RUN_XAUTHORITY_SEC_FILE, getuid(), getgid(), 0600); | ||
1160 | /* coverity[toctou] */ | 1165 | /* coverity[toctou] */ |
1161 | unlink(tmpfname); | 1166 | unlink(tmpfname); |
1162 | umount("/tmp"); | 1167 | umount("/tmp"); |
1163 | 1168 | ||
1164 | // Ensure there is already a file in the usual location, so that bind-mount below will work. | 1169 | // Ensure there is already a file in the usual location, so that bind-mount below will work. |
1165 | // todo: fix TOCTOU races, currently managed by imposing /usr/bin/xauth as executable | ||
1166 | char *dest; | 1170 | char *dest; |
1167 | if (asprintf(&dest, "%s/.Xauthority", cfg.homedir) == -1) | 1171 | if (asprintf(&dest, "%s/.Xauthority", cfg.homedir) == -1) |
1168 | errExit("asprintf"); | 1172 | errExit("asprintf"); |
1169 | if (stat(dest, &s) == -1) { | 1173 | if (lstat(dest, &s) == -1) |
1170 | // create an .Xauthority file | ||
1171 | touch_file_as_user(dest, getuid(), getgid(), 0600); | 1174 | touch_file_as_user(dest, getuid(), getgid(), 0600); |
1172 | } | 1175 | |
1173 | if (is_link(dest)) { | 1176 | // get a file descriptor for .Xauthority |
1174 | fprintf(stderr, "Error: .Xauthority is a symbolic link\n"); | 1177 | fd = safe_fd(dest, O_PATH|O_NOFOLLOW|O_CLOEXEC); |
1178 | if (fd == -1) | ||
1179 | errExit("safe_fd"); | ||
1180 | // check if the actual mount destination is a user owned regular file | ||
1181 | if (fstat(fd, &s) == -1) | ||
1182 | errExit("fstat"); | ||
1183 | if (!S_ISREG(s.st_mode) || s.st_uid != getuid()) { | ||
1184 | if (S_ISLNK(s.st_mode)) | ||
1185 | fprintf(stderr, "Error: .Xauthority is a symbolic link\n"); | ||
1186 | else | ||
1187 | fprintf(stderr, "Error: .Xauthority is not a user owned regular file\n"); | ||
1175 | exit(1); | 1188 | exit(1); |
1176 | } | 1189 | } |
1177 | 1190 | ||
1178 | // mount | 1191 | // mount via the link in /proc/self/fd |
1179 | if (mount(RUN_XAUTHORITY_SEC_FILE, dest, "none", MS_BIND, "mode=0600") == -1) { | 1192 | char *proc; |
1193 | if (asprintf(&proc, "/proc/self/fd/%d", fd) == -1) | ||
1194 | errExit("asprintf"); | ||
1195 | if (mount(RUN_XAUTHORITY_SEC_FILE, proc, "none", MS_BIND, "mode=0600") == -1) { | ||
1180 | fprintf(stderr, "Error: cannot mount the new .Xauthority file\n"); | 1196 | fprintf(stderr, "Error: cannot mount the new .Xauthority file\n"); |
1181 | exit(1); | 1197 | exit(1); |
1182 | } | 1198 | } |
1183 | 1199 | free(proc); | |
1200 | close(fd); | ||
1184 | // check /proc/self/mountinfo to confirm the mount is ok | 1201 | // check /proc/self/mountinfo to confirm the mount is ok |
1185 | MountData *mptr = get_last_mount(); | 1202 | MountData *mptr = get_last_mount(); |
1186 | if (strcmp(mptr->dir, dest) != 0) | 1203 | if (strcmp(mptr->dir, dest) != 0 || strcmp(mptr->fstype, "tmpfs") != 0) |
1187 | errLogExit("invalid .Xauthority mount"); | ||
1188 | if (strcmp(mptr->fstype, "tmpfs") != 0) | ||
1189 | errLogExit("invalid .Xauthority mount"); | 1204 | errLogExit("invalid .Xauthority mount"); |
1190 | 1205 | ||
1206 | ASSERT_PERMS(dest, getuid(), getgid(), 0600); | ||
1191 | free(dest); | 1207 | free(dest); |
1192 | #endif | 1208 | #endif |
1193 | } | 1209 | } |