]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - afs.c
Fix a use-after-free bug in para_server.
[paraslash.git] / afs.c
diff --git a/afs.c b/afs.c
index 48faeb17fdd153c735105a80a67aa27b1bd216e3..3d0d2d77c4b24ac712f4ebc4d3bfff058414fb55 100644 (file)
--- a/afs.c
+++ b/afs.c
@@ -75,6 +75,8 @@ struct command_task {
        struct task task;
 };
 
+extern struct misc_meta_data *mmd;
+
 static int server_socket;
 static struct command_task command_task_struct;
 static struct signal_task signal_task_struct;
@@ -536,10 +538,17 @@ static int activate_mood_or_playlist(char *arg, int *num_admissible)
        current_play_mode = mode;
        if (arg != current_mop) {
                free(current_mop);
-               if (arg)
+               if (arg) {
                        current_mop = para_strdup(arg);
-               else
+                       mmd_lock();
+                       strcpy(mmd->afs_mode_string, arg); /* FIXME: check length */
+                       mmd_unlock();
+               } else {
+                       mmd_lock();
+                       strcpy(mmd->afs_mode_string, "dummy");
+                       mmd_unlock();
                        current_mop = NULL;
+               }
        }
        return 1;
 }
@@ -675,12 +684,12 @@ static int open_afs_tables(void)
                        continue;
                PARA_ERROR_LOG("%s init: %s\n", afs_tables[i].name,
                        PARA_STRERROR(-ret));
+               break;
        }
        if (ret >= 0)
                return ret;
-       do
-               afs_tables[i].close();
-       while (i--);
+       while (i)
+               afs_tables[--i].close();
        return ret;
 }
 
@@ -700,6 +709,9 @@ static void signal_pre_select(struct sched *s, struct task *t)
 static void signal_post_select(struct sched *s, struct task *t)
 {
        struct signal_task *st = t->private_data;
+       t->ret = -E_AFS_PARENT_DIED;
+       if (getppid() == 1)
+               goto err;
        t->ret = 1;
        if (!FD_ISSET(st->fd, &s->rfds))
                return;
@@ -710,10 +722,14 @@ static void signal_post_select(struct sched *s, struct task *t)
        if (st->signum == SIGHUP) {
                close_afs_tables();
                t->ret = open_afs_tables();
+               /* FIXME: Restore current mood or playlist */
+               if (t->ret < 0)
+                       goto err;
                return;
        }
-       PARA_NOTICE_LOG("caught signal %d\n", st->signum);
        t->ret = -E_AFS_SIGNAL;
+err:
+       PARA_NOTICE_LOG("%s\n", PARA_STRERROR(-t->ret));
        unregister_tasks();
 }