audiod: Fix use after free on exit.
authorAndre Noll <maan@systemlinux.org>
Tue, 15 Jul 2014 05:04:07 +0000 (07:04 +0200)
committerAndre Noll <maan@systemlinux.org>
Tue, 15 Jul 2014 05:09:21 +0000 (07:09 +0200)
client_close() frees the ->ct structure which is used one line later
by task_reap(). valgrind spots this use after free bug and reports

==13497== Invalid read of size 4
==13497==    at 0x8059EA8: task_reap (sched.c:199)
==13497==    by 0x80542FA: close_stat_pipe (audiod.c:1082)
==13497==    by 0x8055632: clean_exit (audiod.c:1159)
==13497==    by 0x80556B6: signal_post_select (audiod.c:1018)
==13497==    by 0x8059E5F: schedule (sched.c:88)
==13497==    by 0x804D41C: main (audiod.c:1437)
==13497==  Address 0x4833c04 is 204 bytes inside a block of size 212 free'd
==13497==    at 0x4028AC0: free (vg_replace_malloc.c:468)
==13497==    by 0x80542E8: close_stat_pipe (audiod.c:1081)
==13497==    by 0x8055632: clean_exit (audiod.c:1159)
==13497==    by 0x80556B6: signal_post_select (audiod.c:1018)
==13497==    by 0x8059E5F: schedule (sched.c:88)
==13497==    by 0x804D41C: main (audiod.c:1437)

The bug was introduced recently in commit 0b43ec5d (task_register()
conversion: client task).

audiod.c

index 6b77e33..6fd101a 100644 (file)
--- a/audiod.c
+++ b/audiod.c
@@ -1078,8 +1078,8 @@ static void close_stat_pipe(void)
 {
        if (!stat_task->ct)
                return;
-       client_close(stat_task->ct);
        task_reap(&stat_task->ct->task);
+       client_close(stat_task->ct);
        stat_task->ct = NULL;
        clear_and_dump_items();
        stat_task->length_seconds = 0;