]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - server.c
[net]: Fix buffer overflow in send_cred_buffer().
[paraslash.git] / server.c
index 9187b63fa6ae20aa525fa435010f1675b1458b0d..1e4caf08c90d0e04233a987f6e520e19850c20c5 100644 (file)
--- a/server.c
+++ b/server.c
@@ -300,6 +300,9 @@ static void signal_post_select(struct sched *s, struct task *t)
                PARA_EMERG_LOG("terminating on signal %d\n", st->signum);
 genocide:
                kill(0, SIGTERM);
+               free(mmd->afd.afhi.chunk_table);
+               free(mmd->afd.afhi.info_string);
+               close_listed_fds();
                mutex_destroy(mmd_mutex);
                shm_detach(mmd);
                exit(EXIT_FAILURE);
@@ -328,8 +331,6 @@ static void init_signal_task(void)
                goto err;
        if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
                goto err;
-       if (signal(SIGUSR1, SIG_IGN) == SIG_ERR)
-               goto err;
        add_close_on_fork_list(st->fd);
        register_task(&st->task);
        return;
@@ -469,6 +470,12 @@ static int init_afs(void)
        return afs_server_socket[0];
 }
 
+__noreturn static void tmp_sigchld_handler(__a_unused int s)
+{
+       PARA_EMERG_LOG("caught early SIGCHLD\n");
+       exit(EXIT_FAILURE);
+}
+
 static void server_init(int argc, char **argv)
 {
        struct server_cmdline_parser_params params = {
@@ -499,6 +506,27 @@ static void server_init(int argc, char **argv)
                daemonize();
        PARA_NOTICE_LOG("initializing audio format handlers\n");
        afh_init();
+
+       /*
+        * Although afs uses its own signal handling we must ignore SIGUSR1
+        * _before_ the afs child process gets born by init_afs() below.  It's
+        * racy to do this in the child because the parent might send SIGUSR1
+        * before the child gets a chance to ignore this signal -- only the
+        * good die young.
+        */
+       if (signal(SIGUSR1, SIG_IGN) == SIG_ERR) {
+               PARA_EMERG_LOG("failed to ignore SIGUSR1\n");
+               exit(EXIT_FAILURE);
+       }
+       /*
+        * We have to install a SIGCHLD handler before the afs process is being
+        * forked off. Otherwise, para_server does not notice if afs dies before
+        * the SIGCHLD handler has been installed by init_signal_task() below.
+        */
+       if (signal(SIGCHLD, tmp_sigchld_handler) == SIG_ERR) {
+               PARA_EMERG_LOG("failed to install temporary SIGCHLD handler\n");
+               exit(EXIT_FAILURE);
+       }
        PARA_NOTICE_LOG("initializing the audio file selector\n");
        afs_socket = init_afs();
        init_signal_task();