aboutsummaryrefslogtreecommitdiffstats
path: root/src/firejail/x11.c
diff options
context:
space:
mode:
authorLibravatar smitsohu <smitsohu@gmail.com>2018-06-12 01:57:01 +0200
committerLibravatar smitsohu <smitsohu@gmail.com>2018-06-12 01:57:01 +0200
commit8db696600f6fd0f425e19f0f154ad6639e2f0a92 (patch)
treed5fefe65cd12d42928f0d5eb5c46049f75cf866d /src/firejail/x11.c
parentremoved CFG_CHROOT_DESKTOP config option (diff)
downloadfirejail-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.c46
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.
37int x11_display(void) { 43int 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}