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

Re: zsh malloc/heap corruption



On Sun, Sep 28, 2025 at 7:19 PM Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
>
> 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) {
>

Is regfree() later on safe?

-- 
Mikael Magnusson




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