Add dlopen/dlclose interceptors to update CFI shadow for loaded/unloaded libraries.
As you mentioned offline, this won't correctly handle dependencies.
Perhaps the code should be building the shadow from scratch using dl_iterate_phdr every time a rebuild is needed? That way, you save needing to worry about dependencies. This may require a redesign of D16098 to avoid the copy.
A new approach.
dlclose may unmap (and dlopen may map) multiple libraries, so we actually need to do the entire dl_iterate_phdr run and update all libraries. For dlclose, we also need to detect libraries that have disappeared from the address space, so we do dl_iterate_phdr before and after dlclose and compare the results.
Looks like we already have a kMaxNumberOfModules constant defined.
I changed this interface in r257858.
Can you avoid needing to take the set difference by rebuilding from scratch?
|341 ↗||(On Diff #44918)|
Should there be a single init() function that combines set and set_phdr?
Is this function needed? Looks like you're passing a comparator to your sort function above.
The previous approach contained a data race on the shadow pointer, which can not be updated without a lock in __cfi_slowpath. That would not be acceptable performance-wise. Probably.
This new version is linux-only as it requires mremap().
Maybe assert somewhere that this is equal to GetPageSize()?
This name is unclear. It should reflect that the shadow pointer is stored here, not the shadow itself.
Please inline into ShadowBuilder::Install, as the pre-conditions of this function aren't clear without context.
Do you need to set the memory protection for shadow_ first?
You can use it now I guess.
This function is unused.
This is done now, right?
Thanks. Is it possible to construct a test case that makes sure we get the memory protection right? I was thinking that the test case would try to write to the shadow at various points (e.g. start of main, after dlopen, after dlclose), and use %expect_crash to test that the write fails.