From Fedora Project Wiki
mNo edit summary
 
(One intermediate revision by one other user not shown)
Line 2: Line 2:


A useful hardening feature is to have a page in the data segment which you can make read-only after initialization (using <code>mprotect</code>).  Assuming the data is accessed using PC-relative instructions, there is no way that malicious code can patch it (without calling <code>mprotect</code> again first).  For this to work, that data needs to be aligned on a page boundary, otherwise the <code>protect</code> call might make unrelated variables read-only.  We currently do not encode the page size in the executable.  There are some claims it is possible to guess it from the program header, but that seems to be a bit of a stretch.
A useful hardening feature is to have a page in the data segment which you can make read-only after initialization (using <code>mprotect</code>).  Assuming the data is accessed using PC-relative instructions, there is no way that malicious code can patch it (without calling <code>mprotect</code> again first).  For this to work, that data needs to be aligned on a page boundary, otherwise the <code>protect</code> call might make unrelated variables read-only.  We currently do not encode the page size in the executable.  There are some claims it is possible to guess it from the program header, but that seems to be a bit of a stretch.
[[Toolchain/Watermark/HardeningStackCheck|Stack overflow checking]] depends on the page size, too.


Similarly, for figuring out if a binary has indeed full RELRO, we need to know if the dynamic linker can actually make the GOT read-only because it does not overlap with data which has to be read-write.  Without explicit page size information, it is not possible to tell whether lack of RELRO due to misalignment is a static linker bug or a missing linker flag.
Similarly, for figuring out if a binary has indeed full RELRO, we need to know if the dynamic linker can actually make the GOT read-only because it does not overlap with data which has to be read-write.  Without explicit page size information, it is not possible to tell whether lack of RELRO due to misalignment is a static linker bug or a missing linker flag.
The page size is chosen by the operating system implementation of execve(), and is passed to the program as ElfXX_auxv[{AT_PAGESZ}].a_val.  On PowerPC64, it already varies: 64KiB or 4KiB.  The default is 4KiB for 32-bit programs, and 64KiB for 64-bit programs.  However, qemu-ppc64 always chooses 4KiB, even for 64-bit programs.  Various MIPS chips and ARM chips also have differing page sizes, and the same compiled-and-linked executable binary program must run on all chips that implement the architecture.


[[Category:Toolchain/Watermark/Provisional]]
[[Category:Toolchain/Watermark/Provisional]]

Latest revision as of 16:31, 27 September 2017

Page Size

A useful hardening feature is to have a page in the data segment which you can make read-only after initialization (using mprotect). Assuming the data is accessed using PC-relative instructions, there is no way that malicious code can patch it (without calling mprotect again first). For this to work, that data needs to be aligned on a page boundary, otherwise the protect call might make unrelated variables read-only. We currently do not encode the page size in the executable. There are some claims it is possible to guess it from the program header, but that seems to be a bit of a stretch.

Stack overflow checking depends on the page size, too.

Similarly, for figuring out if a binary has indeed full RELRO, we need to know if the dynamic linker can actually make the GOT read-only because it does not overlap with data which has to be read-write. Without explicit page size information, it is not possible to tell whether lack of RELRO due to misalignment is a static linker bug or a missing linker flag.

The page size is chosen by the operating system implementation of execve(), and is passed to the program as ElfXX_auxv[{AT_PAGESZ}].a_val. On PowerPC64, it already varies: 64KiB or 4KiB. The default is 4KiB for 32-bit programs, and 64KiB for 64-bit programs. However, qemu-ppc64 always chooses 4KiB, even for 64-bit programs. Various MIPS chips and ARM chips also have differing page sizes, and the same compiled-and-linked executable binary program must run on all chips that implement the architecture.