I believe I recently "fixed" #132. But the underlying problem was that preload.c is a very confusing file. It dates from a long time ago, before we had systrapping, when we relied on preloading to catch mmap and the like. But since that did not catch all mmap calls, we added systrapping. Yet we kept this file because it was doing some other things too, including relating to malloc/alloca instrumentation. Why do its functions exist?
__assert_fail (protected) -- reentrancy avoidance (this is an mmap-free implementation)
abort (protected; debug-only) -- for debugging, delay termination of the process
malloc_or_alloca_usable_size -- obsolete, but retained for debugging
malloc_usable_size -- receives cross-DSO calls to the global malloc_usable_size (global malloc et al are in user2hook.o, but that does not generate a malloc_usable_size hook)
mmap -- trap-free hooking with nudging
mmap64 -- trap-free hooking with nudging
munmap -- trap-free hooking
mremap -- trap-free hooking with nudging
signal -- prevent SIGILL handler clobbering -- should be systrap
sigaction -- prevent SIGILL handler clobbering -- should be systrap
memcpy -- to support shadow memory (bulk copy notification)
memmove -- to support shadow memory (bulk copy notification)
Now that we have systrapping, preload.c exists mainly to provide a no-trap path to these system calls. How important is that? We could just call the libc and let it trap.
The bug was that we were doing that already, in addition! Our preloaded mremap was calling the real libc, not a raw syscall. So it was being trapped, and hooked there. But also, our preload wrapper was running the hook. The hook running twice was not good for mremap. It is harmless for munmap but was happening for that too.
I believe I recently "fixed" #132. But the underlying problem was that
preload.cis a very confusing file. It dates from a long time ago, before we had systrapping, when we relied on preloading to catchmmapand the like. But since that did not catch allmmapcalls, we added systrapping. Yet we kept this file because it was doing some other things too, including relating to malloc/alloca instrumentation. Why do its functions exist?__assert_fail(protected) -- reentrancy avoidance (this is an mmap-free implementation)abort(protected; debug-only) -- for debugging, delay termination of the processmalloc_or_alloca_usable_size-- obsolete, but retained for debuggingmalloc_usable_size-- receives cross-DSO calls to the globalmalloc_usable_size(globalmallocet al are inuser2hook.o, but that does not generate amalloc_usable_sizehook)mmap-- trap-free hooking with nudgingmmap64-- trap-free hooking with nudgingmunmap-- trap-free hookingmremap-- trap-free hooking with nudgingsignal-- preventSIGILLhandler clobbering -- should be systrapsigaction-- preventSIGILLhandler clobbering -- should be systrapmemcpy-- to support shadow memory (bulk copy notification)memmove-- to support shadow memory (bulk copy notification)Now that we have systrapping,
preload.cexists mainly to provide a no-trap path to these system calls. How important is that? We could just call the libc and let it trap.The bug was that we were doing that already, in addition! Our preloaded
mremapwas calling the real libc, not a raw syscall. So it was being trapped, and hooked there. But also, our preload wrapper was running the hook. The hook running twice was not good formremap. It is harmless formunmapbut was happening for that too.