Skip to content

Commit

Permalink
Merge tag 'hardening-v5.16-rc1' of git://git.kernel.org/pub/scm/linux…
Browse files Browse the repository at this point in the history
…/kernel/git/kees/linux

Pull compiler hardening updates from Kees Cook:
 "These are various compiler-related hardening feature updates. Notable
  is the addition of an explicit limited rationale for, and deprecation
  schedule of, gcc-plugins.

  gcc-plugins:
   - remove support for GCC 4.9 and older (Ard Biesheuvel)
   - remove duplicate include in gcc-common.h (Ye Guojin)
   - Explicitly document purpose and deprecation schedule (Kees Cook)
   - Remove cyc_complexity (Kees Cook)

  instrumentation:
   - Avoid harmless Clang option under CONFIG_INIT_STACK_ALL_ZERO (Kees Cook)

  Clang LTO:
   - kallsyms: strip LTO suffixes from static functions (Nick Desaulniers)"

* tag 'hardening-v5.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux:
  gcc-plugins: remove duplicate include in gcc-common.h
  gcc-plugins: Remove cyc_complexity
  gcc-plugins: Explicitly document purpose and deprecation schedule
  kallsyms: strip LTO suffixes from static functions
  gcc-plugins: remove support for GCC 4.9 and older
  hardening: Avoid harmless Clang option under CONFIG_INIT_STACK_ALL_ZERO
  • Loading branch information
torvalds committed Nov 2, 2021
2 parents 0146337 + 6425392 commit f594e28
Show file tree
Hide file tree
Showing 13 changed files with 75 additions and 320 deletions.
28 changes: 26 additions & 2 deletions Documentation/kbuild/gcc-plugins.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,32 @@ This infrastructure was ported from grsecurity [6]_ and PaX [7]_.
.. [7] https://pax.grsecurity.net/
Purpose
=======

GCC plugins are designed to provide a place to experiment with potential
compiler features that are neither in GCC nor Clang upstream. Once
their utility is proven, the goal is to upstream the feature into GCC
(and Clang), and then to finally remove them from the kernel once the
feature is available in all supported versions of GCC.

Specifically, new plugins should implement only features that have no
upstream compiler support (in either GCC or Clang).

When a feature exists in Clang but not GCC, effort should be made to
bring the feature to upstream GCC (rather than just as a kernel-specific
GCC plugin), so the entire ecosystem can benefit from it.

Similarly, even if a feature provided by a GCC plugin does *not* exist
in Clang, but the feature is proven to be useful, effort should be spent
to upstream the feature to GCC (and Clang).

After a feature is available in upstream GCC, the plugin will be made
unbuildable for the corresponding GCC version (and later). Once all
kernel-supported versions of GCC provide the feature, the plugin will
be removed from the kernel.


Files
=====

Expand Down Expand Up @@ -70,7 +96,6 @@ Enable the GCC plugin infrastructure and some plugin(s) you want to use
in the kernel config::

CONFIG_GCC_PLUGINS=y
CONFIG_GCC_PLUGIN_CYC_COMPLEXITY=y
CONFIG_GCC_PLUGIN_LATENT_ENTROPY=y
...

Expand All @@ -89,4 +114,3 @@ The GCC plugins are in scripts/gcc-plugins/. You need to put plugin source files
right under scripts/gcc-plugins/. Creating subdirectories is not supported.
It must be added to scripts/gcc-plugins/Makefile, scripts/Makefile.gcc-plugins
and a relevant Kconfig file.
See the cyc_complexity_plugin.c (CONFIG_GCC_PLUGIN_CYC_COMPLEXITY) GCC plugin.
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -831,12 +831,12 @@ endif

# Initialize all stack variables with a zero value.
ifdef CONFIG_INIT_STACK_ALL_ZERO
# Future support for zero initialization is still being debated, see
# https://bugs.llvm.org/show_bug.cgi?id=45497. These flags are subject to being
# renamed or dropped.
KBUILD_CFLAGS += -ftrivial-auto-var-init=zero
ifdef CONFIG_CC_IS_CLANG
# https://bugs.llvm.org/show_bug.cgi?id=45497
KBUILD_CFLAGS += -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang
endif
endif

