Skip to content

Commit ce92bfb

Browse files
committed
Merge remote-tracking branch 'origin/pr/147'
* origin/pr/147: Check for dup2() errors and avoid FD leak Do not use a timeout if QREXEC_STARTUP_NOWAIT is set Avoid writing to an uninitialized file descriptor
2 parents 4c24dfe + a9f5e18 commit ce92bfb

File tree

1 file changed

+26
-18
lines changed

1 file changed

+26
-18
lines changed

daemon/qrexec-daemon.c

+26-18
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@ static const char default_user_keyword[] = "DEFAULT:";
111111
#define default_user_keyword_len_without_colon (sizeof(default_user_keyword)-2)
112112

113113
static int opt_quiet = 0;
114-
static int opt_direct = 0;
115114

116115
static const char *policy_program = QREXEC_POLICY_PROGRAM;
117116

@@ -262,7 +261,7 @@ static int handle_agent_hello(libvchan_t *ctrl, const char *domain_name)
262261
static void signal_handler(int sig);
263262

264263
/* do the preparatory tasks, needed before entering the main event loop */
265-
static void init(int xid)
264+
static void init(int xid, bool opt_direct)
266265
{
267266
char qrexec_error_log_name[256];
268267
int logfd;
@@ -283,19 +282,21 @@ static void init(int xid)
283282
startup_timeout = MAX_STARTUP_TIME_DEFAULT;
284283
}
285284

286-
int pipes[2];
285+
int pipes[2] = { -1, -1 };
286+
bool have_timeout = getenv("QREXEC_STARTUP_NOWAIT") == NULL;
287287
if (!opt_direct) {
288-
if (pipe2(pipes, O_CLOEXEC))
288+
if (have_timeout && pipe2(pipes, O_CLOEXEC))
289289
err(1, "pipe2()");
290290
switch (pid=fork()) {
291291
case -1:
292292
PERROR("fork");
293293
exit(1);
294294
case 0:
295-
close(pipes[0]);
295+
if (have_timeout)
296+
close(pipes[0]);
296297
break;
297298
default:
298-
if (getenv("QREXEC_STARTUP_NOWAIT"))
299+
if (!have_timeout)
299300
exit(0);
300301
close(pipes[1]);
301302
if (!opt_quiet)
@@ -353,8 +354,10 @@ static void init(int xid)
353354
exit(1);
354355
}
355356

356-
dup2(logfd, 1);
357-
dup2(logfd, 2);
357+
if (dup2(logfd, 1) != 1 || dup2(logfd, 2) != 2)
358+
err(1, "dup2()");
359+
if (logfd > 2)
360+
close(logfd);
358361

359362
if (setsid() < 0) {
360363
PERROR("setsid()");
@@ -363,18 +366,22 @@ static void init(int xid)
363366
}
364367

365368
int wait_fd;
366-
vchan = libvchan_client_init_async(xid, VCHAN_BASE_PORT, &wait_fd);
369+
if (have_timeout) {
370+
vchan = libvchan_client_init_async(xid, VCHAN_BASE_PORT, &wait_fd);
371+
if (vchan != NULL && qubes_wait_for_vchan_connection_with_timeout(
372+
vchan, wait_fd, false, startup_timeout) < 0) {
373+
if (!opt_direct && write(pipes[1], "\1", 1)) {}
374+
LOG(ERROR, "qrexec connection timeout");
375+
exit(3);
376+
}
377+
} else {
378+
/* No timeout in this case */
379+
vchan = libvchan_client_init(xid, VCHAN_BASE_PORT);
380+
}
367381
if (!vchan) {
368382
LOG(ERROR, "Cannot create data vchan connection");
369383
exit(3);
370384
}
371-
if (qubes_wait_for_vchan_connection_with_timeout(
372-
vchan, wait_fd, false, startup_timeout) < 0) {
373-
if (write(pipes[1], "\1", 1)) {}
374-
LOG(ERROR, "qrexec connection timeout");
375-
exit(3);
376-
}
377-
378385
protocol_version = handle_agent_hello(vchan, remote_domain_name);
379386
if (protocol_version < 0) {
380387
exit(1);
@@ -417,7 +424,7 @@ static void init(int xid)
417424
err(1, "sigaction");
418425
if (sigaction(SIGTERM, &sigterm_action, NULL))
419426
err(1, "sigaction");
420-
if (!opt_direct) {
427+
if (have_timeout && !opt_direct) {
421428
if (write(pipes[1], "", 1) != 1)
422429
err(1, "write(pipe)");
423430
close(pipes[1]);
@@ -1528,6 +1535,7 @@ int main(int argc, char **argv)
15281535
{
15291536
int i, opt;
15301537
sigset_t selectmask;
1538+
bool opt_direct = false;
15311539

15321540
{
15331541
int null_fd = open("/dev/null", O_RDONLY|O_NOCTTY);
@@ -1571,7 +1579,7 @@ int main(int argc, char **argv)
15711579
remote_domain_name = argv[optind+1];
15721580
if (argc - optind >= 3)
15731581
default_user = argv[optind+2];
1574-
init(remote_domain_id);
1582+
init(remote_domain_id, opt_direct);
15751583

15761584
sigemptyset(&selectmask);
15771585
sigaddset(&selectmask, SIGCHLD);

0 commit comments

Comments
 (0)