Name: John Moser E-Mail: firstname.lastname@example.org
JohnMoser is a security hobbyist focused on PaX, GrSecurity, ProPolice, and supporting infrastructure such as PIE (Position Independent Executables) to support the ASLR (Address Space Layout Randomization) supplied by PaX. All this will be touched very briefly here in case JohnMoser ever says something that confuses you.
PaX prevents several types of attacks using advanced memory protection schemes. Memory protections become privileged, and address space is made non-guaranteed by injecting entropy into the layout with an effect of relatively large magnitude.
PaX uses memory protections to prevent code injection (shellcode) by separating writability and executability strictly. On most architectures, PaX uses the CPU supplied NX "No Execute" memory protection; 32 bit x86 (i386) does not have this. PaX supplies an NX bit on x86 in low overhead using one of two methods:
- SEGMEXEC, which used VMA Mirroring, which is very fast but halves the available Virtual Address Space. VMA Mirroring had a bad implimentation which caused a massive privilege escallation security flaw for 2.5 years since its creation; however, the design was not fundamentally flawed and the bug was fixed.
The restrictions applied by PaX are very simply explained:
- ELF .text relocations are automatically detected and the creation of transitionable memory in relation to the relocation is allowed. Operations related to the relocation are automatically and accurately detected.
- Aside from (1), a mapping may not be created with protections including both PROT_WRITE and PROT_EXEC.
- Aside from (1), a mapping may not be transitioned from any state to include the PROT_WRITE and PROT_EXEC protections both at the same time.
- Aside from (1), a mapping may not be transitioned from a state not including the PROT_EXEC protection to a state include the PROT_EXEC protection.
A few simple rules to remove PROT_EXEC or PROT_WRITE from generic mappings where appropriate are also in place; for example, file backed mappings requesting PROT_EXEC have PROT_WRITE removed, as it is assumed they are libraries being mapped PROT_READ|PROT_WRITE|PROT_EXEC (RWX). By this design, tasks not requiring runtime code generation typically "just work," but don't haphazardly create memory which would allow for runtime code generation such as an executable stack where shellcode may be injected.
PaX also supplies high-entropy ASLR for all parts of memory -- stack, heap/bss, data, library, library bss, library data, anything made with mmap(), and also for the executable base for fixed position ET_EXEC executables using VMA Mirroring (this is called RANDEXEC). RANDEXEC is very slow and bad and causes some things to crash; distributions should make all executables PIE (ET_DYN, like libraries). GDB dislikes PIE right now, but there are patches to fix that floating around.
The effects of the PaX randomization are simply explained as well.
- CPU cache line misses are reduced to a degree, as mappings are often not in the same place from process to process; for example, the mapping for the stack in two tasks may be in different virtual address spaces, resulting in context switches between the tasks not requiring the immediate invalidation of the TLB entries from the previous running task. If the previous task comes back on the CPU, its TLB and cache entries may still exist, avoiding a few faults into CPU cache; if the TLB or cache fills, or a task is switched to which attempts to access a mapping at the same virtual address, the cache entry and TLB entry are removed as normal.
- Injecting shellcode into the stack becomes extremely difficult and often possible only by extreme luck. The location of the stack is non-guaranteed. On 32-bit x86, the stack (typically 8MiB) may exist at any point in a 256MiB area of virtual address space, aligned to 16 bytes; on 64-bit x86-64, the stack may exist somewhere in 64GiB of virtual address space, aligned to 16 bytes. Not only does this demand that you locate the stack; but stack stuffing with NOP instructions does not significantly increase the chances of hitting the right address.
- Returning to preexisting code becomes extremely difficult and often possible only by extreme luck. The location of all libraries is offset by a random distance up to 256MiB, aligned to the size of a page (typically 4KiB). If the main executable is PIC, then that is also offset in the same area.
- Utilizing user controlled data in the heap for an attack or an information leak is difficult and often possible only by extreme luck. The base of the heap is offset by a small random value; however, with a PIC main executable, the entropy is greatly increased.
GrSecurity is a more complete kernel security solution built around PaX. It brings a Mandatory Access Control system and enhances a bunch of stuff, notably chroot() jails. GrSecurity provides options for extremely tight but non-intrusive information restrictions, such as restricting information about processes to the current user and restricting access to /proc/cpuinfo and the like.
GrSecurity has a few major advantages over PaX on a typical desktop:
- Nobody cares about your home desktop; however, attackers do exist in automated form called "Worms." If Linux gains popularity, such worms will predictably begin to appear targetting it.
GrSecurity supplies chroot() jail restrictions which can prevent the exploitation of chroot()ed servers. If the home user is running a local Squid or bind9 server to speed his connection up and it gets broken into, the attacker may be left in a chroot() jail which is easily broken out of by mounting procfs and figuring out what's /, then mounting / and escaping the jail. Even root access doesn't allow escape of a GrSecurity-hardened chroot() jail so easily.
GrSecurity supplies linking restrictions which are non-invasive in typical situations, but which catch some serious bad logic in the usage of temporary files. Some privileged processes create temporary files directly in /tmp; if done improperly, race conditions occur which allow attackers to destructively overwrite files that the process owner can access. GrSecurity linking restrictions prevent this.
Although often useless to attackers, the information in /proc that GrSecurity restricts is also often useless to a typical desktop user. There's no harm in walling it off, so it can be considered a Good Thing if you consider this data as being placed on a scheme where confidentiality and availability sit adjacent to eachother; that is, if availability is not needed, confidentiality should be guaranteed.
On a server the advantages are a bit higher:
- A Mandatory Access Control system is supplied to refine information assurance.
- Brute force attacks to break through PaX ASLR are deterred, although they become Denial of Service attacks.
- A greater deal of logging and auditing information is available, including information about the ipaddress related to a process spawned through a remote connection.
ProPolice and LibSafe
ProPolice makes buffer overflows on the stack inable to damage anything but other buffers (potentially) inside the same stack frame before it is used, although notably they can damage things outside the stack frame that's being pointed to (by pointers, yes). LibSafe catches any stack frame boundary crossing overflows in common standard C string functions immediately and thus makes a good compliment to ProPolice. Both will detect the damage and abort the program before any malicious attack can happen etc.
Other that these security things, JohnMoser has thought about memory allocators and how they need to be rewritten to handle MemoryReduction. He has written test programs that allocate 100M of memory with malloc() and free() all but the highest, then sleep(), resulting in a program holding a 100M RSS with about a kilobyte of working set he requested if that. Once the highest allocation is freed 15 seconds later, the program sleeps for a minute, holding barely any RSS usage suddenly.
User Interface Stuff
JohnMoser is also big on usability, though he's a console guy. Flashy, easy-to-use programs are good.