Skip to content

Use-after-free when renaming file

Description

It's possible for the rename-file dialog to have its filename freed between running the dialog and pressing the Rename button. This results in a use-after-free when running with ASan.

I initially triggered the bug by performing steps like this, but I am unable to reliably reproduce the issue this way:

  1. File > Create Document > Empty File
  2. Click Create
  3. F2 to rename the file
  4. Rename the file and press the Rename button

I can, however, reliably reproduce the issue with these more convoluted steps:

  1. File > Create Document > Empty File
  2. Click Create
  3. F2 to rename the file
  4. Right-click on the file and select Rename to open another rename dialog
  5. In one of the dialogs, change the name to foo and press Rename
  6. In the remaining dialog, press Rename to trigger the use-after-free

Debugging

ERROR: AddressSanitizer: heap-use-after-free on address 0x502000b6ebf0 at pc 0x5555559a2a20 bp 0x7fffffffce90 sp 0x7fffffffc650
READ of size 1 at 0x502000b6ebf0 thread T0
    #0 0x5555559a2a1f in strcmp.part.0 (/usr/local/bin/thunar+0x44ea1f)
    #1 0x555555b2c676 in thunar_dialogs_show_rename_file /home/s/code/thunar/thunar/thunar-dialogs.c:370:11
    #2 0x555555aa6d57 in thunar_application_rename_file /home/s/code/thunar/thunar/thunar-application.c:1938:9
    #3 0x555555a987e5 in thunar_action_manager_action_rename /home/s/code/thunar/thunar/thunar-action-manager.c:2442:7
    #4 0x7ffff72865a0  (/usr/lib/libgtk-3.so.0+0x865a0)
    #5 0x7ffff7a426bf in g_closure_invoke (/usr/lib/libgobject-2.0.so.0+0x146bf)
    #6 0x7ffff7a70a35  (/usr/lib/libgobject-2.0.so.0+0x42a35)
    #7 0x7ffff7a61334  (/usr/lib/libgobject-2.0.so.0+0x33334)
    #8 0x7ffff7a61c76 in g_signal_emit_valist (/usr/lib/libgobject-2.0.so.0+0x33c76)
    #9 0x7ffff7a61d33 in g_signal_emit (/usr/lib/libgobject-2.0.so.0+0x33d33)
    #10 0x7ffff72968fb in gtk_accel_group_activate (/usr/lib/libgtk-3.so.0+0x968fb)
    #11 0x7ffff7297b5d in gtk_accel_groups_activate (/usr/lib/libgtk-3.so.0+0x97b5d)
    #12 0x7ffff756621a in gtk_window_activate_key (/usr/lib/libgtk-3.so.0+0x36621a)
    #13 0x7ffff7566695  (/usr/lib/libgtk-3.so.0+0x366695)
    #14 0x7ffff728c6cc  (/usr/lib/libgtk-3.so.0+0x8c6cc)
    #15 0x7ffff7a426bf in g_closure_invoke (/usr/lib/libgobject-2.0.so.0+0x146bf)
    #16 0x7ffff7a710e9  (/usr/lib/libgobject-2.0.so.0+0x430e9)
    #17 0x7ffff7a61334  (/usr/lib/libgobject-2.0.so.0+0x33334)
    #18 0x7ffff7a61c76 in g_signal_emit_valist (/usr/lib/libgobject-2.0.so.0+0x33c76)
    #19 0x7ffff7a61d33 in g_signal_emit (/usr/lib/libgobject-2.0.so.0+0x33d33)
    #20 0x7ffff7554cd4  (/usr/lib/libgtk-3.so.0+0x354cd4)
    #21 0x7ffff73eed29  (/usr/lib/libgtk-3.so.0+0x1eed29)
    #22 0x7ffff73ef796 in gtk_main_do_event (/usr/lib/libgtk-3.so.0+0x1ef796)
    #23 0x7ffff7d0fb76  (/usr/lib/libgdk-3.so.0+0x33b76)
    #24 0x7ffff7d68437  (/usr/lib/libgdk-3.so.0+0x8c437)
    #25 0x7ffff6f34f68  (/usr/lib/libglib-2.0.so.0+0x59f68)
    #26 0x7ffff6f933a6  (/usr/lib/libglib-2.0.so.0+0xb83a6)
    #27 0x7ffff6f33161 in g_main_context_iteration (/usr/lib/libglib-2.0.so.0+0x58161)
    #28 0x7ffff7106b65 in g_application_run (/usr/lib/libgio-2.0.so.0+0xdfb65)
    #29 0x555555a6303b in main /home/s/code/thunar/thunar/main.c:86:3
    #30 0x7ffff6d1eccf  (/usr/lib/libc.so.6+0x25ccf)
    #31 0x7ffff6d1ed89 in __libc_start_main (/usr/lib/libc.so.6+0x25d89)
    #32 0x5555558ed584 in _start (/usr/local/bin/thunar+0x399584)

