Subject: bug#58334: 29.0.50; ASAN heap use after free in gui_produce_glyphs

From: Gerd Möllmann <[email-masked]>
Date: Thu, 06 Oct 2022 17:03:17 +0200

This is again on my local branch based on master.  Recent fixes for ASAN
are contained in that branch.  It seems to be pretty good at producing
this...

==19549==ERROR: AddressSanitizer: heap-use-after-free on address 0x0001393095c0 at pc 0x000100144340 bp 0x00016fdc16b0 sp 0x00016fdc16a8
READ of size 4 at 0x0001393095c0 thread T0
    #0 0x10014433c in gui_produce_glyphs xdisp.c:31875
    #1 0x1000a8bc0 in move_it_in_display_line_to xdisp.c:9813
    #2 0x10009a5c0 in move_it_to xdisp.c:10373
    #3 0x1000dcbac in move_it_vertically_backward xdisp.c:10745
    #4 0x100089ca4 in move_it_by_lines xdisp.c:10940
    #5 0x10055a7a4 in Fvertical_motion indent.c:2381
    #6 0x100642f20 in eval_sub eval.c:2488
    #7 0x10064440c in Fprogn eval.c:436
    #8 0x100618360 in Fsave_excursion editfns.c:886
    #9 0x1006424a0 in eval_sub eval.c:2435
    #10 0x100647ba4 in FletX eval.c:931
    #11 0x1006424a0 in eval_sub eval.c:2435
    #12 0x10064440c in Fprogn eval.c:436
    #13 0x1006424a0 in eval_sub eval.c:2435
    #14 0x10064af5c in Funwind_protect eval.c:1298
    #15 0x1006424a0 in eval_sub eval.c:2435
    #16 0x10064440c in Fprogn eval.c:436
    #17 0x1006185a4 in Fsave_current_buffer editfns.c:899
    #18 0x1006424a0 in eval_sub eval.c:2435
    #19 0x10064440c in Fprogn eval.c:436
    #20 0x100648d50 in Flet eval.c:1023
    #21 0x1006424a0 in eval_sub eval.c:2435
    #22 0x10064440c in Fprogn eval.c:436
    #23 0x100656f78 in funcall_lambda eval.c:3218
    #24 0x1006528f4 in apply_lambda eval.c:3088
    #25 0x100643d28 in eval_sub eval.c:2572
    #26 0x10064440c in Fprogn eval.c:436
    #27 0x1006424a0 in eval_sub eval.c:2435
    #28 0x1006441ac in Fif eval.c:391
    #29 0x1006424a0 in eval_sub eval.c:2435
    #30 0x10064440c in Fprogn eval.c:436
    #31 0x100656f78 in funcall_lambda eval.c:3218
    #32 0x100655384 in funcall_general eval.c:2941
    #33 0x10064a08c in Ffuncall eval.c:2979
    #34 0x100457288 in safe_run_hooks_1 keyboard.c:1829
    #35 0x10064cc80 in internal_condition_case_n eval.c:1555
    #36 0x100424970 in safe_run_hook_funcall keyboard.c:1887
    #37 0x100654690 in run_hook_with_args eval.c:2838
    #38 0x100424edc in safe_run_hooks_maybe_narrowed keyboard.c:1920
    #39 0x10041c68c in command_loop_1 keyboard.c:1511
    #40 0x10064c3d8 in internal_condition_case eval.c:1471
    #41 0x10041aacc in command_loop_2 keyboard.c:1123
    #42 0x10064ab64 in internal_catch eval.c:1194
    #43 0x100418ab8 in command_loop keyboard.c:1093
    #44 0x1004185cc in recursive_edit_1 keyboard.c:710
    #45 0x1004fa414 in read_minibuf minibuf.c:903
    #46 0x1004f7994 in Fread_from_minibuffer minibuf.c:1371
    #47 0x100643510 in eval_sub eval.c:2506
    #48 0x10064440c in Fprogn eval.c:436
    #49 0x1006424a0 in eval_sub eval.c:2435
    #50 0x10064af5c in Funwind_protect eval.c:1298
    #51 0x1006424a0 in eval_sub eval.c:2435
    #52 0x10064440c in Fprogn eval.c:436
    #53 0x100648d50 in Flet eval.c:1023
    #54 0x1006424a0 in eval_sub eval.c:2435
    #55 0x10064af5c in Funwind_protect eval.c:1298
    #56 0x1006424a0 in eval_sub eval.c:2435
    #57 0x10064440c in Fprogn eval.c:436
    #58 0x100648d50 in Flet eval.c:1023
    #59 0x1006424a0 in eval_sub eval.c:2435
    #60 0x10064440c in Fprogn eval.c:436
    #61 0x10064465c in Fcond eval.c:416
    #62 0x1006424a0 in eval_sub eval.c:2435
    #63 0x10064440c in Fprogn eval.c:436
    #64 0x1006480b4 in FletX eval.c:955
    #65 0x1006424a0 in eval_sub eval.c:2435
    #66 0x10064440c in Fprogn eval.c:436
    #67 0x1006185a4 in Fsave_current_buffer editfns.c:899
    #68 0x1006424a0 in eval_sub eval.c:2435
    #69 0x10064440c in Fprogn eval.c:436
    #70 0x100656f78 in funcall_lambda eval.c:3218
    #71 0x1006528f4 in apply_lambda eval.c:3088
    #72 0x100643d28 in eval_sub eval.c:2572
    #73 0x10064af5c in Funwind_protect eval.c:1298
    #74 0x1006424a0 in eval_sub eval.c:2435
    #75 0x10064440c in Fprogn eval.c:436
    #76 0x100648d50 in Flet eval.c:1023
    #77 0x1006424a0 in eval_sub eval.c:2435
    #78 0x10064be50 in internal_lisp_condition_case eval.c:1425
    #79 0x10064b18c in Fcondition_case eval.c:1340
    #80 0x1006424a0 in eval_sub eval.c:2435
    #81 0x10064af5c in Funwind_protect eval.c:1298
    #82 0x1006424a0 in eval_sub eval.c:2435
    #83 0x10064440c in Fprogn eval.c:436
    #84 0x100648d50 in Flet eval.c:1023
    #85 0x1006424a0 in eval_sub eval.c:2435
    #86 0x10064440c in Fprogn eval.c:436
    #87 0x100656f78 in funcall_lambda eval.c:3218
    #88 0x100655384 in funcall_general eval.c:2941
    #89 0x10064a08c in Ffuncall eval.c:2979
    #90 0x100653d68 in Fapply eval.c:2650
    #91 0x1006429d0 in eval_sub eval.c:2454
    #92 0x10064440c in Fprogn eval.c:436
    #93 0x1006441fc in Fif eval.c:392
    #94 0x1006424a0 in eval_sub eval.c:2435
    #95 0x10064440c in Fprogn eval.c:436
    #96 0x1006441fc in Fif eval.c:392
    #97 0x1006424a0 in eval_sub eval.c:2435
    #98 0x10064440c in Fprogn eval.c:436
    #99 0x100648d50 in Flet eval.c:1023
    #100 0x1006424a0 in eval_sub eval.c:2435
    #101 0x10064440c in Fprogn eval.c:436
    #102 0x100656f78 in funcall_lambda eval.c:3218
    #103 0x100655384 in funcall_general eval.c:2941
    #104 0x10064a08c in Ffuncall eval.c:2979
    #105 0x100653d68 in Fapply eval.c:2650
    #106 0x1006429d0 in eval_sub eval.c:2454
    #107 0x10064440c in Fprogn eval.c:436
    #108 0x1006424a0 in eval_sub eval.c:2435
    #109 0x1006441ac in Fif eval.c:391
    #110 0x1006424a0 in eval_sub eval.c:2435
    #111 0x10064440c in Fprogn eval.c:436
    #112 0x1006441fc in Fif eval.c:392
    #113 0x1006424a0 in eval_sub eval.c:2435
    #114 0x10064440c in Fprogn eval.c:436
    #115 0x100648d50 in Flet eval.c:1023
    #116 0x1006424a0 in eval_sub eval.c:2435
    #117 0x10064440c in Fprogn eval.c:436
    #118 0x100656f78 in funcall_lambda eval.c:3218
    #119 0x1006528f4 in apply_lambda eval.c:3088
    #120 0x100643d28 in eval_sub eval.c:2572
    #121 0x10064440c in Fprogn eval.c:436
    #122 0x100656f78 in funcall_lambda eval.c:3218
    #123 0x100655384 in funcall_general eval.c:2941
    #124 0x10064a08c in Ffuncall eval.c:2979
    #125 0x100635fbc in Ffuncall_interactively callint.c:248
    #126 0x1006564d4 in funcall_subr eval.c:3044
    #127 0x1006551dc in funcall_general eval.c:2925
    #128 0x10064a08c in Ffuncall eval.c:2979
    #129 0x100652d64 in Fapply eval.c:2603
    #130 0x100636ce8 in Fcall_interactively callint.c:340
    #131 0x100655b14 in funcall_subr eval.c:3021
    #132 0x100730088 in exec_byte_code bytecode.c:809
    #133 0x10065e22c in fetch_and_exec_byte_code eval.c:3066
    #134 0x100656a54 in funcall_lambda eval.c:3138
    #135 0x10065522c in funcall_general eval.c:2929
    #136 0x10064a08c in Ffuncall eval.c:2979
    #137 0x10042645c in call1 lisp.h:3313
    #138 0x10041c518 in command_loop_1 keyboard.c:1496
    #139 0x10064c3d8 in internal_condition_case eval.c:1471
    #140 0x10041aacc in command_loop_2 keyboard.c:1123
    #141 0x10064ab64 in internal_catch eval.c:1194
    #142 0x100418b64 in command_loop keyboard.c:1101
    #143 0x1004185cc in recursive_edit_1 keyboard.c:710
    #144 0x100419588 in Frecursive_edit keyboard.c:793
    #145 0x1004116c8 in main emacs.c:2521
    #146 0x101555088 in start+0x204 (dyld:arm64e+0x5088)

