Sfoglia il codice sorgente

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
Marek Marczykowski-Górecki 8 anni fa
parent
commit
73beddf78e
3 ha cambiato i file con 13 aggiunte e 8 eliminazioni
  1. 10 5
      qrexec/qrexec-agent-data.c
  2. 2 0
      qrexec/qrexec-agent.h
  3. 1 3
      qrexec/qrexec-client-vm.c

+ 10 - 5
qrexec/qrexec-agent-data.c

@@ -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) {

+ 2 - 0
qrexec/qrexec-agent.h

@@ -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,

+ 1 - 3
qrexec/qrexec-client-vm.c

@@ -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: