Description
When compiling calc with clang on macOS AND with the following in Makefile.local:
CFLAGS+= -fsanitize=address
LDFLAGS+= -fsanitize=address
Running 'make chk' results calc reporting:
AddressSanitizer: heap-use-after-free
See issue.txt for details.
The problem here is that when addglobal() (see addglobal symbol.c:122):
sp->g_name = addstr(&globalnames, name);
and then addstr() does a realloc (see addstr str.c:115):
list = (char *)realloc(hp->h_list, newsize + 1);
pointers into that global block become BOGUS. Normally symbols are located within globalnames by an offset, which is correct. Something in calc is doing the wrong thing and is retaining a pointer into globalnames when it should use an offset instead.
Realloc is allowed to move the memory block, so global symbol lookup should use an OFFSET into globalnames, NOT pointers!
This bug is triggered when lots of global symbols are defined. This happens, for example, when the cal/regress.cal code is run. Because of the extensive script use, enough global symbols are defined that the initial global symbol block is filled and realloc() can move it.
Triggering this bug is highly dependent on the libc allocator, so your kilometer-age may vary. :-)
Nevertheless, the issue of realloc in calc should be carefully examined when it goes to larger blocks such as that for globalnames.
While this bug was first observed in v2.14.0.14, it appears this bug goes way back to pre-1999. Thanks to clang, we have identified this flaw and intend to correct it.
Comments, and bug fix patches are welcome!