Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: zsh malloc/heap corruption



On Sat, Sep 27, 2025 at 8:56 PM Anthony Heading <ajrh@xxxxxxxx> wrote:
>
> Is it useful if I work on a better testcase with this new understanding,
> or does that one stack trace tell you all that's needed?

The key seems to be this bit:

#15 _int_malloc (av=av@entry=0x7987fd603ac0 <main_arena>, bytes=bytes@entry=88)
    at ./malloc/malloc.c:4410
#16 0x00007987fd4ae931 in __libc_calloc (n=n@entry=88,
    elem_size=elem_size@entry=1) at ./malloc/malloc.c:3754
#17 0x00007987fd502cbd in create_cd_newstate (hash=23, context=0,
    nodes=0x7fff8941f760, dfa=0x5b93559c14e0) at ./posix/regex_internal.c:1687
#18 re_acquire_state_context (context=0, nodes=0x7fff8941f760,
    dfa=0x5b93559c14e0, err=0x7fff8941f75c) at ./posix/regex_internal.c:1562
#19 build_trtable (dfa=0x5b93559c14e0, state=state@entry=0x5b93559be5a0)
    at ./posix/regexec.c:3331
#20 0x00007987fd507154 in transit_state (state=0x5b93559be5a0,
    mctx=0x7fff894241a0, err=0x7fff894240bc) at ./posix/regexec.c:2257
#21 check_matching (p_match_first=<optimized out>, fl_longest_match=true,
    mctx=0x7fff894241a0) at ./posix/regexec.c:1120
#22 re_search_internal (preg=preg@entry=0x7fff894243f0,
    string=string@entry=0x5b93559babc0 "+main_task:3> pwd", length=17,
    start=<optimized out>, last_start=<optimized out>, stop=<optimized out>,
    nmatch=1, pmatch=0x5b93559b5110, eflags=0) at ./posix/regexec.c:792

The POSIX regex library is directly calling calloc(), which lacks the
signal protection in the wrappers zsh uses for all its own memory
allocation.

The following should fix it, at the cost of possibly slowing down some
regular expression matches a little.

diff --git a/Src/Modules/regex.c b/Src/Modules/regex.c
index d02769ef0..cd11b16d7 100644
--- a/Src/Modules/regex.c
+++ b/Src/Modules/regex.c
@@ -74,7 +74,9 @@ zcond_regex_match(char **a, int id)
        rcflags |= REG_EXTENDED;
        if (!isset(CASEMATCH))
            rcflags |= REG_ICASE;
+       queue_signals();
        r = regcomp(&re, rhre, rcflags);
+       unqueue_signals();
        if (r) {
            zregex_regerrwarn(r, &re, "failed to compile regex");
            break;
@@ -89,7 +91,9 @@ zcond_regex_match(char **a, int id)
        }
        matchessz = (re.re_nsub + 1) * sizeof(regmatch_t);
        matches = zalloc(matchessz);
+       queue_signals();
        r = regexec(&re, lhstr, re.re_nsub+1, matches, reflags);
+       unqueue_signals();
        if (r == REG_NOMATCH)
            ; /* We do nothing when we fail to match. */
        else if (r == 0) {




Messages sorted by: Reverse Date, Date, Thread, Author