diff options
| -rw-r--r-- | Makefile | 5 | ||||
| -rw-r--r-- | scripts/gcc-plugins/Kconfig | 126 | ||||
| -rw-r--r-- | security/Kconfig | 2 | ||||
| -rw-r--r-- | security/Kconfig.hardening | 164 |
4 files changed, 177 insertions, 120 deletions
| @@ -748,6 +748,11 @@ KBUILD_CFLAGS += -fomit-frame-pointer | |||
| 748 | endif | 748 | endif |
| 749 | endif | 749 | endif |
| 750 | 750 | ||
| 751 | # Initialize all stack variables with a pattern, if desired. | ||
| 752 | ifdef CONFIG_INIT_STACK_ALL | ||
| 753 | KBUILD_CFLAGS += -ftrivial-auto-var-init=pattern | ||
| 754 | endif | ||
| 755 | |||
| 751 | DEBUG_CFLAGS := $(call cc-option, -fno-var-tracking-assignments) | 756 | DEBUG_CFLAGS := $(call cc-option, -fno-var-tracking-assignments) |
| 752 | 757 | ||
| 753 | ifdef CONFIG_DEBUG_INFO | 758 | ifdef CONFIG_DEBUG_INFO |
diff --git a/scripts/gcc-plugins/Kconfig b/scripts/gcc-plugins/Kconfig index 74271dba4f94..80220ed26a35 100644 --- a/scripts/gcc-plugins/Kconfig +++ b/scripts/gcc-plugins/Kconfig | |||
| @@ -13,17 +13,19 @@ config HAVE_GCC_PLUGINS | |||
| 13 | An arch should select this symbol if it supports building with | 13 | An arch should select this symbol if it supports building with |
| 14 | GCC plugins. | 14 | GCC plugins. |
| 15 | 15 | ||
| 16 | menuconfig GCC_PLUGINS | 16 | config GCC_PLUGINS |
| 17 | bool "GCC plugins" | 17 | bool |
| 18 | depends on HAVE_GCC_PLUGINS | 18 | depends on HAVE_GCC_PLUGINS |
| 19 | depends on PLUGIN_HOSTCC != "" | 19 | depends on PLUGIN_HOSTCC != "" |
| 20 | default y | ||
| 20 | help | 21 | help |
| 21 | GCC plugins are loadable modules that provide extra features to the | 22 | GCC plugins are loadable modules that provide extra features to the |
| 22 | compiler. They are useful for runtime instrumentation and static analysis. | 23 | compiler. They are useful for runtime instrumentation and static analysis. |
| 23 | 24 | ||
| 24 | See Documentation/gcc-plugins.txt for details. | 25 | See Documentation/gcc-plugins.txt for details. |
| 25 | 26 | ||
| 26 | if GCC_PLUGINS | 27 | menu "GCC plugins" |
| 28 | depends on GCC_PLUGINS | ||
| 27 | 29 | ||
| 28 | config GCC_PLUGIN_CYC_COMPLEXITY | 30 | config GCC_PLUGIN_CYC_COMPLEXITY |
| 29 | bool "Compute the cyclomatic complexity of a function" if EXPERT | 31 | bool "Compute the cyclomatic complexity of a function" if EXPERT |
| @@ -66,71 +68,6 @@ config GCC_PLUGIN_LATENT_ENTROPY | |||
| 66 | * https://grsecurity.net/ | 68 | * https://grsecurity.net/ |
| 67 | * https://pax.grsecurity.net/ | 69 | * https://pax.grsecurity.net/ |
| 68 | 70 | ||
| 69 | config GCC_PLUGIN_STRUCTLEAK | ||
| 70 | bool "Zero initialize stack variables" | ||
| 71 | help | ||
| 72 | While the kernel is built with warnings enabled for any missed | ||
| 73 | stack variable initializations, this warning is silenced for | ||
| 74 | anything passed by reference to another function, under the | ||
| 75 | occasionally misguided assumption that the function will do | ||
| 76 | the initialization. As this regularly leads to exploitable | ||
| 77 | flaws, this plugin is available to identify and zero-initialize | ||
| 78 | such variables, depending on the chosen level of coverage. | ||
| 79 | |||
| 80 | This plugin was originally ported from grsecurity/PaX. More | ||
| 81 | information at: | ||
| 82 | * https://grsecurity.net/ | ||
| 83 | * https://pax.grsecurity.net/ | ||
| 84 | |||
| 85 | choice | ||
| 86 | prompt "Coverage" | ||
| 87 | depends on GCC_PLUGIN_STRUCTLEAK | ||
| 88 | default GCC_PLUGIN_STRUCTLEAK_BYREF_ALL | ||
| 89 | help | ||
| 90 | This chooses the level of coverage over classes of potentially | ||
| 91 | uninitialized variables. The selected class will be | ||
| 92 | zero-initialized before use. | ||
| 93 | |||
| 94 | config GCC_PLUGIN_STRUCTLEAK_USER | ||
| 95 | bool "structs marked for userspace" | ||
| 96 | help | ||
| 97 | Zero-initialize any structures on the stack containing | ||
| 98 | a __user attribute. This can prevent some classes of | ||
| 99 | uninitialized stack variable exploits and information | ||
| 100 | exposures, like CVE-2013-2141: | ||
| 101 | https://git.kernel.org/linus/b9e146d8eb3b9eca | ||
| 102 | |||
| 103 | config GCC_PLUGIN_STRUCTLEAK_BYREF | ||
| 104 | bool "structs passed by reference" | ||
| 105 | help | ||
| 106 | Zero-initialize any structures on the stack that may | ||
| 107 | be passed by reference and had not already been | ||
| 108 | explicitly initialized. This can prevent most classes | ||
| 109 | of uninitialized stack variable exploits and information | ||
| 110 | exposures, like CVE-2017-1000410: | ||
| 111 | https://git.kernel.org/linus/06e7e776ca4d3654 | ||
| 112 | |||
| 113 | config GCC_PLUGIN_STRUCTLEAK_BYREF_ALL | ||
| 114 | bool "anything passed by reference" | ||
| 115 | help | ||
| 116 | Zero-initialize any stack variables that may be passed | ||
| 117 | by reference and had not already been explicitly | ||
| 118 | initialized. This is intended to eliminate all classes | ||
| 119 | of uninitialized stack variable exploits and information | ||
| 120 | exposures. | ||
| 121 | |||
| 122 | endchoice | ||
| 123 | |||
| 124 | config GCC_PLUGIN_STRUCTLEAK_VERBOSE | ||
| 125 | bool "Report forcefully initialized variables" | ||
| 126 | depends on GCC_PLUGIN_STRUCTLEAK | ||
| 127 | depends on !COMPILE_TEST # too noisy | ||
| 128 | help | ||
| 129 | This option will cause a warning to be printed each time the | ||
| 130 | structleak plugin finds a variable it thinks needs to be | ||
| 131 | initialized. Since not all existing initializers are detected | ||
| 132 | by the plugin, this can produce false positive warnings. | ||
| 133 | |||
| 134 | config GCC_PLUGIN_RANDSTRUCT | 71 | config GCC_PLUGIN_RANDSTRUCT |
| 135 | bool "Randomize layout of sensitive kernel structures" | 72 | bool "Randomize layout of sensitive kernel structures" |
| 136 | select MODVERSIONS if MODULES | 73 | select MODVERSIONS if MODULES |
| @@ -171,59 +108,8 @@ config GCC_PLUGIN_RANDSTRUCT_PERFORMANCE | |||
| 171 | in structures. This reduces the performance hit of RANDSTRUCT | 108 | in structures. This reduces the performance hit of RANDSTRUCT |
| 172 | at the cost of weakened randomization. | 109 | at the cost of weakened randomization. |
| 173 | 110 | ||
| 174 | config GCC_PLUGIN_STACKLEAK | ||
| 175 | bool "Erase the kernel stack before returning from syscalls" | ||
| 176 | depends on GCC_PLUGINS | ||
| 177 | depends on HAVE_ARCH_STACKLEAK | ||
| 178 | help | ||
| 179 | This option makes the kernel erase the kernel stack before | ||
| 180 | returning from system calls. That reduces the information which | ||
| 181 | kernel stack leak bugs can reveal and blocks some uninitialized | ||
| 182 | stack variable attacks. | ||
| 183 | |||
| 184 | The tradeoff is the performance impact: on a single CPU system kernel | ||
| 185 | compilation sees a 1% slowdown, other systems and workloads may vary | ||
| 186 | and you are advised to test this feature on your expected workload | ||
| 187 | before deploying it. | ||
| 188 | |||
| 189 | This plugin was ported from grsecurity/PaX. More information at: | ||
| 190 | * https://grsecurity.net/ | ||
| 191 | * https://pax.grsecurity.net/ | ||
| 192 | |||
| 193 | config STACKLEAK_TRACK_MIN_SIZE | ||
| 194 | int "Minimum stack frame size of functions tracked by STACKLEAK" | ||
| 195 | default 100 | ||
| 196 | range 0 4096 | ||
| 197 | depends on GCC_PLUGIN_STACKLEAK | ||
| 198 | help | ||
| 199 | The STACKLEAK gcc plugin instruments the kernel code for tracking | ||
| 200 | the lowest border of the kernel stack (and for some other purposes). | ||
| 201 | It inserts the stackleak_track_stack() call for the functions with | ||
| 202 | a stack frame size greater than or equal to this parameter. | ||
| 203 | If unsure, leave the default value 100. | ||
| 204 | |||
| 205 | config STACKLEAK_METRICS | ||
| 206 | bool "Show STACKLEAK metrics in the /proc file system" | ||
| 207 | depends on GCC_PLUGIN_STACKLEAK | ||
| 208 | depends on PROC_FS | ||
| 209 | help | ||
| 210 | If this is set, STACKLEAK metrics for every task are available in | ||
| 211 | the /proc file system. In particular, /proc/<pid>/stack_depth | ||
| 212 | shows the maximum kernel stack consumption for the current and | ||
| 213 | previous syscalls. Although this information is not precise, it | ||
| 214 | can be useful for estimating the STACKLEAK performance impact for | ||
| 215 | your workloads. | ||
| 216 | |||
| 217 | config STACKLEAK_RUNTIME_DISABLE | ||
| 218 | bool "Allow runtime disabling of kernel stack erasing" | ||
| 219 | depends on GCC_PLUGIN_STACKLEAK | ||
| 220 | help | ||
| 221 | This option provides 'stack_erasing' sysctl, which can be used in | ||
| 222 | runtime to control kernel stack erasing for kernels built with | ||
| 223 | CONFIG_GCC_PLUGIN_STACKLEAK. | ||
| 224 | |||
| 225 | config GCC_PLUGIN_ARM_SSP_PER_TASK | 111 | config GCC_PLUGIN_ARM_SSP_PER_TASK |
| 226 | bool | 112 | bool |
| 227 | depends on GCC_PLUGINS && ARM | 113 | depends on GCC_PLUGINS && ARM |
| 228 | 114 | ||
| 229 | endif | 115 | endmenu |
diff --git a/security/Kconfig b/security/Kconfig index 353cfef71d4e..aeac3676dd4d 100644 --- a/security/Kconfig +++ b/security/Kconfig | |||
| @@ -287,5 +287,7 @@ config LSM | |||
| 287 | 287 | ||
| 288 | If unsure, leave this as the default. | 288 | If unsure, leave this as the default. |
| 289 | 289 | ||
| 290 | source "security/Kconfig.hardening" | ||
| 291 | |||
| 290 | endmenu | 292 | endmenu |
| 291 | 293 | ||
diff --git a/security/Kconfig.hardening b/security/Kconfig.hardening new file mode 100644 index 000000000000..0a1d4ca314f4 --- /dev/null +++ b/security/Kconfig.hardening | |||
| @@ -0,0 +1,164 @@ | |||
| 1 | menu "Kernel hardening options" | ||
| 2 | |||
| 3 | config GCC_PLUGIN_STRUCTLEAK | ||
| 4 | bool | ||
| 5 | help | ||
| 6 | While the kernel is built with warnings enabled for any missed | ||
| 7 | stack variable initializations, this warning is silenced for | ||
| 8 | anything passed by reference to another function, under the | ||
| 9 | occasionally misguided assumption that the function will do | ||
| 10 | the initialization. As this regularly leads to exploitable | ||
| 11 | flaws, this plugin is available to identify and zero-initialize | ||
| 12 | such variables, depending on the chosen level of coverage. | ||
| 13 | |||
| 14 | This plugin was originally ported from grsecurity/PaX. More | ||
| 15 | information at: | ||
| 16 | * https://grsecurity.net/ | ||
| 17 | * https://pax.grsecurity.net/ | ||
| 18 | |||
| 19 | menu "Memory initialization" | ||
| 20 | |||
| 21 | config CC_HAS_AUTO_VAR_INIT | ||
| 22 | def_bool $(cc-option,-ftrivial-auto-var-init=pattern) | ||
| 23 | |||
| 24 | choice | ||
| 25 | prompt "Initialize kernel stack variables at function entry" | ||
| 26 | default GCC_PLUGIN_STRUCTLEAK_BYREF_ALL if COMPILE_TEST && GCC_PLUGINS | ||
| 27 | default INIT_STACK_ALL if COMPILE_TEST && CC_HAS_AUTO_VAR_INIT | ||
| 28 | default INIT_STACK_NONE | ||
| 29 | help | ||
| 30 | This option enables initialization of stack variables at | ||
| 31 | function entry time. This has the possibility to have the | ||
| 32 | greatest coverage (since all functions can have their | ||
| 33 | variables initialized), but the performance impact depends | ||
| 34 | on the function calling complexity of a given workload's | ||
| 35 | syscalls. | ||
| 36 | |||
| 37 | This chooses the level of coverage over classes of potentially | ||
| 38 | uninitialized variables. The selected class will be | ||
| 39 | initialized before use in a function. | ||
| 40 | |||
| 41 | config INIT_STACK_NONE | ||
| 42 | bool "no automatic initialization (weakest)" | ||
| 43 | help | ||
| 44 | Disable automatic stack variable initialization. | ||
| 45 | This leaves the kernel vulnerable to the standard | ||
| 46 | classes of uninitialized stack variable exploits | ||
| 47 | and information exposures. | ||
| 48 | |||
| 49 | config GCC_PLUGIN_STRUCTLEAK_USER | ||
| 50 | bool "zero-init structs marked for userspace (weak)" | ||
| 51 | depends on GCC_PLUGINS | ||
| 52 | select GCC_PLUGIN_STRUCTLEAK | ||
| 53 | help | ||
| 54 | Zero-initialize any structures on the stack containing | ||
| 55 | a __user attribute. This can prevent some classes of | ||
| 56 | uninitialized stack variable exploits and information | ||
| 57 | exposures, like CVE-2013-2141: | ||
| 58 | https://git.kernel.org/linus/b9e146d8eb3b9eca | ||
| 59 | |||
| 60 | config GCC_PLUGIN_STRUCTLEAK_BYREF | ||
| 61 | bool "zero-init structs passed by reference (strong)" | ||
| 62 | depends on GCC_PLUGINS | ||
| 63 | select GCC_PLUGIN_STRUCTLEAK | ||
| 64 | help | ||
| 65 | Zero-initialize any structures on the stack that may | ||
| 66 | be passed by reference and had not already been | ||
| 67 | explicitly initialized. This can prevent most classes | ||
| 68 | of uninitialized stack variable exploits and information | ||
| 69 | exposures, like CVE-2017-1000410: | ||
| 70 | https://git.kernel.org/linus/06e7e776ca4d3654 | ||
| 71 | |||
| 72 | config GCC_PLUGIN_STRUCTLEAK_BYREF_ALL | ||
| 73 | bool "zero-init anything passed by reference (very strong)" | ||
| 74 | depends on GCC_PLUGINS | ||
| 75 | select GCC_PLUGIN_STRUCTLEAK | ||
| 76 | help | ||
| 77 | Zero-initialize any stack variables that may be passed | ||
| 78 | by reference and had not already been explicitly | ||
| 79 | initialized. This is intended to eliminate all classes | ||
| 80 | of uninitialized stack variable exploits and information | ||
| 81 | exposures. | ||
| 82 | |||
| 83 | config INIT_STACK_ALL | ||
| 84 | bool "0xAA-init everything on the stack (strongest)" | ||
| 85 | depends on CC_HAS_AUTO_VAR_INIT | ||
| 86 | help | ||
| 87 | Initializes everything on the stack with a 0xAA | ||
| 88 | pattern. This is intended to eliminate all classes | ||
| 89 | of uninitialized stack variable exploits and information | ||
| 90 | exposures, even variables that were warned to have been | ||
| 91 | left uninitialized. | ||
| 92 | |||
| 93 | endchoice | ||
| 94 | |||
| 95 | config GCC_PLUGIN_STRUCTLEAK_VERBOSE | ||
| 96 | bool "Report forcefully initialized variables" | ||
| 97 | depends on GCC_PLUGIN_STRUCTLEAK | ||
| 98 | depends on !COMPILE_TEST # too noisy | ||
| 99 | help | ||
| 100 | This option will cause a warning to be printed each time the | ||
| 101 | structleak plugin finds a variable it thinks needs to be | ||
| 102 | initialized. Since not all existing initializers are detected | ||
| 103 | by the plugin, this can produce false positive warnings. | ||
| 104 | |||
| 105 | config GCC_PLUGIN_STACKLEAK | ||
| 106 | bool "Poison kernel stack before returning from syscalls" | ||
| 107 | depends on GCC_PLUGINS | ||
| 108 | depends on HAVE_ARCH_STACKLEAK | ||
| 109 | help | ||
| 110 | This option makes the kernel erase the kernel stack before | ||
| 111 | returning from system calls. This has the effect of leaving | ||
| 112 | the stack initialized to the poison value, which both reduces | ||
| 113 | the lifetime of any sensitive stack contents and reduces | ||
| 114 | potential for uninitialized stack variable exploits or information | ||
| 115 | exposures (it does not cover functions reaching the same stack | ||
| 116 | depth as prior functions during the same syscall). This blocks | ||
| 117 | most uninitialized stack variable attacks, with the performance | ||
| 118 | impact being driven by the depth of the stack usage, rather than | ||
| 119 | the function calling complexity. | ||
| 120 | |||
| 121 | The performance impact on a single CPU system kernel compilation | ||
| 122 | sees a 1% slowdown, other systems and workloads may vary and you | ||
| 123 | are advised to test this feature on your expected workload before | ||
| 124 | deploying it. | ||
| 125 | |||
| 126 | This plugin was ported from grsecurity/PaX. More information at: | ||
| 127 | * https://grsecurity.net/ | ||
| 128 | * https://pax.grsecurity.net/ | ||
| 129 | |||
| 130 | config STACKLEAK_TRACK_MIN_SIZE | ||
| 131 | int "Minimum stack frame size of functions tracked by STACKLEAK" | ||
| 132 | default 100 | ||
| 133 | range 0 4096 | ||
| 134 | depends on GCC_PLUGIN_STACKLEAK | ||
| 135 | help | ||
| 136 | The STACKLEAK gcc plugin instruments the kernel code for tracking | ||
| 137 | the lowest border of the kernel stack (and for some other purposes). | ||
| 138 | It inserts the stackleak_track_stack() call for the functions with | ||
| 139 | a stack frame size greater than or equal to this parameter. | ||
| 140 | If unsure, leave the default value 100. | ||
| 141 | |||
| 142 | config STACKLEAK_METRICS | ||
| 143 | bool "Show STACKLEAK metrics in the /proc file system" | ||
| 144 | depends on GCC_PLUGIN_STACKLEAK | ||
| 145 | depends on PROC_FS | ||
| 146 | help | ||
| 147 | If this is set, STACKLEAK metrics for every task are available in | ||
| 148 | the /proc file system. In particular, /proc/<pid>/stack_depth | ||
| 149 | shows the maximum kernel stack consumption for the current and | ||
| 150 | previous syscalls. Although this information is not precise, it | ||
| 151 | can be useful for estimating the STACKLEAK performance impact for | ||
| 152 | your workloads. | ||
| 153 | |||
| 154 | config STACKLEAK_RUNTIME_DISABLE | ||
| 155 | bool "Allow runtime disabling of kernel stack erasing" | ||
| 156 | depends on GCC_PLUGIN_STACKLEAK | ||
| 157 | help | ||
| 158 | This option provides 'stack_erasing' sysctl, which can be used in | ||
| 159 | runtime to control kernel stack erasing for kernels built with | ||
| 160 | CONFIG_GCC_PLUGIN_STACKLEAK. | ||
| 161 | |||
| 162 | endmenu | ||
| 163 | |||
| 164 | endmenu | ||
