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

Herbert Xu <[email protected]> Sat, 13 Sep 2025 22:06:28 +0800
Newsgroups org.kernel.vger.dash
Message-ID <[email protected]>
On Fri, Aug 29, 2025 at 07:40:16PM -0700, Nathan Mills wrote:
>
> * Crash #71 is an overread when the pointer `p` is near the end of the
> string being processed and it checks the next 6 characters or so
> looking for `$@`.
>
> ** Crash #71 heap-buffer-overflow (memcmp) **
> 
> Base64'd:
> SkooKQoLITwqIT0KCgpKPCohPQoKCkooKTxuJycnJzsnJzsKCoODyfohPPf///8qIT0KCgpK
>
> ** Crash #71 heap-buffer-overflow (memcmp) **
> 
> Base64'd:
> SkooKQoLITwqIT0KCgpKPCohPQoKCkooKTxuJycnJzsnJzsKCoODyfohPPf///8qIT0KCgpK
> 
> 
> 
> ../v0.5.12-gb4ef25d/default/crashes/id:000071,sig:06,src:001663,time:5639570,execs:803122,op:havoc,rep:7:
> 5: cannot open *!=: No such file
> ../v0.5.12-gb4ef25d/default/crashes/id:000071,sig:06,src:001663,time:5639570,execs:803122,op:havoc,rep:7:
> 8: : Permission denied
> ../v0.5.12-gb4ef25d/default/crashes/id:000071,sig:06,src:001663,time:5639570,execs:803122,op:havoc,rep:7:
> 10: cannot open ����*!=: No such file
> =================================================================
> ==75725==ERROR: AddressSanitizer: heap-buffer-overflow on address
> 0x50d0000000d0 at pc 0x55555564ca84 bp 0x7fffffff9100 sp
> 0x7fffffff88c0
> READ of size 5 at 0x50d0000000d0 thread T0
>     #0 0x55555564ca83  (/home/nixos/src/dash/asan_debug/src/dash+0xf8a83)
>     #1 0x55555564cfad  (/home/nixos/src/dash/asan_debug/src/dash+0xf8fad)
>     #2 0x5555556db48d  (/home/nixos/src/dash/asan_debug/src/dash+0x18748d)
>     #3 0x5555556dadc7  (/home/nixos/src/dash/asan_debug/src/dash+0x186dc7)
>     #4 0x5555556d18fa  (/home/nixos/src/dash/asan_debug/src/dash+0x17d8fa)
>     #5 0x5555556d2647  (/home/nixos/src/dash/asan_debug/src/dash+0x17e647)
>     #6 0x5555556d13cc  (/home/nixos/src/dash/asan_debug/src/dash+0x17d3cc)
>     #7 0x5555556d63ed  (/home/nixos/src/dash/asan_debug/src/dash+0x1823ed)
>     #8 0x5555556d2df9  (/home/nixos/src/dash/asan_debug/src/dash+0x17edf9)
>     #9 0x5555556d13cc  (/home/nixos/src/dash/asan_debug/src/dash+0x17d3cc)
>     #10 0x5555556ef42c  (/home/nixos/src/dash/asan_debug/src/dash+0x19b42c)
>     #11 0x5555556eefe4  (/home/nixos/src/dash/asan_debug/src/dash+0x19afe4)
>     #12 0x7ffff7c2a47d
> (/nix/store/g8zyryr9cr6540xsyg4avqkwgxpnwj2a-glibc-2.40-66/lib/libc.so.6+0x2a47d)
> (BuildId: 076d831f9114b2d83bda538386af4e9665308c38)
>     #13 0x7ffff7c2a538
> (/nix/store/g8zyryr9cr6540xsyg4avqkwgxpnwj2a-glibc-2.40-66/lib/libc.so.6+0x2a538)
> (BuildId: 076d831f9114b2d83bda538386af4e9665308c38)
>     #14 0x55555558c5c4  (/home/nixos/src/dash/asan_debug/src/dash+0x385c4)
> 
> 0x50d0000000d0 is located 0 bytes after 144-byte region
> [0x50d000000040,0x50d0000000d0)
> allocated by thread T0 here:
>     #0 0x55555567f2c7  (/home/nixos/src/dash/asan_debug/src/dash+0x12b2c7)
>     #1 0x5555556efbf4  (/home/nixos/src/dash/asan_debug/src/dash+0x19bbf4)
>     #2 0x55555570db42  (/home/nixos/src/dash/asan_debug/src/dash+0x1b9b42)
>     #3 0x5555556da016  (/home/nixos/src/dash/asan_debug/src/dash+0x186016)
>     #4 0x5555556d14e6  (/home/nixos/src/dash/asan_debug/src/dash+0x17d4e6)
>     #5 0x5555556d1345  (/home/nixos/src/dash/asan_debug/src/dash+0x17d345)
>     #6 0x5555556ef42c  (/home/nixos/src/dash/asan_debug/src/dash+0x19b42c)
>     #7 0x5555556eefe4  (/home/nixos/src/dash/asan_debug/src/dash+0x19afe4)
>     #8 0x7ffff7c2a47d
> (/nix/store/g8zyryr9cr6540xsyg4avqkwgxpnwj2a-glibc-2.40-66/lib/libc.so.6+0x2a47d)
> (BuildId: 076d831f9114b2d83bda538386af4e9665308c38)
> 
> SUMMARY: AddressSanitizer: heap-buffer-overflow
> (/home/nixos/src/dash/asan_debug/src/dash+0xf8a83)
> Shadow bytes around the buggy address:
>   0x50cffffffe00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>   0x50cffffffe80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>   0x50cfffffff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>   0x50cfffffff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>   0x50d000000000: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
> =>0x50d000000080: 00 00 00 00 00 00 00 00 00 00[fa]fa fa fa fa fa
>   0x50d000000100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
>   0x50d000000180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
>   0x50d000000200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
>   0x50d000000280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
>   0x50d000000300: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
> Shadow byte legend (one shadow byte represents 8 application bytes):
>   Addressable:           00
>   Partially addressable: 01 02 03 04 05 06 07
>   Heap left redzone:       fa
>   Freed heap region:       fd
>   Stack left redzone:      f1
>   Stack mid redzone:       f2
>   Stack right redzone:     f3
>   Stack after return:      f5
>   Stack use after scope:   f8
>   Global redzone:          f9
>   Global init order:       f6
>   Poisoned by user:        f7
>   Container overflow:      fc
>   Array cookie:            ac
>   Intra object redzone:    bb
>   ASan internal:           fe
>   Left alloca redzone:     ca
>   Right alloca redzone:    cb
> ==75725==ABORTING
> 
> Program received signal SIGKILL, Killed.
> 0x000055555569d350 in __sanitizer::internal__exit(int) ()
> (rr) bt
> #0  0x000055555569d350 in __sanitizer::internal__exit(int) ()
> #1  0x00005555556aa393 in __sanitizer::Die() ()
> #2  0x0000555555689203 in __asan::ScopedInErrorReport::~ScopedInErrorReport() ()
> #3  0x00005555556887fa in __asan::ReportGenericError(unsigned long,
> unsigned long, unsigned long, unsigned long, bool, unsigned long,
> unsigned int, bool) [clone .part.0] ()
> #4  0x000055555564cab4 in MemcmpInterceptorCommon(void*, int (*)(void
> const*, void const*, unsigned long), void const*, void const*,
> unsigned long) ()
> #5  0x000055555564cfae in __interceptor_memcmp ()
> #6  0x00005555556db48e in argstr (p=0x50d0000000cc "\210", flag=8) at
> expand.c:357
> #7  0x00005555556dadc8 in expandarg (arg=0x50d0000000a8,
> arglist=0x7ffff5e005a0, flag=10) at expand.c:232
> #8  0x00005555556d18fb in expredir (n=0x50d000000080) at eval.c:542
> #9  0x00005555556d2648 in evalcommand (cmd=0x50d000000060, flags=0) at
> eval.c:847
> #10 0x00005555556d13cd in evaltree (n=0x50d000000060, flags=0) at eval.c:305
> #11 0x00005555556d63ee in evalfun (func=0x50d000000040, argc=1,
> argv=0x5555560bc670 <stackbase+112>, flags=0)
>     at eval.c:1017
> #12 0x00005555556d2dfa in evalcommand (cmd=0x5555560bc630
> <stackbase+48>, flags=0) at eval.c:931
> #13 0x00005555556d13cd in evaltree (n=0x5555560bc630 <stackbase+48>,
> flags=0) at eval.c:305
> #14 0x00005555556ef42d in cmdloop (top=1) at main.c:246
> #15 0x00005555556eefe5 in main (argc=2, argv=0x7fffffffa2d8) at main.c:180
> (rr) frame 6
> #6  0x00005555556db48e in argstr (p=0x50d0000000cc "\210", flag=8) at
> expand.c:357
> 357                             if (!inquotes && !memcmp(p, dolatstr + 1,
> (rr) p p
> $1 = 0x50d0000000cc "\210"
> (rr) up
> #7  0x00005555556dadc8 in expandarg (arg=0x50d0000000a8,
> arglist=0x7ffff5e005a0, flag=10) at expand.c:232
> 232             argstr(arg->narg.text, flag);

This is actualy harmless because memcmp will return non-zero if we
read past the NUL character on the string p.  If there was a way
to mark this as a false-positive it would be nice.

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