From 116219bea949f80242ddcf08f5ee7fd89d47f7cf Mon Sep 17 00:00:00 2001
From: Andreas Mohr <and@gmx.li>
Date: Tue, 24 Nov 2015 20:18:21 +0000
Subject: [PATCH] fix heap-use-after-free bug when accessing already freed
widget object
heap-use-after-free plus memleak hits by accessing mc listing mode
v4: address comments by mooffie and fix another memleak in this context
v3: fix list object declaration
v2: address comments by andrew_b
accessing widget object (at g_array_index loop) which was freed
already (item->quick_widget->u.input.label before at loop)
found by Clang/AddressSanitizer
ERROR: AddressSanitizer: heap-use-after-free on address 0x60800000aaa0 at pc 0x7fcaad33ef39 bp 0x7ffc752eabd0 sp 0x7ffc752eabc8
READ of size 4 at 0x60800000aaa0 thread T0
#0 0x7fcaad33ef38 in quick_dialog_skip /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/quick.c:615:33
#1 0x5e3434 in panel_listing_box /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/boxes.c:831:13
#2 0x5f5630 in change_listing_cmd /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/cmd.c:1656:17
#3 0x52f55d in midnight_execute_cmd /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/midnight.c:1113:9
#4 0x7fcaad339319 in menubar_execute /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/menu.c:341:9
#5 0x7fcaad337962 in menubar_handle_key /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/menu.c:539:13
#6 0x7fcaad3359c0 in menubar_callback /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/menu.c:597:13
#7 0x7fcaad31f5a3 in dlg_try_hotkey /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/dialog.c:450:19
#8 0x7fcaad31e950 in dlg_key_event /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/dialog.c:509:19
#9 0x7fcaad31ee12 in frontend_dlg_run /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/dialog.c:570:9
#10 0x7fcaad31eb15 in dlg_run /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/dialog.c:1267:5
#11 0x52d8dd in do_nc /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/midnight.c:1757:9
#12 0x4fb287 in main /tmp/portage/app-misc/mc-9999/work/mc-9999/src/main.c:463:21
#13 0x7fcaab72d9e3 in __libc_start_main (/lib64/libc.so.6+0x209e3)
#14 0x427248 in _start (/tmp/portage/app-misc/mc-9999/work/mc-9999/src/.libs/mc+0x427248)
0x60800000aaa0 is located 0 bytes inside of 88-byte region [0x60800000aaa0,0x60800000aaf8)
freed by thread T0 here:
#0 0x4c9a58 in __interceptor_free (/tmp/portage/app-misc/mc-9999/work/mc-9999/src/.libs/mc+0x4c9a58)
#1 0x7fcaad33e3e7 in quick_dialog_skip /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/quick.c:616:13
#2 0x5e3434 in panel_listing_box /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/boxes.c:831:13
#3 0x5f5630 in change_listing_cmd /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/cmd.c:1656:17
#4 0x52f55d in midnight_execute_cmd /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/midnight.c:1113:9
#5 0x7fcaad339319 in menubar_execute /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/menu.c:341:9
#6 0x7fcaad337962 in menubar_handle_key /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/menu.c:539:13
#7 0x7fcaad3359c0 in menubar_callback /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/menu.c:597:13
#8 0x7fcaad31f5a3 in dlg_try_hotkey /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/dialog.c:450:19
#9 0x7fcaad31e950 in dlg_key_event /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/dialog.c:509:19
#10 0x7fcaad31ee12 in frontend_dlg_run /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/dialog.c:570:9
#11 0x7fcaad31eb15 in dlg_run /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/dialog.c:1267:5
#12 0x52d8dd in do_nc /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/midnight.c:1757:9
#13 0x4fb287 in main /tmp/portage/app-misc/mc-9999/work/mc-9999/src/main.c:463:21
#14 0x7fcaab72d9e3 in __libc_start_main (/lib64/libc.so.6+0x209e3)
#15 0x427248 in _start (/tmp/portage/app-misc/mc-9999/work/mc-9999/src/.libs/mc+0x427248)
previously allocated by thread T0 here:
#0 0x4c9ef0 in calloc (/tmp/portage/app-misc/mc-9999/work/mc-9999/src/.libs/mc+0x4c9ef0)
#1 0x7fcaac65a51c in g_malloc0 (/usr/lib64/libglib-2.0.so.0+0x6651c)
#2 0x7fcaad33f02e in quick_create_labeled_input /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/quick.c:90:26
#3 0x7fcaad33b076 in quick_dialog_skip /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/quick.c:238:17
#4 0x5e3434 in panel_listing_box /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/boxes.c:831:13
#5 0x5f5630 in change_listing_cmd /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/cmd.c:1656:17
#6 0x52f55d in midnight_execute_cmd /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/midnight.c:1113:9
#7 0x7fcaad339319 in menubar_execute /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/menu.c:341:9
#8 0x7fcaad337962 in menubar_handle_key /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/menu.c:539:13
#9 0x7fcaad3359c0 in menubar_callback /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/menu.c:597:13
#10 0x7fcaad31f5a3 in dlg_try_hotkey /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/dialog.c:450:19
#11 0x7fcaad31e950 in dlg_key_event /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/dialog.c:509:19
#12 0x7fcaad31ee12 in frontend_dlg_run /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/dialog.c:570:9
#13 0x7fcaad31eb15 in dlg_run /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/dialog.c:1267:5
#14 0x52d8dd in do_nc /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/midnight.c:1757:9
#15 0x4fb287 in main /tmp/portage/app-misc/mc-9999/work/mc-9999/src/main.c:463:21
#16 0x7fcaab72d9e3 in __libc_start_main (/lib64/libc.so.6+0x209e3)
#17 0x427248 in _start (/tmp/portage/app-misc/mc-9999/work/mc-9999/src/.libs/mc+0x427248)
SUMMARY: AddressSanitizer: heap-use-after-free /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/quick.c:615:33 in quick_dialog_skip
Direct leak of 58 byte(s) in 2 object(s) allocated from:
#0 0x4c7c30 in malloc (/tmp/portage/app-misc/mc-9999/work/mc-9999/src/.libs/mc+0x4c7c30)
#1 0x7f6762da8d38 in g_malloc (/usr/lib64/libglib-2.0.so.0+0x66d38)
#2 0x7f6762dd1011 in g_strdup (/usr/lib64/libglib-2.0.so.0+0x8f011)
#3 0x7f6763a82cea in quick_dialog_skip /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/quick.c:602:63
#4 0x5e17c5 in panel_listing_box /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/boxes.c:831:13
#5 0x5f39c0 in change_listing_cmd /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/cmd.c:1656:17
#6 0x52d79d in midnight_execute_cmd /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/midnight.c:1113:9
#7 0x7f6763a7de79 in menubar_execute /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/menu.c:341:9
#8 0x7f6763a7c4c2 in menubar_handle_key /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/menu.c:539:13
#9 0x7f6763a7a520 in menubar_callback /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/menu.c:597:13
#10 0x7f6763a640e3 in dlg_try_hotkey /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/dialog.c:450:19
#11 0x7f6763a63490 in dlg_key_event /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/dialog.c:509:19
#12 0x7f6763a63952 in frontend_dlg_run /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/dialog.c:570:9
#13 0x7f6763a63655 in dlg_run /tmp/portage/app-misc/mc-9999/work/mc-9999/lib/widget/dialog.c:1267:5
#14 0x52bb1d in do_nc /tmp/portage/app-misc/mc-9999/work/mc-9999/src/filemanager/midnight.c:1757:9
#15 0x4f94b7 in main /tmp/portage/app-misc/mc-9999/work/mc-9999/src/main.c:463:21
#16 0x7f6761e7e953 in __libc_start_main (/lib64/libc.so.6+0x20953)
#17 0x427408 in _start (/tmp/portage/app-misc/mc-9999/work/mc-9999/src/.libs/mc+0x427408)
SUMMARY: AddressSanitizer: 58 byte(s) leaked in 2 allocation(s)
Signed-off-by: Andreas Mohr <and@gmx.li>
---
lib/widget/quick.c | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/lib/widget/quick.c b/lib/widget/quick.c
index a47a59c..5dbc795 100644
a
|
b
|
quick_dialog_skip (quick_dialog_t * quick_dlg, int nskip) |
181 | 181 | quick_widget_t *quick_widget; |
182 | 182 | WGroupbox *g = NULL; |
183 | 183 | WDialog *dd; |
| 184 | GList *heap_allocated_quick_widgets = NULL; |
184 | 185 | int return_val; |
185 | 186 | |
186 | 187 | len = str_term_width1 (I18N (quick_dlg->title)) + 6; |
… |
… |
quick_dialog_skip (quick_dialog_t * quick_dlg, int nskip) |
235 | 236 | *quick_widget->u.input.result = NULL; |
236 | 237 | y++; |
237 | 238 | if (quick_widget->u.input.label_location != input_label_none) |
| 239 | { |
238 | 240 | quick_create_labeled_input (widgets, &y, x, quick_widget, &width); |
| 241 | heap_allocated_quick_widgets = |
| 242 | g_list_prepend (heap_allocated_quick_widgets, quick_widget->u.input.label); |
| 243 | } |
239 | 244 | else |
240 | 245 | { |
241 | 246 | item.widget = WIDGET (quick_create_input (y, x, quick_widget)); |
… |
… |
quick_dialog_skip (quick_dialog_t * quick_dlg, int nskip) |
588 | 593 | break; |
589 | 594 | |
590 | 595 | case quick_input: |
591 | | if ((quick_widget->u.input.completion_flags & INPUT_COMPLETE_CD) != 0) |
592 | | *item->quick_widget->u.input.result = |
593 | | tilde_expand (INPUT (item->widget)->buffer); |
594 | | else |
595 | | *item->quick_widget->u.input.result = g_strdup (INPUT (item->widget)->buffer); |
| 596 | if (item->quick_widget->u.input.label_location != input_label_none) |
| 597 | { |
| 598 | if ((quick_widget->u.input.completion_flags & INPUT_COMPLETE_CD) != 0) |
| 599 | *item->quick_widget->u.input.result = |
| 600 | tilde_expand (INPUT (item->widget)->buffer); |
| 601 | else |
| 602 | *item->quick_widget->u.input.result = g_strdup (INPUT (item->widget)->buffer); |
| 603 | } |
596 | 604 | break; |
597 | 605 | |
598 | 606 | case quick_radio: |
… |
… |
quick_dialog_skip (quick_dialog_t * quick_dlg, int nskip) |
607 | 615 | dlg_destroy (dd); |
608 | 616 | |
609 | 617 | /* destroy input labels created before */ |
610 | | for (i = 0; i < widgets->len; i++) |
611 | | { |
612 | | quick_widget_item_t *item; |
613 | | |
614 | | item = &g_array_index (widgets, quick_widget_item_t, i); |
615 | | if (item->quick_widget->widget_type == quick_input) |
616 | | g_free (item->quick_widget->u.input.label); |
617 | | } |
618 | | |
| 618 | g_list_free_full (heap_allocated_quick_widgets, g_free); |
619 | 619 | g_array_free (widgets, TRUE); |
620 | 620 | |
621 | 621 | return return_val; |