Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5aadfdeb authored by Masahiro Yamada's avatar Masahiro Yamada
Browse files

kcov: test compiler capability in Kconfig and correct dependency



As Documentation/kbuild/kconfig-language.txt notes, 'select' should be
be used with care - it forces a lower limit of another symbol, ignoring
the dependency.  Currently, KCOV can select GCC_PLUGINS even if arch
does not select HAVE_GCC_PLUGINS.  This could cause the unmet direct
dependency.

Now that Kconfig can test compiler capability, let's handle this in a
more sophisticated way.

There are two ways to enable KCOV; use the compiler that natively
supports -fsanitize-coverage=trace-pc, or build the SANCOV plugin if
the compiler has ability to build GCC plugins.  Hence, the correct
dependency for KCOV is:

  depends on CC_HAS_SANCOV_TRACE_PC || GCC_PLUGINS

You do not need to build the SANCOV plugin if the compiler already
supports -fsanitize-coverage=trace-pc.  Hence, the select should be:

  select GCC_PLUGIN_SANCOV if !CC_HAS_SANCOV_TRACE_PC

With this, GCC_PLUGIN_SANCOV is selected only when necessary, so
scripts/Makefile.gcc-plugins can be cleaner.

I also cleaned up Kconfig and scripts/Makefile.kcov as well.

Signed-off-by: default avatarMasahiro Yamada <yamada.masahiro@socionext.com>
Reviewed-by: default avatarKees Cook <keescook@chromium.org>
parent 6a61b70b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -601,7 +601,7 @@ all: vmlinux
CFLAGS_GCOV	:= -fprofile-arcs -ftest-coverage \
	$(call cc-option,-fno-tree-loop-im) \
	$(call cc-disable-warning,maybe-uninitialized,)
export CFLAGS_GCOV CFLAGS_KCOV
export CFLAGS_GCOV

# The arch Makefile can set ARCH_{CPP,A,C}FLAGS to override the default
# values of the respective KBUILD_* variables
+7 −4
Original line number Diff line number Diff line
@@ -736,12 +736,15 @@ config ARCH_HAS_KCOV
	  only for x86_64. KCOV requires testing on other archs, and most likely
	  disabling of instrumentation for some early boot code.

config CC_HAS_SANCOV_TRACE_PC
	def_bool $(cc-option,-fsanitize-coverage=trace-pc)

config KCOV
	bool "Code coverage for fuzzing"
	depends on ARCH_HAS_KCOV
	depends on CC_HAS_SANCOV_TRACE_PC || GCC_PLUGINS
	select DEBUG_FS
	select GCC_PLUGINS if !COMPILE_TEST
	select GCC_PLUGIN_SANCOV if !COMPILE_TEST
	select GCC_PLUGIN_SANCOV if !CC_HAS_SANCOV_TRACE_PC
	help
	  KCOV exposes kernel code coverage information in a form suitable
	  for coverage-guided fuzzing (randomized testing).
@@ -755,7 +758,7 @@ config KCOV
config KCOV_ENABLE_COMPARISONS
	bool "Enable comparison operands collection by KCOV"
	depends on KCOV
	default n
	depends on $(cc-option,-fsanitize-coverage=trace-cmp)
	help
	  KCOV also exposes operands of every comparison in the instrumented
	  code along with operand sizes and PCs of the comparison instructions.
@@ -765,7 +768,7 @@ config KCOV_ENABLE_COMPARISONS
config KCOV_INSTRUMENT_ALL
	bool "Instrument all code by default"
	depends on KCOV
	default y if KCOV
	default y
	help
	  If you are doing generic system call fuzzing (like e.g. syzkaller),
	  then you will want to instrument the whole kernel and you should
+2 −6
Original line number Diff line number Diff line
@@ -14,17 +14,13 @@ ifdef CONFIG_GCC_PLUGINS
  endif

  ifdef CONFIG_GCC_PLUGIN_SANCOV
    ifeq ($(strip $(CFLAGS_KCOV)),)
      # It is needed because of the gcc-plugin.sh and gcc version checks.
      gcc-plugin-$(CONFIG_GCC_PLUGIN_SANCOV)           += sancov_plugin.so

      ifneq ($(PLUGINCC),)
        CFLAGS_KCOV := $(SANCOV_PLUGIN)
      else
      ifeq ($(PLUGINCC),)
        $(warning warning: cannot use CONFIG_KCOV: -fsanitize-coverage=trace-pc is not supported by compiler)
      endif
  endif
  endif

  gcc-plugin-$(CONFIG_GCC_PLUGIN_STRUCTLEAK)	+= structleak_plugin.so
  gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_VERBOSE)	+= -fplugin-arg-structleak_plugin-verbose
@@ -38,7 +34,7 @@ ifdef CONFIG_GCC_PLUGINS
  GCC_PLUGINS_CFLAGS := $(strip $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) $(gcc-plugin-cflags-y))

  export PLUGINCC GCC_PLUGINS_CFLAGS GCC_PLUGIN GCC_PLUGIN_SUBDIR
  export SANCOV_PLUGIN DISABLE_LATENT_ENTROPY_PLUGIN
  export DISABLE_LATENT_ENTROPY_PLUGIN

  ifneq ($(PLUGINCC),)
    # SANCOV_PLUGIN can be only in CFLAGS_KCOV because avoid duplication.
+6 −4
Original line number Diff line number Diff line
ifdef CONFIG_KCOV
CFLAGS_KCOV	:= $(call cc-option,-fsanitize-coverage=trace-pc,)
ifeq ($(CONFIG_KCOV_ENABLE_COMPARISONS),y)
CFLAGS_KCOV += $(call cc-option,-fsanitize-coverage=trace-cmp,)
endif

kcov-flags-$(CONFIG_CC_HAS_SANCOV_TRACE_PC)	+= -fsanitize-coverage=trace-pc
kcov-flags-$(CONFIG_KCOV_ENABLE_COMPARISONS)	+= -fsanitize-coverage=trace-cmp
kcov-flags-$(CONFIG_GCC_PLUGIN_SANCOV)		+= -fplugin=$(objtree)/scripts/gcc-plugins/sancov_plugin.so

export CFLAGS_KCOV := $(kcov-flags-y)

endif
+0 −4
Original line number Diff line number Diff line
@@ -13,10 +13,6 @@ else
  export HOST_EXTRACXXFLAGS
endif

ifneq ($(CFLAGS_KCOV), $(SANCOV_PLUGIN))
  GCC_PLUGIN := $(filter-out $(SANCOV_PLUGIN), $(GCC_PLUGIN))
endif

export HOSTLIBS

$(obj)/randomize_layout_plugin.o: $(objtree)/$(obj)/randomize_layout_seed.h