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
}