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

From: Gerd Möllmann <[email-masked]>
Date: Sun, 25 Sep 2022 07:50:17 +0200

Eli Zaretskii <[email-masked]> writes:

>> From: Gerd Möllmann <[email-masked]>
>> Cc: [email-masked]
>> Date: Sat, 24 Sep 2022 17:08:12 +0200
>> 
>> But in general, I think the small string compaction could be a serious
>> problem here, as soon as a GC happens while the regexp machine holds
>> pointers.
>
> What is the path from regexp match to GC?

I think since bug#56108 it's safe to say that a GC can happen while
matching.  In that bug, a regexp_cache entry was "freed" by GC.

> The GC was triggered by
> redisplay, but how did redisplay start while regexp match was in
> progress?  Do you see any code in regexp that could trigger redisplay?

I'm afraid, I don't follow.  Why do you think redisplay comes into play
here?

Anyways, my working hypotheses currently goes like this:

We match using some Lisp string S and get its data pointer, say D.
Since D is not null, S must be a live string.

(Actually I didn't check that this is still the case, but I think I've
been setting s.data to null for free strings right from the start, and I
can't imagine why anyone would change that.)

Between the point we get D, and the point of the crash, a GC happens.
We know in principle that a GC can happen while matching since
bug#56108.  I'm taking that as a given.  The GC compacts strings and
changes S's data pointer.

After GC, S.data != D.

Now, ASAN knows that a struct sdata was allocated and freed in the past
that contains S.data.  Or perhaps better said S.data points into the
part of the the freed struct sdata that ASAN checks.

How can that hapoen?

I have no idea, but that's the scenario I give the most credibility so
far.

WDYT?