[PATCH] D64903: [ELF] Pad the last page of last PF_X PT_LOAD with traps when -z separate-code is specified
Petr Hosek via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 19 00:20:18 PDT 2019
phosek added a comment.
I have several points on this.
First, all the differences are demonstrated on uncompressed binaries, but if the binary size was really important for you, you'd always use compression in practice. For example, on Fuchsia where binary size is critical, we never leave binaries uncompressed on disk. To demonstrate this, I've used the same example that @MaskRay used:
$ echo 'int main() {}' > t.c
$ clang --target=aarch64-linux-gnu --sysroot=path/to/sysroot t.c -o t
$ stat -c %s t
201136
$ lz4 t t.lz4
$ stat -c %s t.lz4
4265
$ zstd t -o t.zstd
$ stat -c %s t.zstd
2435
With D64906 <https://reviews.llvm.org/D64906> and D64930 <https://reviews.llvm.org/D64930> applied:
$ stat -c %s t
70064
$ stat -c %s t.lz4
3730
$ stat -c %s t.zstd
2401
With zstd (which is default compressor used by Fuchsia), the difference between the two schemes is 34 bytes.
Second, with `-z noseparate-code`, you'll end up with a partial page wasting additional memory at runtime So the difference between `-z separate-code` and `-z noseparate-code` isn't really about security vs space as is presented in the description, it's primarily a trade-off between memory and disk space. We can reclaim most disk space loss using compression as shown above, but we cannot reclaim the memory loss.
Third, there's the security aspect. I agree that the reduction of the number of ROP gadgets is limited, but that doesn't mean we shouldn't do it. I've consulted this change with our security team today and their response is that we always want `-z separate-code`! Why? It's a basic security hygiene, best practice, defense in depth kind of measure. It's the same reason why we fill space between functions with traps, why we use stack protectors, why we use ASLR, etc. We have known attacks against each of those mechanisms, and not all of them have proven as effective as was believed in the past, but that doesn't mean we're going to disable them. The same applies here.
With all that being said, if there's a combination of flag that would allow preserving the current behavior, we'd set those in our driver like we already do for `-z rodynamic` <https://github.com/llvm/llvm-project/blob/master/clang/lib/Driver/ToolChains/Fuchsia.cpp#L50>, so I'm not going to block this change. However, I'd still much rather see the `-z separate-code` being the default because otherwise we're going to loose the advantages I described above (memory savings, security) on other platforms like Linux.
One potential solution might be to control the default behavior with a CMake option which is similar to the solution also used in binutils by ld (`--enable-separate-code`/`--disable-separate-code`). While this isn't being used to control the defaults in lld at the moment, it's used elsewhere in LLVM for that purpose (e.g. `ENABLE_LINKER_BUILD_ID` <https://github.com/llvm/llvm-project/blob/master/clang/CMakeLists.txt#L231> or `ENABLE_X86_RELAX_RELOCATIONS` <https://github.com/llvm/llvm-project/blob/master/clang/CMakeLists.txt#L233> in Clang) and enables each toolchain vendor to choose their defaults.
Repository:
rLLD LLVM Linker
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D64903/new/
https://reviews.llvm.org/D64903
More information about the llvm-commits
mailing list