aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar Aleksey Manevich <manevich.aleksey@gmail.com>2016-08-12 06:10:36 +0300
committerLibravatar Aleksey Manevich <manevich.aleksey@gmail.com>2016-08-12 08:42:13 +0300
commit6243b04031e0d6acad08ad808ebc0a233d1852c3 (patch)
tree96806539cb88f07a54808ceda87c7d1a4d5c0bd3 /src
parentBusybox workaround (diff)
downloadfirejail-6243b04031e0d6acad08ad808ebc0a233d1852c3.tar.gz
firejail-6243b04031e0d6acad08ad808ebc0a233d1852c3.tar.zst
firejail-6243b04031e0d6acad08ad808ebc0a233d1852c3.zip
--x11=xephyr rewrite
Diffstat (limited to 'src')
-rw-r--r--src/firejail/x11.c147
1 files changed, 103 insertions, 44 deletions
diff --git a/src/firejail/x11.c b/src/firejail/x11.c
index 090ff6f3b..9e818ab67 100644
--- a/src/firejail/x11.c
+++ b/src/firejail/x11.c
@@ -158,16 +158,15 @@ void fs_x11(void) {
158 158
159 159
160#ifdef HAVE_X11 160#ifdef HAVE_X11
161//$ Xephyr -ac -br -terminate -screen 800x600 :22 & 161//$ Xephyr -ac -br -noreset -screen 800x600 :22 &
162//$ DISPLAY=:22 firejail --net=eth0 --blacklist=/tmp/.X11-unix/x0 firefox 162//$ DISPLAY=:22 firejail --net=eth0 --blacklist=/tmp/.X11-unix/x0 firefox
163void x11_start_xephyr(int argc, char **argv) { 163void x11_start_xephyr(int argc, char **argv) {
164 EUID_ASSERT(); 164 EUID_ASSERT();
165 int i; 165 size_t i;
166 struct stat s; 166 struct stat s;
167 pid_t client = 0; 167 pid_t client = 0;
168 pid_t server = 0; 168 pid_t server = 0;
169 169
170
171 setenv("FIREJAIL_X11", "yes", 1); 170 setenv("FIREJAIL_X11", "yes", 1);
172 171
173 // unfortunately, xephyr does a number of weird things when started by root user!!! 172 // unfortunately, xephyr does a number of weird things when started by root user!!!
@@ -186,29 +185,78 @@ void x11_start_xephyr(int argc, char **argv) {
186 } 185 }
187 186
188 int display = random_display_number(); 187 int display = random_display_number();
188 char *display_str;
189 if (asprintf(&display_str, ":%d", display) == -1)
190 errExit("asprintf");
189 191
190 // start xephyr 192 assert(xephyr_screen);
191 char *cmd1; 193 char *server_argv[256] = { "Xephyr", "-ac", "-br", "-noreset", "-screen", xephyr_screen }; // rest initialyzed to NULL
194 unsigned pos = 0;
195 while (server_argv[pos] != NULL) pos++;
192 if (checkcfg(CFG_XEPHYR_WINDOW_TITLE)) { 196 if (checkcfg(CFG_XEPHYR_WINDOW_TITLE)) {
193 if (asprintf(&cmd1, "Xephyr -ac -br -title \"firejail x11 sandbox\" -terminate -screen %s %s :%d", xephyr_screen, xephyr_extra_params, display) == -1) 197 server_argv[pos++] = "-title";
194 errExit("asprintf"); 198 server_argv[pos++] = "firejail x11 sandbox";
195 }
196 else {
197 if (asprintf(&cmd1, "Xephyr -ac -br -terminate -screen %s %s :%d", xephyr_screen, xephyr_extra_params, display) == -1)
198 errExit("asprintf");
199 } 199 }
200 200
201 int len = 50; // DISPLAY... 201 assert(xephyr_extra_params); // should be "" if empty
202 for (i = 0; i < argc; i++) { 202
203 len += strlen(argv[i]) + 1; // + ' ' 203 // parse xephyr_extra_params
204 // very basic quoting support
205 char *temp = strdup(xephyr_extra_params);
206 if (xephyr_extra_params != "") {
207 if (!temp)
208 errExit("strdup");
209 bool dquote = false;
210 bool squote = false;
211 for (i = 0; i < strlen(xephyr_extra_params); i++) {
212 if (temp[i] == '\"') {
213 dquote = !dquote;
214 if (dquote) temp[i] = '\0'; // replace closing quote by \0
215 }
216 if (temp[i] == '\'') {
217 squote = !squote;
218 if (squote) temp[i] = '\0'; // replace closing quote by \0
219 }
220 if (!dquote && !squote && temp[i] == ' ') temp[i] = '\0';
221 if (dquote && squote) {
222 fprintf(stderr, "Error: mixed quoting found while parsing xephyr_extra_params\n");
223 exit(1);
224 }
225 }
226 if (dquote) {
227 fprintf(stderr, "Error: unclosed quote found while parsing xephyr_extra_params\n");
228 exit(1);
229 }
230
231 for (i = 0; i < strlen(xephyr_extra_params)-1; i++) {
232 if (pos >= (sizeof(server_argv)/sizeof(*server_argv))) {
233 fprintf(stderr, "Error: arg count limit exceeded while parsing xephyr_extra_params\n");
234 exit(1);
235 }
236 if (temp[i] == '\0' && (temp[i+1] == '\"' || temp[i+1] == '\'')) server_argv[pos++] = temp + i + 2;
237 else if (temp[i] == '\0' && temp[i+1] != '\0') server_argv[pos++] = temp + i + 1;
238 }
204 } 239 }
205 240
206 char *cmd2 = malloc(len + 1); // + '\0' 241 server_argv[pos++] = display_str;
207 if (!cmd2) 242 server_argv[pos++] = NULL;
208 errExit("malloc"); 243
244 assert(pos < (sizeof(server_argv)/sizeof(*server_argv))); // no overrun
245 assert(server_argv[pos-1] == NULL); // last element is null
209 246
210 sprintf(cmd2, "DISPLAY=:%d ", display); 247 if (arg_debug) {
211 char *ptr = cmd2 + strlen(cmd2); 248 size_t i = 0;
249 printf("xephyr server:");
250 while (server_argv[i]!=NULL) {
251 printf(" \"%s\"", server_argv[i]);
252 i++;
253 }
254 putchar('\n');
255 }
256
257 // remove --x11 arg
258 char *client_argv[argc+2];
259 size_t j = 0;
212 for (i = 0; i < argc; i++) { 260 for (i = 0; i < argc; i++) {
213 if (strcmp(argv[i], "--x11") == 0) 261 if (strcmp(argv[i], "--x11") == 0)
214 continue; 262 continue;
@@ -216,14 +264,23 @@ void x11_start_xephyr(int argc, char **argv) {
216 continue; 264 continue;
217 if (strcmp(argv[i], "--x11=xephyr") == 0) 265 if (strcmp(argv[i], "--x11=xephyr") == 0)
218 continue; 266 continue;
219 ptr += sprintf(ptr, "%s ", argv[i]); 267 client_argv[j] = argv[i];
268 j++;
269 }
270 client_argv[j] = NULL;
271
272 assert(j < argc+2); // no overrun
273
274 if (arg_debug) {
275 size_t i = 0;
276 printf("xephyr client:");
277 while (client_argv[i]!=NULL) {
278 printf(" \"%s\"", client_argv[i]);
279 i++;
280 }
281 putchar('\n');
220 } 282 }
221 if (arg_debug)
222 printf("xephyr server: %s\n", cmd1);
223 if (arg_debug)
224 printf("xephyr client: %s\n", cmd2);
225 283
226 signal(SIGHUP,SIG_IGN); // fix sleep(1) below
227 server = fork(); 284 server = fork();
228 if (server < 0) 285 if (server < 0)
229 errExit("fork"); 286 errExit("fork");
@@ -231,17 +288,14 @@ void x11_start_xephyr(int argc, char **argv) {
231 if (arg_debug) 288 if (arg_debug)
232 printf("Starting xephyr...\n"); 289 printf("Starting xephyr...\n");
233 290
234 char *a[4]; 291 execvp(server_argv[0], server_argv);
235 a[0] = "/bin/bash";
236 a[1] = "-c";
237 a[2] = cmd1;
238 a[3] = NULL;
239
240 execvp(a[0], a);
241 perror("execvp"); 292 perror("execvp");
242 exit(1); 293 exit(1);
243 } 294 }
244 295
296 if (arg_debug)
297 printf("xephyr server pid %d\n", server);
298
245 // check X11 socket 299 // check X11 socket
246 char *fname; 300 char *fname;
247 if (asprintf(&fname, "/tmp/.X11-unix/X%d", display) == -1) 301 if (asprintf(&fname, "/tmp/.X11-unix/X%d", display) == -1)
@@ -259,7 +313,6 @@ void x11_start_xephyr(int argc, char **argv) {
259 exit(1); 313 exit(1);
260 } 314 }
261 free(fname); 315 free(fname);
262 sleep(1);
263 316
264 if (arg_debug) { 317 if (arg_debug) {
265 printf("X11 sockets: "); fflush(0); 318 printf("X11 sockets: "); fflush(0);
@@ -267,26 +320,32 @@ void x11_start_xephyr(int argc, char **argv) {
267 (void) rv; 320 (void) rv;
268 } 321 }
269 322
323 setenv("DISPLAY", display_str, 1);
270 // run attach command 324 // run attach command
271 client = fork(); 325 client = fork();
272 if (client < 0) 326 if (client < 0)
273 errExit("fork"); 327 errExit("fork");
274 if (client == 0) { 328 if (client == 0) {
275 printf("\n*** Attaching to Xephyr display %d ***\n\n", display); 329 printf("\n*** Attaching to Xephyr display %d ***\n\n", display);
276 char *a[4]; 330
277 a[0] = "/bin/bash"; 331 execvp(client_argv[0], client_argv);
278 a[1] = "-c";
279 a[2] = cmd2;
280 a[3] = NULL;
281
282 execvp(a[0], a);
283 perror("execvp"); 332 perror("execvp");
284 exit(1); 333 exit(1);
285 } 334 }
286 sleep(1); 335
287 336 // cleanup
288 if (!arg_quiet) 337 free(display_str);
289 printf("Xephyr server pid %d, client pid %d\n", server, client); 338 free(temp);
339
340 // wait for either server or client termination
341 pid_t pid = wait();
342
343 // see which process terminated and kill other
344 if (pid == server) {
345 kill(client, SIGTERM);
346 } else if (pid == client) {
347 kill(server, SIGTERM);
348 }
290 349
291 exit(0); 350 exit(0);
292} 351}