The glibc dynamic loader rounds the size down, so without this the loader
will fail to change the memory protection for the last page.
Details
Diff Detail
- Build Status
Buildable 2548 Build 2548: arc lint + arc unit
Event Timeline
lld/ELF/Writer.cpp | ||
---|---|---|
1452–1453 | For reference the FreeBSD rtld algorithm is: obj->relro_page = obj->relocbase + trunc_page(ph->p_vaddr); obj->relro_size = round_page(ph->p_memsz); https://svnweb.freebsd.org/base/head/libexec/rtld-elf/rtld.c?annotate=310422#l1334 |
- Add a note about FreeBSD
lld/ELF/Writer.cpp | ||
---|---|---|
1452–1453 | Thanks. round_page appears to be system-specific but always seems to round up [0]. I've added a note to the comment. [0] https://github.com/freebsd/freebsd/search?utf8=%E2%9C%93&q=%22define+round_page%22&type=Code |
To test my change D28272, I compiled and ran a small test program (essentially the one in figure 2 in the referenced paper). I was surprised to find that even after the copy relocation was moved to relro the program terminated without segfaulting. An strace revealed that the loader wasn't calling mprotect on the relro region at all, which turned out to be because it was smaller than the page size.
For reference the FreeBSD rtld algorithm is:
https://svnweb.freebsd.org/base/head/libexec/rtld-elf/rtld.c?annotate=310422#l1334