# While VLAs have been removed, GCC produces unreachable stack probes
# for the randomize_kstack_offset feature. Disable it for all compilers.
Expand Down
46 changes: 33 additions & 13 deletions kernel/kallsyms.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,26 +164,46 @@ static unsigned long kallsyms_sym_address(int idx)
return kallsyms_relative_base - 1 - kallsyms_offsets[idx];
}

#if defined(CONFIG_CFI_CLANG) && defined(CONFIG_LTO_CLANG_THIN)
/*
* LLVM appends a hash to static function names when ThinLTO and CFI are
* both enabled, i.e. foo() becomes foo$707af9a22804d33c81801f27dcfe489b.
* This causes confusion and potentially breaks user space tools, so we
* strip the suffix from expanded symbol names.
*/
static inline bool cleanup_symbol_name(char *s)
static bool cleanup_symbol_name(char *s)
{
char *res;

if (!IS_ENABLED(CONFIG_LTO_CLANG))
return false;

/*
* LLVM appends various suffixes for local functions and variables that
* must be promoted to global scope as part of LTO. This can break
* hooking of static functions with kprobes. '.' is not a valid
* character in an identifier in C. Suffixes observed:
* - foo.llvm.[0-9a-f]+
* - foo.[0-9a-f]+
* - foo.[0-9a-f]+.cfi_jt
*/
res = strchr(s, '.');
if (res) {
*res = '\0';
return true;
}

if (!IS_ENABLED(CONFIG_CFI_CLANG) ||
!IS_ENABLED(CONFIG_LTO_CLANG_THIN) ||
CONFIG_CLANG_VERSION >= 130000)
return false;

/*
* Prior to LLVM 13, the following suffixes were observed when thinLTO
* and CFI are both enabled:
* - foo$[0-9]+
*/
res = strrchr(s, '$');
if (res)
if (res) {
*res = '\0';
return true;
}

return res != NULL;
return false;
}
#else
static inline bool cleanup_symbol_name(char *s) { return false; }
#endif

/* Lookup the address for this symbol. Returns 0 if not found. */
unsigned long kallsyms_lookup_name(const char *name)
Expand Down
2 changes: 0 additions & 2 deletions scripts/Makefile.gcc-plugins
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# SPDX-License-Identifier: GPL-2.0

gcc-plugin-$(CONFIG_GCC_PLUGIN_CYC_COMPLEXITY) += cyc_complexity_plugin.so

gcc-plugin-$(CONFIG_GCC_PLUGIN_LATENT_ENTROPY) += latent_entropy_plugin.so
gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_LATENT_ENTROPY) \
+= -DLATENT_ENTROPY_PLUGIN
Expand Down
20 changes: 2 additions & 18 deletions scripts/gcc-plugins/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,10 @@ menuconfig GCC_PLUGINS

if GCC_PLUGINS

config GCC_PLUGIN_CYC_COMPLEXITY
bool "Compute the cyclomatic complexity of a function" if EXPERT
depends on !COMPILE_TEST # too noisy
help
The complexity M of a function's control flow graph is defined as:
M = E - N + 2P
where

E = the number of edges
N = the number of nodes
P = the number of connected components (exit nodes).

Enabling this plugin reports the complexity to stderr during the
build. It mainly serves as a simple example of how to create a
gcc plugin for the kernel.

config GCC_PLUGIN_SANCOV
bool
# Plugin can be removed once the kernel only supports GCC 6+
depends on !CC_HAS_SANCOV_TRACE_PC
help
This plugin inserts a __sanitizer_cov_trace_pc() call at the start of
basic blocks. It supports all gcc versions with plugin support (from
Expand Down Expand Up @@ -83,8 +69,6 @@ config GCC_PLUGIN_RANDSTRUCT
the existing seed and will be removed by a make mrproper or
make distclean.

Note that the implementation requires gcc 4.7 or newer.

This plugin was ported from grsecurity/PaX. More information at:
* https://grsecurity.net/
* https://pax.grsecurity.net/
Expand Down
69 changes: 0 additions & 69 deletions scripts/gcc-plugins/cyc_complexity_plugin.c

This file was deleted.

Loading

0 comments on commit f594e28

Please sign in to comment.