Re: I found multiple crash bugs in Dash v0.5.12-115-gb4ef25d

Herbert Xu <[email protected]> Sat, 13 Sep 2025 21:34:56 +0800
Newsgroups org.kernel.vger.dash
Message-ID <[email protected]>
On Fri, Aug 29, 2025 at 07:40:16PM -0700, Nathan Mills wrote:
>
> * Crash #6 is a memcpy-param-overlap caused by not handling literal
> CTLMBCHAR characters in the input correctly, so then _rmescapes treats
> them as if they were encoded by Dash. Easily fixed by changing mempcpy
> to memmove and then increment `q`.and rejecting literal CTLMBCHAR
> characters. Note: my suggested fix may have problems handling UTF-8,
> but seems to work fine at least for a couple of Unicode characters I
> tried (one Korean, one Cyrillic).
>
> ** Crash #6 memcpy-param-overlap **
> 
> The character \x85 when converted to signed is -123 which equals
> CTLMBCHAR. This character is in the input file instead of being
> generated by the parser. `ml` is equal to 36, which is the ASCII value
> of the dollar sign.
> 
> Base64'd:
> 
> djR0IQoKJHN1JCgoKIUkKSgpKSk8ZWUAAACAra0kJCT/JF7/
> 
> Minimized:
> 
> src/dash <(echo -e '$(((\x85$)))<e')
> 
> **Fix for #6 **
> diff --git a/src/expand.c b/src/expand.c
> index 3edf160..5276776 100644
> --- a/src/expand.c
> +++ b/src/expand.c
> @@ -2132,7 +2132,8 @@ _rmescapes(char *str, int flag)
>                                 tail = 0;
>                         }
> 
> -                       q = mempcpy(q, p, ml);
> +                       memmove(q, p, ml);
> +                       q += ml;
>                         p += ml + tail;
>                         goto setnesc;
>                 }
> diff --git a/src/parser.c b/src/parser.c
> index d3b598b..919b4ba 100644
> --- a/src/parser.c
> +++ b/src/parser.c
> @@ -1033,6 +1033,11 @@ readtoken1(int firstc, char const *syntax, char
> *eofmark, int striptabs)
>                                       out);
>                         fieldsplitting = synstack->syntax == BASESYNTAX &&
>                                          !synstack->varnest ? 4 : 0;
> +                       if (c >= CTL_FIRST && c <= CTL_LAST) {
> +                               char buf[40];
> +                               fmtstr(buf, sizeof(buf), "Invalid
> control character \\x%02x in input", (unsigned char)c);
> +                               synerror(buf);
> +                       }
>                         ml = getmbc(c, out, fieldsplitting);
>                         if (ml == 1) {
>                                 if (out == stackblock())

Thanks for the report.  This has already been fixed with

commit 98cc11a5dbbc41f71fe68df0766d6ed647e83445 (HEAD -> master)
Author: Herbert Xu <[email protected]>
Date:   Thu Aug 28 17:27:09 2025 +0800

    expand: Do not call rmescapes in expari

Cheers,
-- 
Email: Herbert Xu <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt