heap-use-after-free calcsize() src/nodes.c:174

Aleksander Ushakov <[email protected]> Tue, 13 Jan 2026 21:56:48 +0300
Newsgroups org.kernel.vger.dash
Message-ID <CADdNFasDNSdX+krLXYqUnx8O1HF8P77SLukKJRHfZMu5OUE-gg@mail.gmail.com>
Dear Dash maintainers,

I encountered a bug in Dash in commit f8aaaa (Also the behaviour repeats on
0.5.13 version of Dash) and would like to report
it. The details are provided below.

==50282==ERROR: AddressSanitizer: heap-use-after-free on address
0x515000008288 at pc 0x5a5b8c4d00a1 bp 0x7ffe6c3f4f80 sp 0x7ffe6c3f4730



READ of size 3 at 0x515000008288 thread T0




   #0 0x5a5b8c4d00a0 in __interceptor_strlen
../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:389



   #1 0x5a5b8c60ccd4 in calcsize /upstream/dash/src/nodes.c:174




   #2 0x5a5b8c60cd87 in calcsize /upstream/dash/src/nodes.c:165




   #3 0x5a5b8c60cda9 in calcsize /upstream/dash/src/nodes.c:166




   #4 0x5a5b8c60cb38 in calcsize /upstream/dash/src/nodes.c:160




   #5 0x5a5b8c60ca5b in calcsize /upstream/dash/src/nodes.c:139




   #6 0x5a5b8c60c9b7 in calcsize /upstream/dash/src/nodes.c:146




   #7 0x5a5b8c60c9d8 in calcsize /upstream/dash/src/nodes.c:147




   #8 0x5a5b8c60c9d8 in calcsize /upstream/dash/src/nodes.c:147




   #9 0x5a5b8c60c9d8 in calcsize /upstream/dash/src/nodes.c:147




   #10 0x5a5b8c60c9d8 in calcsize /upstream/dash/src/nodes.c:147




   #11 0x5a5b8c60c9d8 in calcsize /upstream/dash/src/nodes.c:147




   #12 0x5a5b8c60c9d8 in calcsize /upstream/dash/src/nodes.c:147



   #13 0x5a5b8c60ce04 in calcsize /upstream/dash/src/nodes.c:169



   #14 0x5a5b8c60efd7 in copyfunc /upstream/dash/src/nodes.c:109



   #15 0x5a5b8c5a4f11 in defun /upstream/dash/src/exec.c:746



   #16 0x5a5b8c591cbe in evaltree /upstream/dash/src/eval.c:315



   #17 0x5a5b8c5cc35b in cmdloop /upstream/dash/src/main.c:242



   #18 0x5a5b8c4a93ab in main /upstream/dash/src/main.c:176



   #19 0x7049282a1249 in __libc_start_call_main
../sysdeps/nptl/libc_start_call_main.h:58


   #20 0x7049282a1304 in __libc_start_main_impl ../csu/libc-start.c:360



   #21 0x5a5b8c4aa490 in _start (/upstream/dash/src/dash+0x1a490)







0x515000008288 is located 8 bytes inside of 512-byte region
[0x515000008280,0x515000008480)


freed by thread T0 here:



   #0 0x5a5b8c53cfd8 in __interceptor_free
../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:52


   #1 0x5a5b8c5ce35d in popstackmark /upstream/dash/src/memalloc.c:185







previously allocated by thread T0 here:



   #0 0x5a5b8c53e2ff in __interceptor_malloc
../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69


   #1 0x5a5b8c5cd7af in ckmalloc /upstream/dash/src/memalloc.c:55







SUMMARY: AddressSanitizer: heap-use-after-free
../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:389
in __interceptor_strlen
Shadow bytes around the buggy address:
 0x0a2a7fff9000: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
 0x0a2a7fff9010: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
 0x0a2a7fff9020: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
 0x0a2a7fff9030: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
 0x0a2a7fff9040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0a2a7fff9050: fd[fd]fd fd fd fd fd fd fd fd fd fd fd fd fd fd
 0x0a2a7fff9060: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
 0x0a2a7fff9070: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
 0x0a2a7fff9080: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
 0x0a2a7fff9090: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
 0x0a2a7fff90a0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
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
==50286==ABORTING

////////////////
My environment:
////////////////

Debian-12, x86-64, clang-19 compiler

/////////////////
Steps to reproduce:
/////////////////

$ aclocal && autoheader && automake --add-missing && autoconf
$ CC=clang CFLAGS=" -Wno-everything -fsanitize=address -g -O0" ./configure
--disable-fnmatch --disable-lineno --disable-glob
$ make
$ cd src
$ cat myfile.txt | ./dash -i

//////////////////
Steps to get myfile.txt:
//////////////////

copy the text into file bs64.txt (between ==== and ======)
=====================================================================================
dGYgaXMgYSBmdW5jdGlvbgp0ZiAoKSAKeyAKICAgIGVjaG8gdGhpcyBpcyAkezAjIyovfSA+IC9k
ZXYvbnVsbDsKICAgIGVjaG8gYSB8IGNhdCAtID4gL2Rldi9udWxsOwogICAgdGVzdCAtZiAkezAj
IyovfSAmJiBlY2hvICR7MCMjKi99IGlzIGEgcmVndWxhciBmaWxlOwogICAgdGVzdCAtZCAkezAj
IyovfSB8fCBlY2hvICR7MCMjKi99IGlzIG5vdCBhIGRpcmVjdG9yeTsKICAgIGVjaG8gYTsKICAg
IGVjaG8gYjsKICAgIGVjaG8gYzsKICAgIGVjaG8gYmFja2dyb3VuZCA+IC9kZXYvbnVsbCAmICgg
ZXhpdCAxICk7CiAgICBlY2hvICQ/OwogICAgeyAKICAgICAgICBlY2hvIGEKICAgIH07CiAgICBp
PTA7CiAgICB3aGlsZSAoKCBpIDwgMyApKTsgZG8KICAgICAgICB0ZXN0IC1yIC9kZXYvZmQvJGk7
CiAgICAgICAgaT0kKCggaSArIDEgKSk7CiAgICBkb25lOwogICAgW1sgLXIgL2Rldi9mZC8wICYm
IC13IC9kZXYvZmQvMSBdXSB8fCBlY2hvIG9vcHMgPiAvZGV2L251bGw7CiAgICBmb3IgbmFtZSBp
biAkKGVjaG8gMSAyIDMpOwogICAgZG8KICAgICAgICB0ZXN0IC1yIC9kZXYvZmQvJG5hbWU7CiAg
ICBkb25lOwogICAgaWYgW1sgLXIgL2Rldi9mZC8wICYmIC13IC9kZXYvZmQvMSBdXTsgdGhlbgog
ICAgICAgIGVjaG8gb2sgPiAvZGV2L251bGw7CiAgICBlbHNlCiAgICAgICAgaWYgKCggNyA+IDQw
ICkpOyB0aGVuCiAgICAgICAgICAgIGVjaG8gb29wczsKICAgICAgICBlbHNlCiAgICAgICAgICAg
IGVjaG8gZG9uZTsKICAgICAgICBmaTsKICAgIGZpID4gL2Rldi9udWxsOwogICAgY2FzZSAkUEFU
SCBpbiAKICAgICAgICAqJFBXRCopCiAgICAgICAgICAgIGVjaG8gXCRQV0QgaW4gXCRQQVRICiAg
ICAgICAgOzsKICAgICAgICApKQogICAgICAgICAgICBlY2hvIFwkUFdEIG5vdCBpbiBcJFBBVEgK
ICAgICAgICA7OwogICAgZXNhYyA+IC9kJnYvbnVsbDsKICAgIHdoaWxlIGZhbHNlOyBkbwogICAg
ICAgIGVjaG8gejsKICAgIGRvbmUgPiAvZGV2L251bGw7CiAgICB1bnRpbCB0cnVlOyBkbwogICAg
ICAgIGVjaG8gejsKICAgIGRvbmUgPiAvZGV2L251bGw7CiAgICBlY2hvIFwmXHwnKCknIFx7IGVj
aG8gYWJjZGUgXDsgXH07CiAgICBldmFsIGZ1XCVuYycoKScgXHsgZWNobyBhYmNkZSBcOyBcfTsK
ICAgIHR5cGUgZnVcJW5jCn0KdGYyIGlzIGEgZnVuY3Rpb24KdGYyICgpIAp7IAogICAgKCB7IAog
ICAgICAgIHRpbWUgLXAgZWNobyBhIHwgY2F0IC0gPiAvZGV2L251bGwKICAgIH0gKSAyPiYxCn0K
Y3ByaW50LnRlc3RzIGlzIGEgcmVndWxhciBmaWxlCmNwcmludC50ZXN0cyBpcyBub3QgYSBkaXJl
Y3RvcnkKYQpiCmMKMQphCiZ8KCkgeyBlY2hvIGFiY2RlYmNkZQp9Cg==
=====================================================================================
Then do the action: base64 -d bs64.txt > myfile.txt
Or just take from attachments
myfile.txt.txt (text/plain, 1.3 KB)
tf is a function
tf () 
{ 
    echo this is ${0##*/} > /dev/null;
    echo a | cat - > /dev/null;
    test -f ${0##*/} && echo ${0##*/} is a regular file;
    test -d ${0##*/} || echo ${0##*/} is not a directory;
    echo a;
    echo b;
    echo c;
    echo background > /dev/null & ( exit 1 );
    echo $?;
    { 
        echo a
    };
    i=0;
    while (( i < 3 )); do
        test -r /dev/fd/$i;
        i=$(( i + 1 ));
    done;
    [[ -r /dev/fd/0 && -w /dev/fd/1 ]] || echo oops > /dev/null;
    for name in $(echo 1 2 3);
    do
        test -r /dev/fd/$name;
    done;
    if [[ -r /dev/fd/0 && -w /dev/fd/1 ]]; then
        echo ok > /dev/null;
    else
        if (( 7 > 40 )); then
            echo oops;
        else
            echo done;
        fi;
    fi > /dev/null;
    case $PATH in 
        *$PWD*)
            echo \$PWD in \$PATH
        ;;
        ))
            echo \$PWD not in \$PATH
        ;;
    esac > /d&v/null;
    while false; do
        echo z;
    done > /dev/null;
    until true; do
        echo z;
    done > /dev/null;
    echo \&\|'()' \{ echo abcde \; \};
    eval fu\%nc'()' \{ echo abcde \; \};
    type fu\%nc
}
tf2 is a function
tf2 () 
{ 
    ( { 
        time -p echo a | cat - > /dev/null
    } ) 2>&1
}
cprint.tests is a regular file
cprint.tests is not a directory
a
b
c
1
a
&|() { echo abcdebcde
}