0x502000b6ebf0 is located 0 bytes inside of 15-byte region [0x502000b6ebf0,0x502000b6ebff)
freed by thread T0 here:
    #0 0x5555559db732 in free.part.0 (/usr/local/bin/thunar+0x487732)
    #1 0x555555b5f28c in thunar_file_info_clear /home/s/code/thunar/thunar/thunar-file.c:908:3
    #2 0x555555b5d8f4 in thunar_file_load /home/s/code/thunar/thunar/thunar-file.c:1192:3
    #3 0x555555b8145d in thunar_file_reload /home/s/code/thunar/thunar/thunar-file.c:4289:8
    #4 0x555555b81b44 in thunar_file_reload_cb_once /home/s/code/thunar/thunar/thunar-file.c:4309:3
    #5 0x7ffff6f34f68  (/usr/lib/libglib-2.0.so.0+0x59f68)
    #6 0x7ffff6f933a6  (/usr/lib/libglib-2.0.so.0+0xb83a6)
    #7 0x7ffff6f35b96 in g_main_loop_run (/usr/lib/libglib-2.0.so.0+0x5ab96)
    #8 0x7ffff734ac12 in gtk_dialog_run (/usr/lib/libgtk-3.so.0+0x14ac12)
    #9 0x555555b2c631 in thunar_dialogs_show_rename_file /home/s/code/thunar/thunar/thunar-dialogs.c:360:14
    #10 0x555555aa6d57 in thunar_application_rename_file /home/s/code/thunar/thunar/thunar-application.c:1938:9
    #11 0x555555a987e5 in thunar_action_manager_action_rename /home/s/code/thunar/thunar/thunar-action-manager.c:2442:7
    #12 0x7ffff72865a0  (/usr/lib/libgtk-3.so.0+0x865a0)
    #13 0x7ffff7a426bf in g_closure_invoke (/usr/lib/libgobject-2.0.so.0+0x146bf)
    #14 0x7ffff7a70a35  (/usr/lib/libgobject-2.0.so.0+0x42a35)
    #15 0x7ffff7a61334  (/usr/lib/libgobject-2.0.so.0+0x33334)
    #16 0x7ffff7a61c76 in g_signal_emit_valist (/usr/lib/libgobject-2.0.so.0+0x33c76)
    #17 0x7ffff7a61d33 in g_signal_emit (/usr/lib/libgobject-2.0.so.0+0x33d33)
    #18 0x7ffff72968fb in gtk_accel_group_activate (/usr/lib/libgtk-3.so.0+0x968fb)
    #19 0x7ffff7297b5d in gtk_accel_groups_activate (/usr/lib/libgtk-3.so.0+0x97b5d)
    #20 0x7ffff756621a in gtk_window_activate_key (/usr/lib/libgtk-3.so.0+0x36621a)
    #21 0x7ffff7566695  (/usr/lib/libgtk-3.so.0+0x366695)
    #22 0x7ffff728c6cc  (/usr/lib/libgtk-3.so.0+0x8c6cc)
    #23 0x7ffff7a426bf in g_closure_invoke (/usr/lib/libgobject-2.0.so.0+0x146bf)
    #24 0x7ffff7a710e9  (/usr/lib/libgobject-2.0.so.0+0x430e9)
    #25 0x7ffff7a61334  (/usr/lib/libgobject-2.0.so.0+0x33334)
    #26 0x7ffff7a61c76 in g_signal_emit_valist (/usr/lib/libgobject-2.0.so.0+0x33c76)
    #27 0x7ffff7a61d33 in g_signal_emit (/usr/lib/libgobject-2.0.so.0+0x33d33)

