aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2017-02-15 09:02:53 -0500
committerLibravatar netblue30 <netblue30@yahoo.com>2017-02-15 09:02:53 -0500
commit6a8d393f25a9c6e525a450ba474e402decccee95 (patch)
tree509fa35041329f3b36139e8695da3e411f373940
parentmerge #1100 from zackw: rework xpra and xephyr detection (diff)
downloadfirejail-6a8d393f25a9c6e525a450ba474e402decccee95.tar.gz
firejail-6a8d393f25a9c6e525a450ba474e402decccee95.tar.zst
firejail-6a8d393f25a9c6e525a450ba474e402decccee95.zip
merge #1100 from zackw: rework abstract X11 socket detection
-rw-r--r--README5
-rw-r--r--src/firejail/x11.c115
2 files changed, 70 insertions, 50 deletions
diff --git a/README b/README
index 52c5f7dd2..e729b4580 100644
--- a/README
+++ b/README
@@ -104,7 +104,10 @@ valoq (https://github.com/valoq)
104Zack Weinberg (https://github.com/zackw) 104Zack Weinberg (https://github.com/zackw)
105 - removed libconnect 105 - removed libconnect
106 - fixed memory corruption in noblacklist processing 106 - fixed memory corruption in noblacklist processing
107 - rework DISPLAY environment parsing, rework masking X11 sockets in /tmp/.X11-unix directory 107 - rework DISPLAY environment parsing
108 - rework masking X11 sockets in /tmp/.X11-unix directory
109 - rework xpra and xephyr detection
110 - rework abstract X11 socket detection
108Igor Bukanov (https://github.com/ibukanov) 111Igor Bukanov (https://github.com/ibukanov)
109 - found/fiixed privilege escalation in --hosts-file option 112 - found/fiixed privilege escalation in --hosts-file option
110Cat (https://github.com/ecat3) 113Cat (https://github.com/ecat3)
diff --git a/src/firejail/x11.c b/src/firejail/x11.c
index f81a52b70..328ecce18 100644
--- a/src/firejail/x11.c
+++ b/src/firejail/x11.c
@@ -31,30 +31,85 @@
31#include <limits.h> 31#include <limits.h>
32int mask_x11_abstract_socket = 0; 32int mask_x11_abstract_socket = 0;
33 33
34
35// 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.
37int x11_display(void) {
38 const char *display_str = getenv("DISPLAY");
39 char *endp;
40 unsigned long display;
41
42 if (!display_str) {
43 if (arg_debug)
44 fputs("DISPLAY is not set\n", stderr);
45 return -1;
46 }
47
48 if (display_str[0] != ':' || display_str[1] < '0' || display_str[1] > '9') {
49 if (arg_debug)
50 fprintf(stderr, "unsupported DISPLAY form '%s'\n", display_str);
51 return -1;
52 }
53
54 errno = 0;
55 display = strtoul(display_str+1, &endp, 10);
56 if (endp == display_str+1 || (*endp != '\0' && *endp != '.')) { // handling DISPLAY=:0 and also :0.0
57 if (arg_debug)
58 fprintf(stderr, "unsupported DISPLAY form '%s'\n", display_str);
59 return -1;
60 }
61 if (errno || display > (unsigned long)INT_MAX) {
62 if (arg_debug)
63 fprintf(stderr, "display number %s is outside the valid range\n",
64 display_str+1);
65 return -1;
66 }
67
68 if (arg_debug)
69 fprintf(stderr, "DISPLAY=%s parsed as %lu\n", display_str, display);
70
71 return (int)display;
72}
73
74
34#ifdef HAVE_X11 75#ifdef HAVE_X11
35// check for X11 abstract sockets 76// check for X11 abstract sockets
36static int x11_abstract_sockets_present(void) { 77static int x11_abstract_sockets_present(void) {
37 char *path;
38 78
39 EUID_ROOT(); // grsecurity fix 79 EUID_ROOT(); // grsecurity fix
40 FILE *fp = fopen("/proc/net/unix", "r"); 80 FILE *fp = fopen("/proc/net/unix", "r");
41 EUID_USER();
42
43 if (!fp) 81 if (!fp)
44 errExit("fopen"); 82 errExit("fopen");
83 EUID_USER();
84
85 char *linebuf = 0;
86 size_t bufsz = 0;
87 int found = 0;
88 errno = 0;
45 89
46 while (fscanf(fp, "%*s %*s %*s %*s %*s %*s %*s %ms\n", &path) != EOF) { 90 for (;;) {
47 if (path && strncmp(path, "@/tmp/.X11-unix/", 16) == 0) { 91 if (getline(&linebuf, &bufsz, fp) == -1) {
48 free(path); 92 if (errno)
49 fclose(fp); 93 errExit("getline");
50 return 1; 94 break;
95 }
96 // The last space-separated field in 'linebuf' is the
97 // pathname of the socket. Abstract sockets' pathnames
98 // all begin with '@/', normal ones begin with '/'.
99 char *p = strrchr(linebuf, ' ');
100 if (!p) {
101 fputs("error parsing /proc/net/unix\n", stderr);
102 exit(1);
103 }
104 if (strncmp(p+1, "@/tmp/.X11-unix/", 16) == 0) {
105 found = 1;
106 break;
51 } 107 }
52 } 108 }
53 109
54 free(path); 110 free(linebuf);
55 fclose(fp); 111 fclose(fp);
56 112 return found;
57 return 0;
58} 113}
59 114
60static int random_display_number(void) { 115static int random_display_number(void) {
@@ -84,44 +139,6 @@ static int random_display_number(void) {
84#endif 139#endif
85 140
86 141
87// Parse the DISPLAY environment variable and return a display number.
88// Returns -1 if DISPLAY is not set, or is set to anything other than :ddd.
89int x11_display(void) {
90 const char *display_str = getenv("DISPLAY");
91 char *endp;
92 unsigned long display;
93
94 if (!display_str) {
95 if (arg_debug)
96 fputs("DISPLAY is not set\n", stderr);
97 return -1;
98 }
99
100 if (display_str[0] != ':' || display_str[1] < '0' || display_str[1] > '9') {
101 if (arg_debug)
102 fprintf(stderr, "unsupported DISPLAY form '%s'\n", display_str);
103 return -1;
104 }
105
106 errno = 0;
107 display = strtoul(display_str+1, &endp, 10);
108 if (endp == display_str+1 || (*endp != '\0' && *endp != '.')) { // handling DISPLAY=:0 and also :0.0
109 if (arg_debug)
110 fprintf(stderr, "unsupported DISPLAY form '%s'\n", display_str);
111 return -1;
112 }
113 if (errno || display > (unsigned long)INT_MAX) {
114 if (arg_debug)
115 fprintf(stderr, "display number %s is outside the valid range\n",
116 display_str+1);
117 return -1;
118 }
119
120 if (arg_debug)
121 fprintf(stderr, "DISPLAY=%s parsed as %lu\n", display_str, display);
122
123 return (int)display;
124}
125 142
126void fs_x11(void) { 143void fs_x11(void) {
127#ifdef HAVE_X11 144#ifdef HAVE_X11