audiod: Avoid segfault on exit.
authorAndre Noll <maan@systemlinux.org>
Fri, 4 Apr 2014 12:23:44 +0000 (14:23 +0200)
committerAndre Noll <maan@systemlinux.org>
Fri, 4 Apr 2014 12:37:41 +0000 (14:37 +0200)
When para_audiod terminates, it calls clean_exit() which closes
all slots unconditionally, regardless of whether they are in use.
This may lead to a segfault due to an invalid read:

==25253== Invalid read of size 4
==25253==    at 0x40EBEA: close_slot (audiod.c:443)
==25253==    by 0x40FCE8: clean_exit (audiod.c:1163)
==25253==    by 0x40FD7D: signal_post_select (audiod.c:1014)
==25253==    by 0x41490A: schedule (sched.c:65)
==25253==    by 0x406BC3: main (audiod.c:1436)
==25253==  Address 0x5c19d8 is not stack'd, malloc'd or (recently) free'd

This bug was introduced 9 month ago in commit eec23a69 (audiod:
Fix memory leak on exit: close slots). Fix it by calling
close_unused_slots(). This also simplifies clean_exit() a bit.

audiod.c

index d815c4a..a8f4018 100644 (file)
--- a/audiod.c
+++ b/audiod.c
@@ -1153,13 +1153,10 @@ static void close_unused_slots(void)
  */
 void __noreturn clean_exit(int status, const char *msg)
 {
-       int i;
-
        if (socket_name)
                unlink(socket_name);
        close_stat_pipe();
-       FOR_EACH_SLOT(i)
-               close_slot(i);
+       close_unused_slots();
        audiod_cmdline_parser_free(&conf);
        close_stat_clients();
        PARA_EMERG_LOG("%s\n", msg);