From 3096b03aba1f0ca0e7a5a264975951667a72ce6d Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Mon, 12 Nov 2012 13:52:50 +0100 Subject: [PATCH] client: Fix double free bug in interactive mode. This can easily be reproduced: Enter "select" and type "" twice to complete on all moods and playlists, then hit enter to trigger the bug. On newer glibc-based systems para_client aborts due to the double free, and valgrind outputs the following: ==10084== Invalid read of size 4 ==10084== at 0x804CA24: free_argv (string.c:813) ==10084== by 0x804E86A: client_disconnect (client_common.c:46) ==10084== by 0x804BF24: client_i9e_line_handler (client.c:448) ==10084== by 0x8050140: i9e_line_handler (interactive.c:245) ==10084== by 0x428DCF8: rl_callback_read_char (callback.c:217) ==10084== by 0x8050264: i9e_post_select (interactive.c:265) ==10084== by 0x804D183: schedule (sched.c:70) ==10084== by 0x804A0C2: main (client.c:502) ==10084== Address 0x452a928 is 0 bytes inside a block of size 8 free'd ==10084== at 0x4028BDC: free (vg_replace_malloc.c:446) ==10084== by 0x804E86A: client_disconnect (client_common.c:46) ==10084== by 0x804B6B8: execute_client_command (client.c:118) ==10084== by 0x804BA5E: select_completer (client.c:387) ==10084== by 0x80503BF: create_matches (interactive.c:100) ==10084== by 0x80504D0: completion_generator (interactive.c:134) ==10084== by 0x4280B1F: rl_completion_matches (complete.c:1992) ==10084== by 0x4280BBD: gen_completion_matches (complete.c:1062) ==10084== by 0x4281539: rl_complete_internal (complete.c:1830) ==10084== by 0x42819C1: rl_complete (complete.c:401) ==10084== by 0x4278E9C: _rl_dispatch_subseq (readline.c:774) ==10084== by 0x427917E: _rl_dispatch (readline.c:724) The bug happens since we did not set the ->features pointer of struct client task to NULL after the feature list was freed. The fix is trivial. --- client_common.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client_common.c b/client_common.c index 78b232db..d9ed11f4 100644 --- a/client_common.c +++ b/client_common.c @@ -44,6 +44,7 @@ void client_disconnect(struct client_task *ct) if (ct->scc.fd >= 0) close(ct->scc.fd); free_argv(ct->features); + ct->features = NULL; sc_free(ct->scc.recv); ct->scc.recv = NULL; sc_free(ct->scc.send); -- 2.30.2