[arch-dev-public] Proposal: enabling full ASLR on x86_64 via hardening-wrapper

Arch's single biggest security weakness is that it's not benefiting from address space layout randomization (ASLR). Fixing this issue would be a major step towards being a leader in this area. Many distributions enable ASLR, stack protector, etc. for a chosen set of "security critical" stuff but very few enable them across the board. Executable permissions on memory (NX bit) prevent an attacker from directly injecting code via memory corruption vulnerabilities. It's only truly useful in combination with ASLR because if the existing code is in a known location it can be reused by the attacker.[1] [1] https://en.wikipedia.org/wiki/Return-oriented_programming The cost of ASLR is that it requires position independent (relocatable) code (PIC), as is already required for all code in dynamic libraries. On i686, PIC has a significant cost (up to 30% or more). The vanilla kernel also lacks emulation of the NX bit and has no brute force protection to make up for the smaller 32-bit address space. Only the subset of users using grsecurity / PaX would truly benefit. I don't care about i686 anyway. On x86_64, there's hardware support for position independent code so it's essentially free. It does currently cost ~1% due to linker and compiler limitations (indirection to access globals) but this has been fixed in the binutils/gcc master branches. It's much cheaper than the -fstack-protector-strong switch which we're already using, and the security value is higher. The only real barrier to enabling it is the lack of support in GCC for simply flipping it on by default. Library code is already built with -fPIC and is then linked with -shared. Full ASLR requires building the executable code with -fPIE (or -fPIC, which isn't as cheap) and then linking with -pie. There are two approaches to this: 1) Patching the toolchain's spec files (Hardened Gentoo) 2) Wrapper scripts for clang/gcc/ld.bfd/ld.gold (Debian, Fedora, Ubuntu) Upstream hasn't accepted various forms of the first option, so I don't think it's a suitable approach for us. The hardening-wrapper package implements the second option and also enforces our existing hardening flags for build systems ignoring CFLAGS/CXXFLAGS/LDFLAGS. All it would take is either adding hardening-wrapper to the default devtools packages list or making it part of base-devel. Here's an example with a small C program: strcat at thinktank i ~ master % cat test.c #include <stdio.h> static void foo() {} static int bar = 5; int main(void) { int baz = 5; printf("function: %p, data: %p, stack: %p

", foo, &bar, &baz); return 0; } Without the hardening-wrapper package installed: strcat at thinktank i ~ master % gcc test.c -o test strcat at thinktank i ~ master % checksec --file test RELRO STACK CANARY NX PIE RPATH RUNPATH FILE No RELRO No canary found NX enabled No PIE No RPATH No RUNPATH test strcat at thinktank i ~ master % ./test function: 0x400506, data: 0x600980, stack: 0x7fff12ba3a7c strcat at thinktank i ~ master % ./test function: 0x400506, data: 0x600980, stack: 0x7fffa47958fc With the hardening-wrapper package installed: strcat at thinktank i ~ master % gcc test.c -o test strcat at thinktank i ~ master % checksec --file test RELRO STACK CANARY NX PIE RPATH RUNPATH FILE Partial RELRO Canary found NX enabled PIE enabled No RPATH No RUNPATH test strcat at thinktank i ~ master % ./test function: 0x7f267e569800, data: 0x7f267e76a050, stack: 0x7fff3ee5ea14 strcat at thinktank i ~ master % ./test function: 0x7f6a06b3e790, data: 0x7f6a06d3f048, stack: 0x7fff76a891bc The defaults in /etc/hardening-wrapper.conf can be overridden via env variables: strcat at thinktank i ~ master % HARDENING_STACK_PROTECTOR=0 gcc test.c -o test strcat at thinktank i ~ master % checksec --file test RELRO STACK CANARY NX PIE RPATH RUNPATH FILE Partial RELRO No canary found NX enabled PIE enabled No RPATH No RUNPATH test The need to use wrapper scripts is a bit ugly, but I think it's a nicer approach than tracking down and patching dozens of build systems to respect CFLAGS/LDFLAGS and it's the only realistic way to enable PIE. The only alternative short of patching GCC spec files is manually specifying the flags in thousands of executable-only packages, and patching any build system producing both binaries and libraries (yikes!). -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature URL: <https://lists.archlinux.org/pipermail/arch-dev-public/attachments/20141218/1f702ab3/attachment.bin>