26
26
#include <sys/un.h>
27
27
#include <stdio.h>
28
28
#include <stdlib.h>
29
+ #include <stdbool.h>
29
30
#include <signal.h>
30
31
#include <unistd.h>
32
+ #include <stddef.h>
31
33
#include <errno.h>
32
34
#include <err.h>
33
35
#include <sys/wait.h>
@@ -78,12 +80,7 @@ static int meminfo_write_started = 0;
78
80
79
81
static void handle_server_exec_request_do (int type , int connect_domain , int connect_port , char * cmdline );
80
82
81
- static _Noreturn void no_colon_in_cmd (void )
82
- {
83
- fprintf (stderr ,
84
- "cmdline is supposed to be in user:command form\n" );
85
- exit (1 );
86
- }
83
+ const bool qrexec_is_fork_server = false;
87
84
88
85
#ifdef HAVE_PAM
89
86
static int pam_conv_callback (int num_msg , const struct pam_message * * msg ,
@@ -118,7 +115,6 @@ static struct pam_conv conv = {
118
115
NULL
119
116
};
120
117
#endif
121
-
122
118
/* Start program requested by dom0 in already prepared process
123
119
* (stdin/stdout/stderr already set, etc)
124
120
* Called in two cases:
@@ -136,9 +132,8 @@ static struct pam_conv conv = {
136
132
* If dom0 sends overly long cmd, it will probably crash qrexec-agent (unless
137
133
* process can allocate up to 4GB on both stack and heap), sorry.
138
134
*/
139
- _Noreturn void do_exec (char * cmd )
135
+ _Noreturn void do_exec (char * cmd , const char * user )
140
136
{
141
- char * realcmd = strchr (cmd , ':' ), * user ;
142
137
#ifdef HAVE_PAM
143
138
int retval , status ;
144
139
pam_handle_t * pamh = NULL ;
@@ -151,14 +146,9 @@ _Noreturn void do_exec(char *cmd)
151
146
char * shell_basename ;
152
147
#endif
153
148
154
- if (!realcmd )
155
- no_colon_in_cmd ();
156
- /* mark end of username and move to command */
157
- user = strndup (cmd ,(size_t )(realcmd - cmd ));
158
- realcmd ++ ;
159
149
/* ignore "nogui:" prefix in linux agent */
160
- if (strncmp (realcmd , NOGUI_CMD_PREFIX , NOGUI_CMD_PREFIX_LEN ) == 0 )
161
- realcmd += NOGUI_CMD_PREFIX_LEN ;
150
+ if (strncmp (cmd , NOGUI_CMD_PREFIX , NOGUI_CMD_PREFIX_LEN ) == 0 )
151
+ cmd += NOGUI_CMD_PREFIX_LEN ;
162
152
163
153
signal (SIGCHLD , SIG_DFL );
164
154
signal (SIGPIPE , SIG_DFL );
@@ -258,10 +248,10 @@ _Noreturn void do_exec(char *cmd)
258
248
warn ("chdir(%s)" , pw -> pw_dir );
259
249
260
250
/* call QUBESRPC if requested */
261
- exec_qubes_rpc_if_requested (realcmd , env );
251
+ exec_qubes_rpc_if_requested (cmd , env );
262
252
263
253
/* otherwise exec shell */
264
- execle (pw -> pw_shell , arg0 , "-c" , realcmd , (char * )NULL , env );
254
+ execle (pw -> pw_shell , arg0 , "-c" , cmd , (char * )NULL , env );
265
255
exit (127 );
266
256
default :
267
257
/* parent */
@@ -296,10 +286,10 @@ _Noreturn void do_exec(char *cmd)
296
286
exit (1 );
297
287
#else
298
288
/* call QUBESRPC if requested */
299
- exec_qubes_rpc_if_requested (realcmd , environ );
289
+ exec_qubes_rpc_if_requested (cmd , environ );
300
290
301
291
/* otherwise exec shell */
302
- execl ("/bin/su" , "su" , "-" , user , "-c" , realcmd , NULL );
292
+ execl ("/bin/su" , "su" , "-" , user , "-c" , cmd , NULL );
303
293
perror ("execl" );
304
294
exit (1 );
305
295
#endif
@@ -380,7 +370,7 @@ static void wake_meminfo_writer(void)
380
370
/* wake meminfo-writer only once */
381
371
return ;
382
372
383
- f = fopen (MEMINFO_WRITER_PIDFILE , "r " );
373
+ f = fopen (MEMINFO_WRITER_PIDFILE , "re " );
384
374
if (f == NULL ) {
385
375
/* no meminfo-writer found, ignoring */
386
376
return ;
@@ -407,10 +397,10 @@ static int try_fork_server(int type, int connect_domain, int connect_port,
407
397
char * cmdline , size_t cmdline_len ) {
408
398
char * colon ;
409
399
char * fork_server_socket_path ;
410
- int s ;
400
+ int s = -1 ;
411
401
struct sockaddr_un remote ;
412
402
struct qrexec_cmd_info info ;
413
- if (cmdline_len > ( 1ULL << 20 ) )
403
+ if (cmdline_len > MAX_QREXEC_CMD_LEN )
414
404
return -1 ;
415
405
char * username = malloc (cmdline_len );
416
406
if (!username ) {
@@ -420,16 +410,14 @@ static int try_fork_server(int type, int connect_domain, int connect_port,
420
410
memcpy (username , cmdline , cmdline_len );
421
411
colon = strchr (username , ':' );
422
412
if (!colon )
423
- return -1 ;
413
+ goto fail ;
424
414
* colon = '\0' ;
425
415
426
416
if (asprintf (& fork_server_socket_path , QREXEC_FORK_SERVER_SOCKET , username ) < 0 ) {
427
417
fprintf (stderr , "Memory allocation failed\n" );
428
- free (username );
429
- return -1 ;
418
+ goto fail ;
430
419
}
431
420
432
- _Static_assert (sizeof (remote .sun_path ) > 64 , "bad size of sun_path" );
433
421
remote .sun_path [sizeof (remote .sun_path ) - 1 ] = '\0' ;
434
422
remote .sun_family = AF_UNIX ;
435
423
strncpy (remote .sun_path , fork_server_socket_path ,
@@ -438,42 +426,39 @@ static int try_fork_server(int type, int connect_domain, int connect_port,
438
426
439
427
if ((s = socket (AF_UNIX , SOCK_STREAM , 0 )) == -1 ) {
440
428
perror ("socket" );
441
- free (username );
442
- return -1 ;
429
+ goto fail ;
443
430
}
444
431
size_t len = strlen (remote .sun_path ) + sizeof (remote .sun_family );
445
432
if (connect (s , (struct sockaddr * ) & remote , (socklen_t )len ) == -1 ) {
446
433
if (errno != ECONNREFUSED && errno != ENOENT )
447
434
perror ("connect" );
448
- close (s );
449
- free (username );
450
- return -1 ;
435
+ goto fail ;
451
436
}
452
437
453
438
memset (& info , 0 , sizeof info );
454
439
info .type = type ;
455
440
info .connect_domain = connect_domain ;
456
441
info .connect_port = connect_port ;
457
442
size_t username_len = strlen (username );
458
- assert (username_len < SIZE_MAX );
459
443
assert (cmdline_len <= INT_MAX );
460
444
assert (cmdline_len > username_len );
461
445
info .cmdline_len = (int )(cmdline_len - (username_len + 1 ));
462
446
if (!write_all (s , & info , sizeof (info ))) {
463
447
perror ("write" );
464
- close (s );
465
- free (username );
466
- return -1 ;
448
+ goto fail ;
467
449
}
468
- free (username );
469
- username = NULL ;
470
450
if (!write_all (s , colon + 1 , info .cmdline_len )) {
471
451
perror ("write" );
472
- close (s );
473
- return -1 ;
452
+ goto fail ;
474
453
}
475
454
455
+ free (username );
476
456
return s ;
457
+ fail :
458
+ if (s >= 0 )
459
+ close (s );
460
+ free (username );
461
+ return -1 ;
477
462
}
478
463
479
464
0 commit comments