Potential bug in Linker.c on Darwin
Found this while reading the code. I can't test this myself as I don't have a
Darwin box. The bug is in preloadObjectFile
:
// in Linker.c:preloadObjectFile
void *image;
...
image = stgMallocBytes(fileSize + misalignment, "loadObj(image)");
image += misalignment;
...
oc = mkOc(path, image, fileSize, true, NULL, misalignment);
First of all, I don't understand the intended semantics here. This increments a
void pointer which I always thought is not allowed. I don't know if this is
generating any warnings on Darwin, but it's probably worth updating this code to
cast the pointer to a non-void pointer type, increment it, and cast the result
back to void*
.
The main issue is this pointer (image
) is written to the allocated
ObjectCode
's image
field, which is freed in freePreloadObjectFile
:
static void
freePreloadObjectFile (ObjectCode *oc)
{
if (RTS_LINKER_USE_MMAP && oc->imageMapped) {
munmap(oc->image, oc->fileSize);
}
else {
stgFree(oc->image);
}
oc->image = NULL;
oc->fileSize = 0;
}
Note that we directly free the pointer oc->image
here, wihout decrementing
misalignment
that we've added in allocation site. This means we don't pass the
pointer returned by malloc
to free
, we pass bumped version of
malloc
-returned pointer, which is undefined behavior.