Skip to content

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.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information