aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar smitsohu <smitsohu@gmail.com>2021-06-03 18:47:30 +0200
committerLibravatar smitsohu <smitsohu@gmail.com>2021-06-03 18:47:30 +0200
commitacbdbe29da9a04bd3b7a6c584e7633aae8dbe5c5 (patch)
tree3b7b09abebad7994c013c083c7d49bbd7b8ab27e /src
parentUpdate profile.template (diff)
downloadfirejail-acbdbe29da9a04bd3b7a6c584e7633aae8dbe5c5.tar.gz
firejail-acbdbe29da9a04bd3b7a6c584e7633aae8dbe5c5.tar.zst
firejail-acbdbe29da9a04bd3b7a6c584e7633aae8dbe5c5.zip
simplify X11 socket whitelisting
Diffstat (limited to 'src')
-rw-r--r--src/firejail/x11.c63
-rw-r--r--src/include/rundefs.h4
2 files changed, 22 insertions, 45 deletions
diff --git a/src/firejail/x11.c b/src/firejail/x11.c
index 257d376a1..f4f093138 100644
--- a/src/firejail/x11.c
+++ b/src/firejail/x11.c
@@ -1327,7 +1327,7 @@ void fs_x11(void) {
1327 struct stat s1, s2; 1327 struct stat s1, s2;
1328 if (stat("/tmp", &s1) != 0 || lstat("/tmp/.X11-unix", &s2) != 0) 1328 if (stat("/tmp", &s1) != 0 || lstat("/tmp/.X11-unix", &s2) != 0)
1329 return; 1329 return;
1330 if ((s1.st_mode & S_ISVTX) == 0) { 1330 if ((s1.st_mode & S_ISVTX) != S_ISVTX) {
1331 fwarning("cannot mask X11 sockets: sticky bit not set on /tmp directory\n"); 1331 fwarning("cannot mask X11 sockets: sticky bit not set on /tmp directory\n");
1332 return; 1332 return;
1333 } 1333 }
@@ -1335,26 +1335,26 @@ void fs_x11(void) {
1335 fwarning("cannot mask X11 sockets: /tmp/.X11-unix not owned by root user\n"); 1335 fwarning("cannot mask X11 sockets: /tmp/.X11-unix not owned by root user\n");
1336 return; 1336 return;
1337 } 1337 }
1338
1338 char *x11file; 1339 char *x11file;
1339 if (asprintf(&x11file, "/tmp/.X11-unix/X%d", display) == -1) 1340 if (asprintf(&x11file, "/tmp/.X11-unix/X%d", display) == -1)
1340 errExit("asprintf"); 1341 errExit("asprintf");
1342 int src = open(x11file, O_PATH|O_NOFOLLOW|O_CLOEXEC);
1343 if (src < 0) {
1344 free(x11file);
1345 return;
1346 }
1341 struct stat x11stat; 1347 struct stat x11stat;
1342 if (lstat(x11file, &x11stat) != 0 || !S_ISSOCK(x11stat.st_mode)) { 1348 if (fstat(src, &x11stat) < 0)
1349 errExit("fstat");
1350 if (!S_ISSOCK(x11stat.st_mode)) {
1351 close(src);
1343 free(x11file); 1352 free(x11file);
1344 return; 1353 return;
1345 } 1354 }
1346 1355
1347 if (arg_debug || arg_debug_whitelists) 1356 if (arg_debug || arg_debug_whitelists)
1348 fprintf(stderr, "Masking all X11 sockets except %s\n", x11file); 1357 fprintf(stderr, "Masking all X11 sockets except %s\n", x11file);
1349
1350 // Move the real /tmp/.X11-unix to a scratch location
1351 // so we can still access x11file after we mount a
1352 // tmpfs over /tmp/.X11-unix.
1353 if (mkdir(RUN_WHITELIST_X11_DIR, 0700) == -1)
1354 errExit("mkdir");
1355 if (mount("/tmp/.X11-unix", RUN_WHITELIST_X11_DIR, 0, MS_BIND|MS_REC, 0) < 0)
1356 errExit("mount bind");
1357
1358 // This directory must be mode 1777 1358 // This directory must be mode 1777
1359 if (mount("tmpfs", "/tmp/.X11-unix", "tmpfs", 1359 if (mount("tmpfs", "/tmp/.X11-unix", "tmpfs",
1360 MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME, 1360 MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME,
@@ -1363,40 +1363,21 @@ void fs_x11(void) {
1363 fs_logger("tmpfs /tmp/.X11-unix"); 1363 fs_logger("tmpfs /tmp/.X11-unix");
1364 1364
1365 // create an empty root-owned file which will have the desired socket bind-mounted over it 1365 // create an empty root-owned file which will have the desired socket bind-mounted over it
1366 int fd = open(x11file, O_RDONLY|O_CREAT|O_EXCL|O_CLOEXEC, S_IRUSR | S_IWUSR); 1366 int dst = open(x11file, O_RDONLY|O_CREAT|O_EXCL|O_CLOEXEC, S_IRUSR | S_IWUSR);
1367 if (fd < 0) 1367 if (dst < 0)
1368 errExit(x11file); 1368 errExit("open");
1369 close(fd);
1370 1369
1371 // the mount source is under control of the user, so be careful and 1370 char *proc_src, *proc_dst;
1372 // mount without following symbolic links, using a file descriptor 1371 if (asprintf(&proc_src, "/proc/self/fd/%d", src) == -1 ||
1373 char *wx11file; 1372 asprintf(&proc_dst, "/proc/self/fd/%d", dst) == -1)
1374 if (asprintf(&wx11file, "%s/X%d", RUN_WHITELIST_X11_DIR, display) == -1)
1375 errExit("asprintf");
1376 fd = safer_openat(-1, wx11file, O_PATH|O_NOFOLLOW|O_CLOEXEC);
1377 if (fd == -1)
1378 errExit("opening X11 socket");
1379 // confirm once more we are mounting a socket
1380 if (fstat(fd, &x11stat) == -1)
1381 errExit("fstat");
1382 if (!S_ISSOCK(x11stat.st_mode)) {
1383 errno = ENOTSOCK;
1384 errExit("mounting X11 socket");
1385 }
1386 char *proc;
1387 if (asprintf(&proc, "/proc/self/fd/%d", fd) == -1)
1388 errExit("asprintf"); 1373 errExit("asprintf");
1389 if (mount(proc, x11file, NULL, MS_BIND|MS_REC, NULL) < 0) 1374 if (mount(proc_src, proc_dst, NULL, MS_BIND | MS_REC, NULL) < 0)
1390 errExit("mount bind"); 1375 errExit("mount bind");
1376 free(proc_src);
1377 free(proc_dst);
1378 close(src);
1379 close(dst);
1391 fs_logger2("whitelist", x11file); 1380 fs_logger2("whitelist", x11file);
1392 close(fd);
1393 free(proc);
1394
1395 // block access to RUN_WHITELIST_X11_DIR
1396 if (mount(RUN_RO_DIR, RUN_WHITELIST_X11_DIR, 0, MS_BIND, 0) < 0)
1397 errExit("mount");
1398 fs_logger2("blacklist", RUN_WHITELIST_X11_DIR);
1399 free(wx11file);
1400 free(x11file); 1381 free(x11file);
1401#endif 1382#endif
1402} 1383}
diff --git a/src/include/rundefs.h b/src/include/rundefs.h
index a172dd511..3db750da3 100644
--- a/src/include/rundefs.h
+++ b/src/include/rundefs.h
@@ -79,12 +79,8 @@
79#define PATH_SECCOMP_MDWX_32 LIBDIR "/firejail/seccomp.mdwx.32" 79#define PATH_SECCOMP_MDWX_32 LIBDIR "/firejail/seccomp.mdwx.32"
80#define PATH_SECCOMP_BLOCK_SECONDARY LIBDIR "/firejail/seccomp.block_secondary" // secondary arch blocking filter built during make 80#define PATH_SECCOMP_BLOCK_SECONDARY LIBDIR "/firejail/seccomp.block_secondary" // secondary arch blocking filter built during make
81 81
82
83#define RUN_DEV_DIR RUN_MNT_DIR "/dev" 82#define RUN_DEV_DIR RUN_MNT_DIR "/dev"
84#define RUN_DEVLOG_FILE RUN_MNT_DIR "/devlog" 83#define RUN_DEVLOG_FILE RUN_MNT_DIR "/devlog"
85
86#define RUN_WHITELIST_X11_DIR RUN_MNT_DIR "/orig-x11"
87
88#define RUN_XAUTHORITY_FILE RUN_MNT_DIR "/.Xauthority" // private options 84#define RUN_XAUTHORITY_FILE RUN_MNT_DIR "/.Xauthority" // private options
89#define RUN_XAUTH_FILE RUN_MNT_DIR "/xauth" // x11=xorg 85#define RUN_XAUTH_FILE RUN_MNT_DIR "/xauth" // x11=xorg
90#define RUN_XAUTHORITY_SEC_DIR RUN_MNT_DIR "/.sec.Xauthority" // x11=xorg 86#define RUN_XAUTHORITY_SEC_DIR RUN_MNT_DIR "/.sec.Xauthority" // x11=xorg