Home > Features
- Industry-leading ASLR
- Bounds checks on kernel copies to/from userland
- Prevents direct userland access by kernel
- Prevents kernel stack overflows on 64-bit architectures
- Hardened userland memory permissions
- Random padding between thread stacks
- Hardened BPF JIT against spray attacks
- Automatically responds to exploit bruteforcing
Grsecurity has lead the way over the years in providing a proper ASLR implementation that deals with the many ways in which an attacker can influence ASLR or defeat it through system-provided information leaks and entropy reduction. In addition, the number of bits of entropy applied to randomization of each memory region is significantly higher in grsecurity compared to upstream's weaker ASLR implementation.
Blog post outlining a number of local ASLR bypasses unfixed in Linux distros for years but solved in grsecurity
Blog post from 2012 demonstrating a technique for disabling mmap randomization on suid root binaries, unfixed to date in upstream Linux
Report by MWR Labs demonstrating a few of the differences between ASLR in grsecurity (included in Gentoo Hardened in their testing) vs other distros
Configure help entry
Bounds checks on kernel copies to/from userland
This feature hardens the functions the Linux kernel uses to copy data to and from user applications. It ensures copies to/from a heap object don't exceed the object's size and that stack copies don't exceed the size of the stack frame. It further prevents modifying or leaking sensitive kernel objects via these functions.
Prevents direct userland access by kernel
Through PaX's UDEREF and KERNEXEC features, grsecurity forces any userland data access to go through an approved accessor and rejects any attempt to execute userland code in kernel context. This prevents exploitation of an entire class of vulnerabilities of which null pointer dereferences are just a subset. Another member of that larger class, commonly exploited on other OSes, involves the various magic values used throughout the kernel. Many of these magic values, when interpreted as pointers especially on 32-bit platforms, will point into userland. On a system without grsecurity, an attacker can provide specially crafted data at these addresses in order to exploit the system. Most kernel exploits released for Linux require the ability to execute or directly access data in userland -- by preventing both of these things, grsecurity has rendered useless the majority of released Linux kernel exploits. In another sense, grsecurity provides functionality equivalent to the SMEP and (unreleased) SMAP features of modern Intel processors, on older x86 processors and even the ARM platform.
Prevents kernel stack overflows on 64-bit architectures
While vulnerabilities arising through the improper use of variable-length-arrays (VLAs) and runtime stack allocation are handled automatically with a GCC plugin, grsecurity also provides a feature to prevent exploitation arising from other sources of kernel stack overflows: deep nesting and recursion. On a mainline Linux kernel, a kernel task is free to overflow its stack into adjacent heap objects in order to escalate privilege. Grsecurity places kernel stacks non-contiguously in a separate memory region on 64-bit architectures to avoid any such abuse.
Hardened userland memory permissions
Though mainline Linux now supports NX and a weaker ASLR, by default it does nothing to prevent the introduction of malicious code into a process. While initial control flow hijacking may occur through ROP, the pattern consistently seen on Windows and other OSes is that the majority of the exploit's payload is performed within allocated RWX memory. Grsecurity eliminates this weakness by default, greatly driving up the costs of exploitation and raising the bar above the capabilities of most attackers.
Random padding between thread stacks
Linux distros generally do not compile code with the -fstack-check flag to GCC, making it possible to exploit incorrectly-sized calls to alloca(). By taking advantage of pthread's behavior of allocating quickly-created thread stacks adjacent to each other, the stack of another thread can be reliably modified to achieve exploitation. Randomizing the offset between thread stacks removes the reliability of this technique, generally reducing the exploit to a crash.
Hardened BPF JIT against spray attacks
The Linux kernel contains functionality that allows it to generate machine code at runtime to speed up packet filtering and SECCOMP rules. This functionality can be abused by attackers as they are able to both pre-determine the contents of the generated machine code and also fully control certain arbitrary values within that content that permit them to execute arbitrary code through an unintended instruction sequence. Grsecurity uses a technique called "constant blinding" to prevent an attacker from having enough control over the generated machine code to launch a successful attack. Unlike upstream's attempts at resolving this problem, our solution is resistent to leaks of the location and contents of the JIT-generated code.
In the default, JIT-disabled mode, grsecurity also protects the execution environment against a corrupted interpreter buffer.
Automatically responds to exploit bruteforcing
Even if all system-level infoleak sources and methods of entropy reduction are closed down, there remains the fact that a Linux system is generally unable to prevent bruteforcing of arbitrary network services and suid/sgid binaries. Grsecurity solves this issue by forcing a delay between forks of network services being bruteforced and bans users from executing suid/sgid apps for a period of time if they cause one to crash. Grsecurity takes a similar approach to preventing repeated attempts at exploiting kernel vulnerabilities. After the first detected attempt causing an OOPS message, grsecurity bans that unprivileged user from the system until restart.
grsecurity's chroot hardening automatically converts all uses of chroot into real jails with confinement levels equivalent to containers. Processes inside a chroot will not be able to create suid/sgid binaries, see or attack processes outside the chroot jail, mount filesystems, use sensitive capabilities, or modify UNIX domain sockets or shared memory created outside the chroot jail.
Eliminates side-channel attacks against admin terminals
Demonstrating our ability to swiftly respond to new threats, this feature was developed the same day as Vladz' report on a side-channel attack against the /dev/ptmx device. While we immediately handled a more generalized form of the attack, as of over a year later, upstream Linux has still failed to prevent one of the two attack vectors explicitly listed in the original report.
Provides Trusted Path Execution
Trusted Path Execution (TPE) is an old and simple concept. It dates back to at least 1998 with route's Phrack 62 article linked below. The goal of TPE is to provide an easily-configurable and generally software compatible method of preventing unprivileged users from executing binaries they create. Grsecurity extends the idea of TPE a bit and resolves some vulnerabilities in the original design in the process (for instance, TPE is not bypassed via ld.so under grsecurity).
Hide other users' processes for unprivileged users
While the upstream kernel now provides a mount option for /proc to hide other unprivileged users' processes, grsecurity goes beyond this by hiding such information by default, hiding additional sources of sensitive information provided by the kernel in /proc, and hiding private network-related information of all users. Not only is the networking information a violation of the privacy of other users on the system, but it has also been useful in the past for TCP hijacking attacks.
Prevents ptrace-based process snooping
This feature was introduced to deal with ptrace-based userland rootkits and other malicious process hijacking. Importantly, it preserves the ability of a user to debug his/her own programs through a novel implementation that enforces a process can only attach to its children.
Prevents attackers from auto-loading vulnerable kernel modules
Your webhosting server has no need for a protocol used only in cars, or one for HAM radios, but your distro's kernel configuration likely causes modules for these to be built -- useful only for exploiting your system. While Linux distros continue to take a reactive approach (via blacklisting) to vulnerable, rarely-legitimately used modules like these, grsecurity uses a proactive approach that prevents unprivileged users from auto-loading kernel modules. The below list of example exploits for vulnerable and rarely used kernel modules is far from exhaustive, but is provided to serve as demonstration.
Prevents dumping unreadable binaries
On a normal distro kernel, it's not possible to allow a user to execute a program without also giving away the full contents of the program's binary image. While direct reads are denied, a user can ptrace themselves and then execute the binary, using ptrace to extract out the entire mapped contents of the binary image -- even if that binary is setuid root. This information leak can be useful in creating reliable exploits against custom-compiled binaries. This weakness was abused by Jason Donenfeld, for example, in his exploit for the /proc/pid/mem kernel vulnerability.
Enforces consistent multithreaded privileges
Though glibc wraps calls to setuid() and setgid() with magic signals that cause other threads in a process to change their credentials as well, other libcs and multithreaded applications in other languages do not do this, leading to unexpected vulnerable results of a thread running as root that the developers believe is running unprivileged. Since it's also conceptually wrong for threads sharing the same address space to be running with radically different privilege, grsecurity enforces glibc's behavior at the kernel level despite what language or libc is involved in userland.
Denies access to overly-permissive IPC objects
This feature was developed in response to research done by Portcullis Labs who surveyed use of shared memory in Linux software with surprising results -- many were unnecessarily granting all users on the system the ability to read and or write their created shared memory. Since in many cases this can result in security vulnerabilities, grsecurity locks down access to overly-permissive shared memory and other IPC objects in such a way that does not impact normal operations.
Automatic full system policy learning
Grsecurity's RBAC has provided the very first learning system that can automatically generate least-privilege full system policies without manual configuration. While the default learning heuristics will provide secure results for most users while predicting future access needs, it also supports a simple human-readable configuration file to drive the policy generation. Have a directory specific to your system that you wish to ensure is protected by policy? A single line in the configuration file will create a security boundary around any process that reads or writes to files in that directory. Users will find that in most cases, full system learning will produce a more secure policy than one created by hand.
Human-readable policies and logs
If you've ever developed SELinux policies, grsecurity's RBAC policies will be a breath of fresh air. Our policies are similar in appearance to those of AppArmor, though more intuitive. Logs display full paths for the violating process and its parent and describes the nature of the violation in an easily-understandable way. You won't need to be an expert on system call names and rummage through logs stuffed into the same restrictive template to determine the reason for a policy violation in grsecurity's RBAC system.
The organization of grsecurity's RBAC policies makes intuitive sense. Roles apply to users or groups (with allowance for "special" roles that can be entered with or without authentication). These roles contain a collection of subjects which describe policies for binaries and scripts on the system. Subjects contain a collection of objects, which are the files, capabilities, network sockets, and resources a process is permitted to use. Combined with the human-readable policies, many users find they are able to jump right in to creating meaningful security policies either through full system learning or by using full system learning as a starting example policy.
Automated policy analysis
Unlike other access control systems, grsecurity's RBAC was not designed to be an all-permissive framework -- it has the specific purpose of locking down access to the entire system. Because it has a specific goal, it allows us to implement mandatory policy analysis that catches administrator mistakes and prevents an administrator from deploying a policy that would provide a false sense of security. Any errors found in the policy are described with human-readable, meaningful explanations of what kinds of attacks would be possible if the policy were allowed to be loaded (as it would be in other access control systems).
Grsecurity does not use LSM and thus is not constrained by the set of hooks LSM provides. With this freedom it is able to implement a number of unconventional features not possible in any LSM. Grsecurity allows overriding and auto-learning of resource limits on a per-subject basis, provides per-subject limits on the number of times a service can crash in a given time interval, can limit access to roles by IP address, tags policy violation logs with the IP address of the originator of the violation, provides mandatory control over per-subject PaX flags, supports policies on individual scripts run directly, and many more features not available elsewhere.
Stackable with LSM
As grsecurity has never used LSM, it does not suffer from a major problem that LSM has been unable to resolve in over 14 years: it does not permit multiple LSMs to be enabled at the same time. Thus while SELinux's default policies cannot be used in conjunction with AppArmor, grsecurity can be used in combination with SELinux, AppArmor, or any other LSM if such a requirement exists.
Randomized kernel structure layouts
The RANDSTRUCT plugin forces some exploits into requiring additional information leaks to achieve reliability. It does this by randomizing the layout of sensitive selected kernel structures as well as automatically randomizing the layout of all structures comprised purely of function pointers -- a common target for exploits.
Prevents integer overflows in size arguments
Integer overflows are a common bug class in the kernel. This feature was first realized as a clever macro to deal with overflows occuring in size expressions of kernel memory allocators, but was replaced and greatly expanded in scope by Emese Revfy with what is now our largest GCC plugin. This powerful plugin can detect and prevent exploitation of a wide range of integer overflow and integer truncation bugs that are likely to result in exploitable conditions.
Log demonstrating size_overflow plugin preventing exploitation of a $40,000 vulnerability at Pwnium 3 (CVE-2013-0913)
Emese Revfy's blog post on the size_overflow plugin
CVE-2013-0914: local ASLR infoleak detected by the plugin
CVE-2013-2141: kernel infoleak discovered by the plugin
Configure help entry
Adds entropy at early boot and runtime
Providing enough randomness, especially at early boot, has been a constant struggle for Linux. While on the Intel platform, Ivy Bridge and newer processor models that support RDRAND generally eliminate the problem of entropy starvation at early boot and runtime, older processors and those of other architectures continue to be plagued by this problem. The demonstrable effects of this include weak private keys on embedded systems, weak randomness on VM guests, predictable stack canaries, and more. PaX's latent entropy plugin included in grsecurity addresses the lack of randomness by modifying the instruction streams of functions called only during boot as well as some specific functions at runtime that perform some unpredictable computations from the perspective of an attacker. These functions are modified to produce a nondeterministic value based on the flow of execution. At several points in the boot process and at runtime, this pseudorandom value is mixed in to the entropy pool. Further, a kernel compiled with this plugin will have the various random pools in the kernel initialized at compile-time to random contents.
Makes read-only sensitive kernel structures
For some years, grsecurity had maintained a large patch that systematically constified a few dozen structure types used frequently in the kernel -- collections of function pointers, or so-called "ops structures". This patch, weighing in at over 1MB, became time-consuming to maintain and upstream kernel developers did not accept the patch wholesale (responsive maintainers adopted patches specific to their domain, but many unresponsive maintainers did not). Creation of the CONSTIFY plugin allowed us to generalize the approach and apply it to hundreds of additional structure types, currently causing up to 75% of function pointers in the kernel image to be made read-only.
Ensures all kernel function pointers point into the kernel
This plugin supplements the protection provided by PaX's KERNEXEC feature on the X64 architecture. While on i386 KERNEXEC is able to prevent execution of userland code using segmentation, that is not possible on X64. This plugin forces the upper bit on in all function pointers and return addresses dereferenced by the kernel. This doesn't impact legitimate kernel code, but causes attempts to return to userland code to result in a non-canonical address that will cause a GPF upon access. Modulo attacks on kernel paging structures, this feature is not needed if PaX's UDEREF is enabled.
Prevents leaking of stack data from previous syscalls
Information leaks of kernel stack data are the most common type of leaks in the kernel and potentially the most dangerous. The reason for this is that the data arising from an uninitialized structure field can possibly come from data on the kernel stack from a previous system call invocation. By carefully choosing a system call to leave stale data on the stack, an attacker can leak the addresses to a wide number of sensitive kernel structures. The STACKLEAK plugin addresses this issue by clearing the portion of the kernel stack that was used during a system call before returning to userland. This ensures that if any leak of an uninitialized field is possible, it must come from a previously-called function in the current system call. This plugin also prevents dynamic stack-based allocation in the kernel from overflowing the kernel stack, which would normally permit an attacker to corrupt an adjacent memory object in order to exploit the system.