qrexec: unify service environment preparation

Always set QREXEC_AGENT_PID variable, setup SIGUSR1 handler. And do that
before starting child process to avoid race conditions.

Required for QubesOS/qubes-issues#
Fixes QubesOS/qubes-issues#1863
This commit is contained in:
Marek Marczykowski-Górecki 2016-03-21 13:23:34 +01:00
parent 7301a898a1
commit 73beddf78e
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724
3 changed files with 13 additions and 8 deletions

View File

@ -57,6 +57,15 @@ static void sigusr1_handler(int __attribute__((__unused__))x)
signal(SIGUSR1, SIG_IGN);
}
void prepare_child_env() {
char pid_s[10];
signal(SIGCHLD, sigchld_handler);
signal(SIGUSR1, sigusr1_handler);
snprintf(pid_s, sizeof(pid_s), "%d", getpid());
setenv("QREXEC_AGENT_PID", pid_s, 1);
}
int handle_handshake(libvchan_t *ctrl)
{
struct msg_header hdr;
@ -482,7 +491,6 @@ int handle_new_process_common(int type, int connect_domain, int connect_port,
libvchan_t *data_vchan;
int exit_code = 0;
pid_t pid;
char pid_s[10];
if (type != MSG_SERVICE_CONNECT) {
assert(cmdline != NULL);
@ -503,10 +511,7 @@ int handle_new_process_common(int type, int connect_domain, int connect_port,
}
handle_handshake(data_vchan);
signal(SIGCHLD, sigchld_handler);
signal(SIGUSR1, sigusr1_handler);
snprintf(pid_s, sizeof(pid_s), "%d", getpid());
setenv("QREXEC_AGENT_PID", pid_s, 1);
prepare_child_env();
/* TODO: use setresuid to allow child process to actually send the signal? */
switch (type) {

View File

@ -24,6 +24,8 @@
int handle_handshake(libvchan_t *ctrl);
void handle_vchan_error(const char *op);
void do_exec(const char *cmd);
/* call before fork() for service handling process (either end) */
void prepare_child_env();
pid_t handle_new_process(int type,
int connect_domain, int connect_port,

View File

@ -82,7 +82,6 @@ int main(int argc, char **argv)
char *abs_exec_path;
pid_t child_pid = 0;
int inpipe[2], outpipe[2];
char pid_s[10];
if (argc < 3) {
fprintf(stderr,
@ -123,8 +122,7 @@ int main(int argc, char **argv)
perror("socketpair");
exit(1);
}
snprintf(pid_s, sizeof(pid_s), "%d", getpid());
setenv("QREXEC_AGENT_PID", pid_s, 1);
prepare_child_env();
switch (child_pid = fork()) {
case -1: