Subject: bug#58042: 29.0.50; ASAN use-after-free in re_match_2_internal

From: Gerd Möllmann <[email-masked]>
Date: Wed, 05 Oct 2022 14:32:07 +0200

Po Lu <[email-masked]> writes:

> Gerd Möllmann <[email-masked]> writes:
>
>> Po Lu <[email-masked]> writes:
>>
>>> I'm going to guess that window_sub_list is returning a window that was
>>> not marked during GC.  It's a problem that also exists with my
>>> incremental garbage collector.  Does this help?
>>>
>>> diff --git a/src/alloc.c b/src/alloc.c
>>> index 419c5e558b..522925d248 100644
>>> --- a/src/alloc.c
>>> +++ b/src/alloc.c
>>> @@ -6634,6 +6634,9 @@ mark_window (struct Lisp_Vector *ptr)
>>>        mark_glyph_matrix (w->desired_matrix);
>>>      }
>>>  
>>> +  if (w->next)
>>> +    mark_window (w->next);
>>> +
>>>    /* Filter out killed buffers from both buffer lists
>>>       in attempt to help GC to reclaim killed buffers faster.
>>>       We can do it elsewhere for live windows, but this is the
>>
>> Indeed, that seems to work!
>
> Could you please replace that code with:
>
>   if (!NILP (w->next)
>       && !vectorlike_marked_p (&XWINDOW (w->next)->header))
>     emacs_abort ();
>
> And see if Emacs ever aborts?
>
> I just remembered that the old garbage collector does not work the same
> way as the one in my branch, so that bug shouldn't be possible.

With the change

diff --git a/src/alloc.c b/src/alloc.c
index 419c5e558b..4e0dd12729 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -6625,6 +6625,15 @@ mark_window (struct Lisp_Vector *ptr)
 
   mark_vectorlike (&ptr->header);
 
+#if 1
+  if (!NILP (w->next)
+      && !vectorlike_marked_p (&XWINDOW (w->next)->header))
+    emacs_abort ();
+#else
+  if (!NILP (w->next))
+    mark_object (w->next);
+#endif
+
   /* Mark glyph matrices, if any.  Marking window
      matrices is sufficient because frame matrices
      use the same glyph memory.  */

I don't get an abort, but the ASAN error again

==67682==ERROR: AddressSanitizer: heap-use-after-free on address 0x000107130d00 at pc 0x0001002a481c bp 0x00016fdcc3c0 sp 0x00016fdcc3b8
READ of size 8 at 0x000107130d00 thread T0
    #0 0x1002a4818 in PSEUDOVECTORP lisp.h:1110
    #1 0x1002a4888 in SYMBOL_WITH_POS_P lisp.h:1122
    #2 0x10025a338 in EQ lisp.h:1342
    #3 0x100280eb0 in run_window_change_functions window.c:3964
    #4 0x1000f18c4 in redisplay_internal xdisp.c:16600
    #5 0x100107bf8 in redisplay xdisp.c:16111
    #6 0x10089364c in -[EmacsView layoutSublayersOfLayer:] nsterm.m:8661
    #7 0x1900a9624 in CA::Layer::layout_if_needed(CA::Transaction*)+0x224 (QuartzCore:arm64e+0x20624)
    #8 0x1901f661c in CA::Context::commit_transaction(CA::Transaction*,
    double, double*)+0x1c0 (QuartzCore:arm6

frame #8: 0x0000000100280eb4 emacs`run_window_change_functions at window.c:3964:7
   3961		     (de-)selected as its frame's or the globally selected
   3962		     window.  */
   3963		  if (((frame_selected_change
-> 3964			&& (EQ (window, old_selected_window)
   3965			    || EQ (window, selected_window)))
   3966		       || (frame_selected_window_change
   3967			   && (EQ (window, FRAME_OLD_SELECTED_WINDOW (f))

(lldb) p window
(Lisp_Object) $18 = 0x00000001071c2935 (struct window *) $23 = 0x00000001071c2930
(lldb) p old_selected_window
(Lisp_Object) $24 = 0x0000000107130d05 (struct Lisp_Vector *) $28 = 0x0000000107130d00

old_selected_window looks strange.  It's a global that is not
staticpro'd

\o/