summaryrefslogtreecommitdiff
path: root/Documentation/security/self-protection.txt
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2017-05-13 04:51:41 -0700
committerJonathan Corbet <corbet@lwn.net>2017-05-18 10:30:23 -0600
commitc2ed6743434d1d9ef49b044c6bdfd6ac1ce140a2 (patch)
tree3474f0927898a416ceb19b3ef0a5588ea0b7da11 /Documentation/security/self-protection.txt
parentaf777cd1b83e95138e7285fde87c795ef0ae7c4d (diff)
doc: ReSTify self-protection.txt
This updates the credentials API documentation to ReST markup and moves it under the security subsection of kernel API documentation. Signed-off-by: Kees Cook <keescook@chromium.org> Signed-off-by: Jonathan Corbet <corbet@lwn.net>
Diffstat (limited to 'Documentation/security/self-protection.txt')
-rw-r--r--Documentation/security/self-protection.txt275
1 files changed, 0 insertions, 275 deletions
diff --git a/Documentation/security/self-protection.txt b/Documentation/security/self-protection.txt
deleted file mode 100644
index 141acfebe6ef..000000000000
--- a/Documentation/security/self-protection.txt
+++ /dev/null
@@ -1,275 +0,0 @@
-# Kernel Self-Protection
-
-Kernel self-protection is the design and implementation of systems and
-structures within the Linux kernel to protect against security flaws in
-the kernel itself. This covers a wide range of issues, including removing
-entire classes of bugs, blocking security flaw exploitation methods,
-and actively detecting attack attempts. Not all topics are explored in
-this document, but it should serve as a reasonable starting point and
-answer any frequently asked questions. (Patches welcome, of course!)
-
-In the worst-case scenario, we assume an unprivileged local attacker
-has arbitrary read and write access to the kernel's memory. In many
-cases, bugs being exploited will not provide this level of access,
-but with systems in place that defend against the worst case we'll
-cover the more limited cases as well. A higher bar, and one that should
-still be kept in mind, is protecting the kernel against a _privileged_
-local attacker, since the root user has access to a vastly increased
-attack surface. (Especially when they have the ability to load arbitrary
-kernel modules.)
-
-The goals for successful self-protection systems would be that they
-are effective, on by default, require no opt-in by developers, have no
-performance impact, do not impede kernel debugging, and have tests. It
-is uncommon that all these goals can be met, but it is worth explicitly
-mentioning them, since these aspects need to be explored, dealt with,
-and/or accepted.
-
-
-## Attack Surface Reduction
-
-The most fundamental defense against security exploits is to reduce the
-areas of the kernel that can be used to redirect execution. This ranges
-from limiting the exposed APIs available to userspace, making in-kernel
-APIs hard to use incorrectly, minimizing the areas of writable kernel
-memory, etc.
-
-### Strict kernel memory permissions
-
-When all of kernel memory is writable, it becomes trivial for attacks
-to redirect execution flow. To reduce the availability of these targets
-the kernel needs to protect its memory with a tight set of permissions.
-
-#### Executable code and read-only data must not be writable
-
-Any areas of the kernel with executable memory must not be writable.
-While this obviously includes the kernel text itself, we must consider
-all additional places too: kernel modules, JIT memory, etc. (There are
-temporary exceptions to this rule to support things like instruction
-alternatives, breakpoints, kprobes, etc. If these must exist in a
-kernel, they are implemented in a way where the memory is temporarily
-made writable during the update, and then returned to the original
-permissions.)
-
-In support of this are CONFIG_STRICT_KERNEL_RWX and
-CONFIG_STRICT_MODULE_RWX, which seek to make sure that code is not
-writable, data is not executable, and read-only data is neither writable
-nor executable.
-
-Most architectures have these options on by default and not user selectable.
-For some architectures like arm that wish to have these be selectable,
-the architecture Kconfig can select ARCH_OPTIONAL_KERNEL_RWX to enable
-a Kconfig prompt. CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT determines
-the default setting when ARCH_OPTIONAL_KERNEL_RWX is enabled.
-
-#### Function pointers and sensitive variables must not be writable
-
-Vast areas of kernel memory contain function pointers that are looked
-up by the kernel and used to continue execution (e.g. descriptor/vector
-tables, file/network/etc operation structures, etc). The number of these
-variables must be reduced to an absolute minimum.
-
-Many such variables can be made read-only by setting them "const"
-so that they live in the .rodata section instead of the .data section
-of the kernel, gaining the protection of the kernel's strict memory
-permissions as described above.
-
-For variables that are initialized once at __init time, these can
-be marked with the (new and under development) __ro_after_init
-attribute.
-
-What remains are variables that are updated rarely (e.g. GDT). These
-will need another infrastructure (similar to the temporary exceptions
-made to kernel code mentioned above) that allow them to spend the rest
-of their lifetime read-only. (For example, when being updated, only the
-CPU thread performing the update would be given uninterruptible write
-access to the memory.)
-
-#### Segregation of kernel memory from userspace memory
-
-The kernel must never execute userspace memory. The kernel must also never
-access userspace memory without explicit expectation to do so. These
-rules can be enforced either by support of hardware-based restrictions
-(x86's SMEP/SMAP, ARM's PXN/PAN) or via emulation (ARM's Memory Domains).
-By blocking userspace memory in this way, execution and data parsing
-cannot be passed to trivially-controlled userspace memory, forcing
-attacks to operate entirely in kernel memory.
-
-### Reduced access to syscalls
-
-One trivial way to eliminate many syscalls for 64-bit systems is building
-without CONFIG_COMPAT. However, this is rarely a feasible scenario.
-
-The "seccomp" system provides an opt-in feature made available to
-userspace, which provides a way to reduce the number of kernel entry
-points available to a running process. This limits the breadth of kernel
-code that can be reached, possibly reducing the availability of a given
-bug to an attack.
-
-An area of improvement would be creating viable ways to keep access to
-things like compat, user namespaces, BPF creation, and perf limited only
-to trusted processes. This would keep the scope of kernel entry points
-restricted to the more regular set of normally available to unprivileged
-userspace.
-
-### Restricting access to kernel modules
-
-The kernel should never allow an unprivileged user the ability to
-load specific kernel modules, since that would provide a facility to
-unexpectedly extend the available attack surface. (The on-demand loading
-of modules via their predefined subsystems, e.g. MODULE_ALIAS_*, is
-considered "expected" here, though additional consideration should be
-given even to these.) For example, loading a filesystem module via an
-unprivileged socket API is nonsense: only the root or physically local
-user should trigger filesystem module loading. (And even this can be up
-for debate in some scenarios.)
-
-To protect against even privileged users, systems may need to either
-disable module loading entirely (e.g. monolithic kernel builds or
-modules_disabled sysctl), or provide signed modules (e.g.
-CONFIG_MODULE_SIG_FORCE, or dm-crypt with LoadPin), to keep from having
-root load arbitrary kernel code via the module loader interface.
-
-
-## Memory integrity
-
-There are many memory structures in the kernel that are regularly abused
-to gain execution control during an attack, By far the most commonly
-understood is that of the stack buffer overflow in which the return
-address stored on the stack is overwritten. Many other examples of this
-kind of attack exist, and protections exist to defend against them.
-
-### Stack buffer overflow
-
-The classic stack buffer overflow involves writing past the expected end
-of a variable stored on the stack, ultimately writing a controlled value
-to the stack frame's stored return address. The most widely used defense
-is the presence of a stack canary between the stack variables and the
-return address (CONFIG_CC_STACKPROTECTOR), which is verified just before
-the function returns. Other defenses include things like shadow stacks.
-
-### Stack depth overflow
-
-A less well understood attack is using a bug that triggers the
-kernel to consume stack memory with deep function calls or large stack
-allocations. With this attack it is possible to write beyond the end of
-the kernel's preallocated stack space and into sensitive structures. Two
-important changes need to be made for better protections: moving the
-sensitive thread_info structure elsewhere, and adding a faulting memory
-hole at the bottom of the stack to catch these overflows.
-
-### Heap memory integrity
-
-The structures used to track heap free lists can be sanity-checked during
-allocation and freeing to make sure they aren't being used to manipulate
-other memory areas.
-
-### Counter integrity
-
-Many places in the kernel use atomic counters to track object references
-or perform similar lifetime management. When these counters can be made
-to wrap (over or under) this traditionally exposes a use-after-free
-flaw. By trapping atomic wrapping, this class of bug vanishes.
-
-### Size calculation overflow detection
-
-Similar to counter overflow, integer overflows (usually size calculations)
-need to be detected at runtime to kill this class of bug, which
-traditionally leads to being able to write past the end of kernel buffers.
-
-
-## Statistical defenses
-
-While many protections can be considered deterministic (e.g. read-only
-memory cannot be written to), some protections provide only statistical
-defense, in that an attack must gather enough information about a
-running system to overcome the defense. While not perfect, these do
-provide meaningful defenses.
-
-### Canaries, blinding, and other secrets
-
-It should be noted that things like the stack canary discussed earlier
-are technically statistical defenses, since they rely on a secret value,
-and such values may become discoverable through an information exposure
-flaw.
-
-Blinding literal values for things like JITs, where the executable
-contents may be partially under the control of userspace, need a similar
-secret value.
-
-It is critical that the secret values used must be separate (e.g.
-different canary per stack) and high entropy (e.g. is the RNG actually
-working?) in order to maximize their success.
-
-### Kernel Address Space Layout Randomization (KASLR)
-
-Since the location of kernel memory is almost always instrumental in
-mounting a successful attack, making the location non-deterministic
-raises the difficulty of an exploit. (Note that this in turn makes
-the value of information exposures higher, since they may be used to
-discover desired memory locations.)
-
-#### Text and module base
-
-By relocating the physical and virtual base address of the kernel at
-boot-time (CONFIG_RANDOMIZE_BASE), attacks needing kernel code will be
-frustrated. Additionally, offsetting the module loading base address
-means that even systems that load the same set of modules in the same
-order every boot will not share a common base address with the rest of
-the kernel text.
-
-#### Stack base
-
-If the base address of the kernel stack is not the same between processes,
-or even not the same between syscalls, targets on or beyond the stack
-become more difficult to locate.
-
-#### Dynamic memory base
-
-Much of the kernel's dynamic memory (e.g. kmalloc, vmalloc, etc) ends up
-being relatively deterministic in layout due to the order of early-boot
-initializations. If the base address of these areas is not the same
-between boots, targeting them is frustrated, requiring an information
-exposure specific to the region.
-
-#### Structure layout
-
-By performing a per-build randomization of the layout of sensitive
-structures, attacks must either be tuned to known kernel builds or expose
-enough kernel memory to determine structure layouts before manipulating
-them.
-
-
-## Preventing Information Exposures
-
-Since the locations of sensitive structures are the primary target for
-attacks, it is important to defend against exposure of both kernel memory
-addresses and kernel memory contents (since they may contain kernel
-addresses or other sensitive things like canary values).
-
-### Unique identifiers
-
-Kernel memory addresses must never be used as identifiers exposed to
-userspace. Instead, use an atomic counter, an idr, or similar unique
-identifier.
-
-### Memory initialization
-
-Memory copied to userspace must always be fully initialized. If not
-explicitly memset(), this will require changes to the compiler to make
-sure structure holes are cleared.
-
-### Memory poisoning
-
-When releasing memory, it is best to poison the contents (clear stack on
-syscall return, wipe heap memory on a free), to avoid reuse attacks that
-rely on the old contents of memory. This frustrates many uninitialized
-variable attacks, stack content exposures, heap content exposures, and
-use-after-free attacks.
-
-### Destination tracking
-
-To help kill classes of bugs that result in kernel addresses being
-written to userspace, the destination of writes needs to be tracked. If
-the buffer is destined for userspace (e.g. seq_file backed /proc files),
-it should automatically censor sensitive values.