€•ƒ¤Œsphinx.addnodes”Œdocument”“”)”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)”}”(hhh]”(hŒ pending_xref”“”)”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…””}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ,/translations/zh_CN/security/self-protection”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)”}”(hhh]”hŒChinese (Traditional)”…””}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ,/translations/zh_TW/security/self-protection”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒItalian”…””}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ,/translations/it_IT/security/self-protection”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒJapanese”…””}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ,/translations/ja_JP/security/self-protection”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒKorean”…””}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ,/translations/ko_KR/security/self-protection”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒSpanish”…””}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ,/translations/sp_SP/security/self-protection”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒsection”“”)”}”(hhh]”(hŒtitle”“”)”}”(hŒKernel Self-Protection”h]”hŒKernel Self-Protection”…””}”(hh¨hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hh£hžhhŸŒF/var/lib/git/docbuild/linux/Documentation/security/self-protection.rst”h KubhŒ paragraph”“”)”}”(hXï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!)”h]”hXï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!)”…””}”(hh¹hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h Khh£hžhubh¸)”}”(hX<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.)”h]”hX@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.)”…””}”(hhÇhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h K hh£hžhubh¸)”}”(hXpThe 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.”h]”hXpThe 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.”…””}”(hhÕhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h Khh£hžhubh¢)”}”(hhh]”(h§)”}”(hŒAttack Surface Reduction”h]”hŒAttack Surface Reduction”…””}”(hhæhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hhãhžhhŸh¶h K ubh¸)”}”(hX*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.”h]”hX*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.”…””}”(hhôhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h K"hhãhžhubh¢)”}”(hhh]”(h§)”}”(hŒ Strict kernel memory permissions”h]”hŒ Strict kernel memory permissions”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hjhžhhŸh¶h K)ubh¸)”}”(hŒÕ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.”h]”hŒÕ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.”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h K+hjhžhubh¢)”}”(hhh]”(h§)”}”(hŒ7Executable code and read-only data must not be writable”h]”hŒ7Executable code and read-only data must not be writable”…””}”(hj$hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hj!hžhhŸh¶h K0ubh¸)”}”(hXð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.)”h]”hXð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.)”…””}”(hj2hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h K2hj!hžhubh¸)”}”(hŒ×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.”h]”(hŒIn support of this are ”…””}”(hj@hžhhŸNh NubhŒliteral”“”)”}”(hŒ``CONFIG_STRICT_KERNEL_RWX``”h]”hŒCONFIG_STRICT_KERNEL_RWX”…””}”(hjJhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj@ubhŒ and ”…””}”(hj@hžhhŸNh NubjI)”}”(hŒ``CONFIG_STRICT_MODULE_RWX``”h]”hŒCONFIG_STRICT_MODULE_RWX”…””}”(hj\hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj@ubhŒƒ, which seek to make sure that code is not writable, data is not executable, and read-only data is neither writable nor executable.”…””}”(hj@hžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h K;hj!hžhubh¸)”}”(hXaMost 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.”h]”(hŒí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. ”…””}”(hjthžhhŸNh NubjI)”}”(hŒ+``CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT``”h]”hŒ'CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT”…””}”(hj|hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjtubhŒI determines the default setting when ARCH_OPTIONAL_KERNEL_RWX is enabled.”…””}”(hjthžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h K@hj!hžhubeh}”(h]”Œ7executable-code-and-read-only-data-must-not-be-writable”ah ]”h"]”Œ7executable code and read-only data must not be writable”ah$]”h&]”uh1h¡hjhžhhŸh¶h K0ubh¢)”}”(hhh]”(h§)”}”(hŒ>Function pointers and sensitive variables must not be writable”h]”hŒ>Function pointers and sensitive variables must not be writable”…””}”(hjŸhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hjœhžhhŸh¶h KGubh¸)”}”(hXVast 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.”h]”hXVast 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.”…””}”(hj­hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h KIhjœhžhubh¸)”}”(hŒë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.”h]”hŒñ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.”…””}”(hj»hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h KNhjœhžhubh¸)”}”(hŒwFor variables that are initialized once at ``__init`` time, these can be marked with the ``__ro_after_init`` attribute.”h]”(hŒ+For variables that are initialized once at ”…””}”(hjÉhžhhŸNh NubjI)”}”(hŒ ``__init``”h]”hŒ__init”…””}”(hjÑhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjÉubhŒ$ time, these can be marked with the ”…””}”(hjÉhžhhŸNh NubjI)”}”(hŒ``__ro_after_init``”h]”hŒ__ro_after_init”…””}”(hjãhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjÉubhŒ attribute.”…””}”(hjÉhžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h KShjœhžhubh¸)”}”(hXvWhat 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.)”h]”hXvWhat 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.)”…””}”(hjûhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h KVhjœhžhubeh}”(h]”Œ>function-pointers-and-sensitive-variables-must-not-be-writable”ah ]”h"]”Œ>function pointers and sensitive variables must not be writable”ah$]”h&]”uh1h¡hjhžhhŸh¶h KGubh¢)”}”(hhh]”(h§)”}”(hŒ2Segregation of kernel memory from userspace memory”h]”hŒ2Segregation of kernel memory from userspace memory”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hjhžhhŸh¶h K^ubh¸)”}”(hXÖ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.”h]”hXÜ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.”…””}”(hj"hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h K`hjhžhubeh}”(h]”Œ2segregation-of-kernel-memory-from-userspace-memory”ah ]”h"]”Œ2segregation of kernel memory from userspace memory”ah$]”h&]”uh1h¡hjhžhhŸh¶h K^ubeh}”(h]”Œ strict-kernel-memory-permissions”ah ]”h"]”Œ strict kernel memory permissions”ah$]”h&]”uh1h¡hhãhžhhŸh¶h K)ubh¢)”}”(hhh]”(h§)”}”(hŒReduced access to syscalls”h]”hŒReduced access to syscalls”…””}”(hjChžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hj@hžhhŸh¶h Kiubh¸)”}”(hŒ‘One trivial way to eliminate many syscalls for 64-bit systems is building without ``CONFIG_COMPAT``. However, this is rarely a feasible scenario.”h]”(hŒROne trivial way to eliminate many syscalls for 64-bit systems is building without ”…””}”(hjQhžhhŸNh NubjI)”}”(hŒ``CONFIG_COMPAT``”h]”hŒ CONFIG_COMPAT”…””}”(hjYhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjQubhŒ.. However, this is rarely a feasible scenario.”…””}”(hjQhžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h Kkhj@hžhubh¸)”}”(hX)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.”h]”hX-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.”…””}”(hjqhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h Knhj@hžhubh¸)”}”(hX*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.”h]”hX*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.”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h Kthj@hžhubeh}”(h]”Œreduced-access-to-syscalls”ah ]”h"]”Œreduced access to syscalls”ah$]”h&]”uh1h¡hhãhžhhŸh¶h Kiubh¢)”}”(hhh]”(h§)”}”(hŒ$Restricting access to kernel modules”h]”hŒ$Restricting access to kernel modules”…””}”(hj˜hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hj•hžhhŸh¶h K{ubh¸)”}”(hXMThe 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.)”h]”hXQThe 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.)”…””}”(hj¦hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h K}hj•hžhubh¸)”}”(hXMTo 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.”h]”(hŒÁ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. ”…””}”(hj´hžhhŸNh NubjI)”}”(hŒ``CONFIG_MODULE_SIG_FORCE``”h]”hŒCONFIG_MODULE_SIG_FORCE”…””}”(hj¼hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj´ubhŒq, or dm-crypt with LoadPin), to keep from having root load arbitrary kernel code via the module loader interface.”…””}”(hj´hžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h K‡hj•hžhubeh}”(h]”Œ$restricting-access-to-kernel-modules”ah ]”h"]”Œ$restricting access to kernel modules”ah$]”h&]”uh1h¡hhãhžhhŸh¶h K{ubeh}”(h]”Œattack-surface-reduction”ah ]”h"]”Œattack surface reduction”ah$]”h&]”uh1h¡hh£hžhhŸh¶h K ubh¢)”}”(hhh]”(h§)”}”(hŒMemory integrity”h]”hŒMemory integrity”…””}”(hjçhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hjähžhhŸh¶h Kubh¸)”}”(hX]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.”h]”hX]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.”…””}”(hjõhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h K‘hjähžhubh¢)”}”(hhh]”(h§)”}”(hŒStack buffer overflow”h]”hŒStack buffer overflow”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hjhžhhŸh¶h K˜ubh¸)”}”(hX²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_STACKPROTECTOR``), which is verified just before the function returns. Other defenses include things like shadow stacks.”h]”(hX3The 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 (”…””}”(hjhžhhŸNh NubjI)”}”(hŒ``CONFIG_STACKPROTECTOR``”h]”hŒCONFIG_STACKPROTECTOR”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjubhŒh), which is verified just before the function returns. Other defenses include things like shadow stacks.”…””}”(hjhžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h Kšhjhžhubeh}”(h]”Œstack-buffer-overflow”ah ]”h"]”Œstack buffer overflow”ah$]”h&]”uh1h¡hjähžhhŸh¶h K˜ubh¢)”}”(hhh]”(h§)”}”(hŒStack depth overflow”h]”hŒStack depth overflow”…””}”(hj?hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hj<hžhhŸh¶h K¢ubh¸)”}”(hXÝ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.”h]”hXß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.”…””}”(hjMhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h K¤hj<hžhubeh}”(h]”Œstack-depth-overflow”ah ]”h"]”Œstack depth overflow”ah$]”h&]”uh1h¡hjähžhhŸh¶h K¢ubh¢)”}”(hhh]”(h§)”}”(hŒHeap memory integrity”h]”hŒHeap memory integrity”…””}”(hjfhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hjchžhhŸh¶h K­ubh¸)”}”(hŒ¦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.”h]”hŒ¨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.”…””}”(hjthžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h K¯hjchžhubeh}”(h]”Œheap-memory-integrity”ah ]”h"]”Œheap memory integrity”ah$]”h&]”uh1h¡hjähžhhŸh¶h K­ubh¢)”}”(hhh]”(h§)”}”(hŒCounter integrity”h]”hŒCounter integrity”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hjŠhžhhŸh¶h K´ubh¸)”}”(hXMany 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.”h]”hXMany 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.”…””}”(hj›hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h K¶hjŠhžhubeh}”(h]”Œcounter-integrity”ah ]”h"]”Œcounter integrity”ah$]”h&]”uh1h¡hjähžhhŸh¶h K´ubh¢)”}”(hhh]”(h§)”}”(hŒ#Size calculation overflow detection”h]”hŒ#Size calculation overflow detection”…””}”(hj´hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hj±hžhhŸh¶h K¼ubh¸)”}”(hŒÕ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.”h]”hŒÕ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.”…””}”(hjÂhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h K¾hj±hžhubeh}”(h]”Œ#size-calculation-overflow-detection”ah ]”h"]”Œ#size calculation overflow detection”ah$]”h&]”uh1h¡hjähžhhŸh¶h K¼ubeh}”(h]”Œmemory-integrity”ah ]”h"]”Œmemory integrity”ah$]”h&]”uh1h¡hh£hžhhŸh¶h Kubh¢)”}”(hhh]”(h§)”}”(hŒProbabilistic defenses”h]”hŒProbabilistic defenses”…””}”(hjãhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hjàhžhhŸh¶h KÄubh¸)”}”(hX1While 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.”h]”hX1While 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.”…””}”(hjñhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h KÆhjàhžhubh¢)”}”(hhh]”(h§)”}”(hŒ%Canaries, blinding, and other secrets”h]”hŒ%Canaries, blinding, and other secrets”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hjÿhžhhŸh¶h KÍubh¸)”}”(hŒÝ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.”h]”hŒÝ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.”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h KÏhjÿhžhubh¸)”}”(hŒ™Blinding literal values for things like JITs, where the executable contents may be partially under the control of userspace, need a similar secret value.”h]”hŒ™Blinding literal values for things like JITs, where the executable contents may be partially under the control of userspace, need a similar secret value.”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h KÔhjÿhžhubh¸)”}”(hŒ¶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.”h]”hŒ¶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.”…””}”(hj,hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h KØhjÿhžhubeh}”(h]”Œ#canaries-blinding-and-other-secrets”ah ]”h"]”Œ%canaries, blinding, and other secrets”ah$]”h&]”uh1h¡hjàhžhhŸh¶h KÍubh¢)”}”(hhh]”(h§)”}”(hŒ1Kernel Address Space Layout Randomization (KASLR)”h]”hŒ1Kernel Address Space Layout Randomization (KASLR)”…””}”(hjEhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hjBhžhhŸh¶h KÝubh¸)”}”(hX4Since 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.)”h]”hX4Since 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.)”…””}”(hjShžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h KßhjBhžhubh¢)”}”(hhh]”(h§)”}”(hŒText and module base”h]”hŒText and module base”…””}”(hjdhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hjahžhhŸh¶h Kæubh¸)”}”(hXrBy 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.”h]”(hŒPBy relocating the physical and virtual base address of the kernel at boot-time (”…””}”(hjrhžhhŸNh NubjI)”}”(hŒ``CONFIG_RANDOMIZE_BASE``”h]”hŒCONFIG_RANDOMIZE_BASE”…””}”(hjzhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjrubhX ), 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.”…””}”(hjrhžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h Kèhjahžhubeh}”(h]”Œtext-and-module-base”ah ]”h"]”Œtext and module base”ah$]”h&]”uh1h¡hjBhžhhŸh¶h Kæubh¢)”}”(hhh]”(h§)”}”(hŒ Stack base”h]”hŒ Stack base”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hjšhžhhŸh¶h Kðubh¸)”}”(hŒ±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.”h]”hŒ±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.”…””}”(hj«hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h Kòhjšhžhubeh}”(h]”Œ stack-base”ah ]”h"]”Œ stack base”ah$]”h&]”uh1h¡hjBhžhhŸh¶h Kðubh¢)”}”(hhh]”(h§)”}”(hŒDynamic memory base”h]”hŒDynamic memory base”…””}”(hjÄhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hjÁhžhhŸh¶h K÷ubh¸)”}”(hX;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.”h]”hX=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.”…””}”(hjÒhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h KùhjÁhžhubeh}”(h]”Œdynamic-memory-base”ah ]”h"]”Œdynamic memory base”ah$]”h&]”uh1h¡hjBhžhhŸh¶h K÷ubh¢)”}”(hhh]”(h§)”}”(hŒStructure layout”h]”hŒStructure layout”…””}”(hjëhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hjèhžhhŸh¶h Mubh¸)”}”(hŒÚ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.”h]”hŒÚ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.”…””}”(hjùhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h Mhjèhžhubeh}”(h]”Œstructure-layout”ah ]”h"]”Œstructure layout”ah$]”h&]”uh1h¡hjBhžhhŸh¶h Mubeh}”(h]”Œ/kernel-address-space-layout-randomization-kaslr”ah ]”h"]”Œ1kernel address space layout randomization (kaslr)”ah$]”h&]”uh1h¡hjàhžhhŸh¶h KÝubeh}”(h]”Œprobabilistic-defenses”ah ]”h"]”Œprobabilistic defenses”ah$]”h&]”uh1h¡hh£hžhhŸh¶h KÄubh¢)”}”(hhh]”(h§)”}”(hŒ Preventing Information Exposures”h]”hŒ Preventing Information Exposures”…””}”(hj"hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hjhžhhŸh¶h M ubh¸)”}”(hX 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).”h]”hX 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).”…””}”(hj0hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h M hjhžhubh¢)”}”(hhh]”(h§)”}”(hŒKernel addresses”h]”hŒKernel addresses”…””}”(hjAhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hj>hžhhŸh¶h Mubh¸)”}”(hX_Printing kernel addresses to userspace leaks sensitive information about the kernel memory layout. Care should be exercised when using any printk specifier that prints the raw address, currently %px, %p[ad], (and %p[sSb] in certain circumstances [*]). Any file written to using one of these specifiers should be readable only by privileged processes.”h]”hX_Printing kernel addresses to userspace leaks sensitive information about the kernel memory layout. Care should be exercised when using any printk specifier that prints the raw address, currently %px, %p[ad], (and %p[sSb] in certain circumstances [*]). Any file written to using one of these specifiers should be readable only by privileged processes.”…””}”(hjOhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h Mhj>hžhubh¸)”}”(hŒ‹Kernels 4.14 and older printed the raw address using %p. As of 4.15-rc1 addresses printed with the specifier %p are hashed before printing.”h]”hŒ‹Kernels 4.14 and older printed the raw address using %p. As of 4.15-rc1 addresses printed with the specifier %p are hashed before printing.”…””}”(hj]hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h Mhj>hžhubh¸)”}”(hŒ†[*] If KALLSYMS is enabled and symbol lookup fails, the raw address is printed. If KALLSYMS is not enabled the raw address is printed.”h]”hŒ†[*] If KALLSYMS is enabled and symbol lookup fails, the raw address is printed. If KALLSYMS is not enabled the raw address is printed.”…””}”(hjkhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h Mhj>hžhubeh}”(h]”Œkernel-addresses”ah ]”h"]”Œkernel addresses”ah$]”h&]”uh1h¡hjhžhhŸh¶h Mubh¢)”}”(hhh]”(h§)”}”(hŒUnique identifiers”h]”hŒUnique identifiers”…””}”(hj„hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hjhžhhŸh¶h M ubh¸)”}”(hŒ•Kernel memory addresses must never be used as identifiers exposed to userspace. Instead, use an atomic counter, an idr, or similar unique identifier.”h]”hŒ•Kernel memory addresses must never be used as identifiers exposed to userspace. Instead, use an atomic counter, an idr, or similar unique identifier.”…””}”(hj’hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h M"hjhžhubeh}”(h]”Œunique-identifiers”ah ]”h"]”Œunique identifiers”ah$]”h&]”uh1h¡hjhžhhŸh¶h M ubh¢)”}”(hhh]”(h§)”}”(hŒMemory initialization”h]”hŒMemory initialization”…””}”(hj«hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hj¨hžhhŸh¶h M'ubh¸)”}”(hŒ¬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.”h]”hŒ¬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.”…””}”(hj¹hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h M)hj¨hžhubeh}”(h]”Œmemory-initialization”ah ]”h"]”Œmemory initialization”ah$]”h&]”uh1h¡hjhžhhŸh¶h M'ubh¢)”}”(hhh]”(h§)”}”(hŒMemory poisoning”h]”hŒMemory poisoning”…””}”(hjÒhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hjÏhžhhŸh¶h M.ubh¸)”}”(hX`When releasing memory, it is best to poison the contents, to avoid reuse attacks that rely on the old contents of memory. E.g., clear stack on a syscall return (``CONFIG_GCC_PLUGIN_STACKLEAK``), wipe heap memory on a free. This frustrates many uninitialized variable attacks, stack content exposures, heap content exposures, and use-after-free attacks.”h]”(hŒ¡When releasing memory, it is best to poison the contents, to avoid reuse attacks that rely on the old contents of memory. E.g., clear stack on a syscall return (”…””}”(hjàhžhhŸNh NubjI)”}”(hŒ``CONFIG_GCC_PLUGIN_STACKLEAK``”h]”hŒCONFIG_GCC_PLUGIN_STACKLEAK”…””}”(hjèhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjàubhŒ ), wipe heap memory on a free. This frustrates many uninitialized variable attacks, stack content exposures, heap content exposures, and use-after-free attacks.”…””}”(hjàhžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h M0hjÏhžhubeh}”(h]”Œmemory-poisoning”ah ]”h"]”Œmemory poisoning”ah$]”h&]”uh1h¡hjhžhhŸh¶h M.ubh¢)”}”(hhh]”(h§)”}”(hŒDestination tracking”h]”hŒDestination tracking”…””}”(hj hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¦hjhžhhŸh¶h M7ubh¸)”}”(hXTo 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.”h]”(hŒÆ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 ”…””}”(hjhžhhŸNh NubjI)”}”(hŒ ``/proc``”h]”hŒ/proc”…””}”(hj!hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjubhŒ9 files), it should automatically censor sensitive values.”…””}”(hjhžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1h·hŸh¶h M9hjhžhubeh}”(h]”Œdestination-tracking”ah ]”h"]”Œdestination tracking”ah$]”h&]”uh1h¡hjhžhhŸh¶h M7ubeh}”(h]”Œ preventing-information-exposures”ah ]”h"]”Œ preventing information exposures”ah$]”h&]”uh1h¡hh£hžhhŸh¶h M ubeh}”(h]”Œkernel-self-protection”ah ]”h"]”Œkernel self-protection”ah$]”h&]”uh1h¡hhhžhhŸh¶h Kubeh}”(h]”h ]”h"]”h$]”h&]”Œsource”h¶uh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)”}”(h¦NŒ generator”NŒ datestamp”NŒ source_link”NŒ source_url”NŒ toc_backlinks”Œentry”Œfootnote_backlinks”KŒ sectnum_xform”KŒstrip_comments”NŒstrip_elements_with_classes”NŒ strip_classes”NŒ report_level”KŒ halt_level”KŒexit_status_level”KŒdebug”NŒwarning_stream”NŒ traceback”ˆŒinput_encoding”Œ utf-8-sig”Œinput_encoding_error_handler”Œstrict”Œoutput_encoding”Œutf-8”Œoutput_encoding_error_handler”jtŒerror_encoding”Œutf-8”Œerror_encoding_error_handler”Œbackslashreplace”Œ language_code”Œen”Œrecord_dependencies”NŒconfig”NŒ id_prefix”hŒauto_id_prefix”Œid”Œ dump_settings”NŒdump_internals”NŒdump_transforms”NŒdump_pseudo_xml”NŒexpose_internals”NŒstrict_visitor”NŒ_disable_config”NŒ_source”h¶Œ _destination”NŒ _config_files”]”Œ7/var/lib/git/docbuild/linux/Documentation/docutils.conf”aŒfile_insertion_enabled”ˆŒ raw_enabled”KŒline_length_limit”M'Œpep_references”NŒ pep_base_url”Œhttps://peps.python.org/”Œpep_file_url_template”Œpep-%04d”Œrfc_references”NŒ rfc_base_url”Œ&https://datatracker.ietf.org/doc/html/”Œ tab_width”KŒtrim_footnote_reference_space”‰Œsyntax_highlight”Œlong”Œ smart_quotes”ˆŒsmartquotes_locales”]”Œcharacter_level_inline_markup”‰Œdoctitle_xform”‰Œ docinfo_xform”KŒsectsubtitle_xform”‰Œ image_loading”Œlink”Œembed_stylesheet”‰Œcloak_email_addresses”ˆŒsection_self_link”‰Œenv”NubŒreporter”NŒindirect_targets”]”Œsubstitution_defs”}”Œsubstitution_names”}”Œrefnames”}”Œrefids”}”Œnameids”}”(jNjKjájÞj=j:j™j–jj j5j2j’jjÙjÖjÝjÚj9j6j`j]j‡j„j®j«jÕjÒjjj?j<jjj—j”j¾j»jåjâj j jFjCj~j{j¥j¢jÌjÉjjj>j;uŒ nametypes”}”(jN‰já‰j=‰j™‰j‰j5‰j’‰jÙ‰j݉j9‰j`‰j‡‰j®‰jÕ‰j‰j?‰j‰j—‰j¾‰jå‰j ‰jF‰j~‰j¥‰j̉j‰j>‰uh}”(jKh£jÞhãj:jj–j!j jœj2jjj@jÖj•jÚjäj6jj]j<j„jcj«jŠjÒj±jjàj<jÿjjBj”jaj»jšjâjÁj jèjCjj{j>j¢jjÉj¨jjÏj;juŒ footnote_refs”}”Œ citation_refs”}”Œ autofootnotes”]”Œautofootnote_refs”]”Œsymbol_footnotes”]”Œsymbol_footnote_refs”]”Œ footnotes”]”Œ citations”]”Œautofootnote_start”KŒsymbol_footnote_start”KŒ id_counter”Œ collections”ŒCounter”“”}”…”R”Œparse_messages”]”Œtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nhžhub.