0x0001393095c0 is located 256 bytes inside of 296-byte region [0x0001393094c0,0x0001393095e8)
freed by thread T0 here:
    #0 0x1033f2de4 in wrap_free+0x98 (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x3ede4)
    #1 0x10098d5e0 in rpl_free free.c:48
    #2 0x1005af84c in xfree alloc.c:810
    #3 0x1003f32ac in free_realized_face xfaces.c:4511
    #4 0x1003e5e40 in free_realized_faces xfaces.c:4702
    #5 0x1003d4a6c in free_all_realized_faces xfaces.c:4742
    #6 0x1000cee18 in init_iterator xdisp.c:3193
    #7 0x1001001ac in gui_consider_frame_title xdisp.c:13497
    #8 0x1001d72cc in prepare_menu_bars xdisp.c:13612
    #9 0x1000f2c64 in redisplay_internal xdisp.c:16529
    #10 0x100109858 in redisplay xdisp.c:16111
    #11 0x100896f90 in -[EmacsView layoutSublayersOfLayer:] nsterm.m:8675
    #12 0x1900a9624 in CA::Layer::layout_if_needed(CA::Transaction*)+0x224 (QuartzCore:arm64e+0x20624)
    #13 0x1901f661c in CA::Context::commit_transaction(CA::Transaction*, double, double*)+0x1c0 (QuartzCore:arm64e+0x16d61c)
    #14 0x19008b4c8 in CA::Transaction::commit()+0x2bc (QuartzCore:arm64e+0x24c8)
    #15 0x18bee1698 in __62+[CATransaction(NSCATransaction) NS_setFlushesWithDisplayLink]_block_invoke+0x12c (AppKit:arm64e+0x1ac698)
    #16 0x18c646754 in ___NSRunLoopObserverCreateWithHandler_block_invoke+0x3c (AppKit:arm64e+0x911754)
    #17 0x1892101a0 in __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__+0x20 (CoreFoundation:arm64e+0x841a0)
    #18 0x18920fff0 in __CFRunLoopDoObservers+0x24c (CoreFoundation:arm64e+0x83ff0)
    #19 0x18920f524 in __CFRunLoopRun+0x300 (CoreFoundation:arm64e+0x83524)
    #20 0x18920ea80 in CFRunLoopRunSpecific+0x254 (CoreFoundation:arm64e+0x82a80)
    #21 0x191e4e334 in RunCurrentEventLoopInMode+0x120 (HIToolbox:arm64e+0x32334)
    #22 0x191e4dfc0 in ReceiveNextEventCommon+0x140 (HIToolbox:arm64e+0x31fc0)
    #23 0x191e4de64 in _BlockUntilNextEventMatchingListInModeWithFilter+0x44 (HIToolbox:arm64e+0x31e64)
    #24 0x18bd76518 in _DPSNextEvent+0x358 (AppKit:arm64e+0x41518)
    #25 0x18bd74e10 in -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:]+0x52c (AppKit:arm64e+0x3fe10)
    #26 0x18bd66fdc in -[NSApplication run]+0x250 (AppKit:arm64e+0x31fdc)
    #27 0x1008744f4 in -[EmacsApp run] nsterm.m:5813
    #28 0x1008cb450 in ns_read_socket_1 nsterm.m:4693
    #29 0x1008b1e74 in ns_read_socket nsterm.m:4711