previously allocated by thread T0 here:
    #0 0x5555559dc769 in malloc (/usr/local/bin/thunar+0x488769)
    #1 0x7ffff6f3d762 in g_malloc (/usr/lib/libglib-2.0.so.0+0x62762)
    #2 0x7ffff6f1c141 in g_path_get_basename (/usr/lib/libglib-2.0.so.0+0x41141)
    #3 0x555555b60f55 in thunar_file_info_reload /home/s/code/thunar/thunar/thunar-file.c:982:20
    #4 0x555555b5de11 in thunar_file_load /home/s/code/thunar/thunar/thunar-file.c:1217:3
    #5 0x555555b5c81b in thunar_file_get /home/s/code/thunar/thunar/thunar-file.c:1273:11
    #6 0x555555b958c1 in thunar_folder_monitor /home/s/code/thunar/thunar/thunar-folder.c:969:33
    #7 0x7ffff709a558  (/usr/lib/libgio-2.0.so.0+0x73558)
    #8 0x7ffff7a61b72  (/usr/lib/libgobject-2.0.so.0+0x33b72)
    #9 0x7ffff7a61c76 in g_signal_emit_valist (/usr/lib/libgobject-2.0.so.0+0x33c76)
    #10 0x7ffff7a61d33 in g_signal_emit (/usr/lib/libgobject-2.0.so.0+0x33d33)
    #11 0x7ffff715ef2b  (/usr/lib/libgio-2.0.so.0+0x137f2b)
    #12 0x7ffff6f34f68  (/usr/lib/libglib-2.0.so.0+0x59f68)
    #13 0x7ffff6f933a6  (/usr/lib/libglib-2.0.so.0+0xb83a6)
    #14 0x7ffff6f33161 in g_main_context_iteration (/usr/lib/libglib-2.0.so.0+0x58161)
    #15 0x7ffff7106b65 in g_application_run (/usr/lib/libgio-2.0.so.0+0xdfb65)
    #16 0x555555a6303b in main /home/s/code/thunar/thunar/main.c:86:3
    #17 0x7ffff6d1eccf  (/usr/lib/libc.so.6+0x25ccf)
    #18 0x7ffff6d1ed89 in __libc_start_main (/usr/lib/libc.so.6+0x25d89)
    #19 0x5555558ed584 in _start (/usr/local/bin/thunar+0x399584)

SUMMARY: AddressSanitizer: heap-use-after-free (/usr/local/bin/thunar+0x44ea1f) in strcmp.part.0
Shadow bytes around the buggy address:
  0x502000b6e900: fa fa fd fd fa fa fd fd fa fa fd fd fa fa fd fd
  0x502000b6e980: fa fa fd fd fa fa fd fd fa fa fd fa fa fa fd fa
  0x502000b6ea00: fa fa 00 00 fa fa fd fd fa fa fd fd fa fa fd fa
  0x502000b6ea80: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x502000b6eb00: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
=>0x502000b6eb80: fa fa fd fa fa fa fd fa fa fa fd fd fa fa[fd]fd
  0x502000b6ec00: fa fa fd fd fa fa fd fa fa fa fd fa fa fa fd fd
  0x502000b6ec80: fa fa fd fd fa fa fd fd fa fa fd fd fa fa fd fd
  0x502000b6ed00: fa fa fd fd fa fa fd fa fa fa fd fd fa fa fd fd
  0x502000b6ed80: fa fa fd fd fa fa fd fd fa fa fd fd fa fa fd fd
  0x502000b6ee00: fa fa fd fd fa fa fd fd fa fa fd fd fa fa fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb

Version: 3af8e869