previously allocated by thread T0 here:
    #0 0x1033f2ca8 in wrap_malloc+0x94 (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x3eca8)
    #1 0x1005af4f4 in lmalloc alloc.c:1361
    #2 0x1005af40c in xmalloc alloc.c:751
    #3 0x1003f92b4 in make_realized_face xfaces.c:4471
    #4 0x1003f5c00 in realize_gui_face xfaces.c:6023
    #5 0x1003e4000 in realize_face xfaces.c:5954
    #6 0x1003e70fc in lookup_face xfaces.c:4890
    #7 0x1003eef98 in face_at_buffer_position xfaces.c:6641
    #8 0x1001a2d9c in face_at_pos xdisp.c:4499
    #9 0x10019ee18 in handle_face_prop xdisp.c:4600
    #10 0x100198810 in handle_stop xdisp.c:3947
    #11 0x1000d72e4 in reseat xdisp.c:7582
    #12 0x1000d7ab8 in reseat_at_previous_visible_line_start xdisp.c:7445
    #13 0x10008c204 in start_display xdisp.c:3581
    #14 0x1005592d8 in Fvertical_motion indent.c:2241
    #15 0x100642f20 in eval_sub eval.c:2488
    #16 0x10064440c in Fprogn eval.c:436
    #17 0x100618360 in Fsave_excursion editfns.c:886
    #18 0x1006424a0 in eval_sub eval.c:2435
    #19 0x100647ba4 in FletX eval.c:931
    #20 0x1006424a0 in eval_sub eval.c:2435
    #21 0x10064440c in Fprogn eval.c:436
    #22 0x1006424a0 in eval_sub eval.c:2435
    #23 0x10064af5c in Funwind_protect eval.c:1298
    #24 0x1006424a0 in eval_sub eval.c:2435
    #25 0x10064440c in Fprogn eval.c:436
    #26 0x1006185a4 in Fsave_current_buffer editfns.c:899
    #27 0x1006424a0 in eval_sub eval.c:2435
    #28 0x10064440c in Fprogn eval.c:436
    #29 0x100648d50 in Flet eval.c:1023

SUMMARY: AddressSanitizer: heap-use-after-free xdisp.c:31875 in gui_produce_glyphs
Shadow bytes around the buggy address:
  0x007027281260: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
  0x007027281270: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x007027281280: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa
  0x007027281290: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
  0x0070272812a0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x0070272812b0: fd fd fd fd fd fd fd fd[fd]fd fd fd fd fa fa fa
  0x0070272812c0: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
  0x0070272812d0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0070272812e0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa
  0x0070272812f0: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x007027281300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
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
==19549==ABORTING
(lldb) AddressSanitizer report breakpoint hit. Use 'thread info -s' to get extended information about the report.

The problem here, it seems to me, is that the redisplay done in
-[EmacsView layoutSublayersOfLayer:] nsterm.m:8675, frees realized faces
at a moment that the code doesn't cannot expect.

I'm too lazy too look further.  I'm pretty sure the story goes pretty
much like what we had before with relocating strings.

Is there a way to prevent freeing realized faces?