linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/7] Clean up UBSAN Makefile
@ 2020-12-03  0:44 Kees Cook
  2020-12-03  0:44 ` [PATCH v2 1/7] ubsan: Remove redundant -Wno-maybe-uninitialized Kees Cook
                   ` (6 more replies)
  0 siblings, 7 replies; 12+ messages in thread
From: Kees Cook @ 2020-12-03  0:44 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kees Cook, Linus Torvalds, Ard Biesheuvel, Arnd Bergmann,
	Masahiro Yamada, Michal Marek, Nathan Chancellor,
	Nick Desaulniers, Marco Elver, Randy Dunlap, Dmitry Vyukov,
	George Popescu, Herbert Xu, Peter Oberparleiter, Andrey Ryabinin,
	clang-built-linux, linux-kbuild, linux-kernel

Hi,

This series attempts to address the issues seen with UBSAN's object-size
sanitizer causing problems under GCC. In the process, the Kconfig and
Makefile are refactored to do all the cc-option calls in the Kconfig.
Additionally start to detangle -Wno-maybe-uninitialized, disable
UBSAN_TRAP under COMPILE_TEST for wider build coverage, and expand the
libusan tests.

Thanks!

-Kees

v2:
- Add reviewed/tested-bys (Nathan Chancellor)
- Reorganize -Wno-maybe-uninitialized changes
- Split up UBSAN_MISC features and document them
- Expand libubsan tests
v1: https://lore.kernel.org/lkml/20201002221527.177500-1-keescook@chromium.org/

Kees Cook (7):
  ubsan: Remove redundant -Wno-maybe-uninitialized
  ubsan: Move cc-option tests into Kconfig
  ubsan: Disable object-size sanitizer under GCC
  ubsan: Disable UBSAN_TRAP for all*config
  ubsan: Enable for all*config builds
  ubsan: Remove UBSAN_MISC in favor of individual options
  ubsan: Expand tests and reporting

 Documentation/dev-tools/ubsan.rst |   1 +
 lib/Kconfig.ubsan                 | 128 +++++++++++++++++++++++++-----
 lib/test_ubsan.c                  |  74 +++++++++++++++--
 scripts/Makefile.ubsan            |  49 ++++--------
 4 files changed, 188 insertions(+), 64 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v2 1/7] ubsan: Remove redundant -Wno-maybe-uninitialized
  2020-12-03  0:44 [PATCH v2 0/7] Clean up UBSAN Makefile Kees Cook
@ 2020-12-03  0:44 ` Kees Cook
  2020-12-03  0:44 ` [PATCH v2 2/7] ubsan: Move cc-option tests into Kconfig Kees Cook
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Kees Cook @ 2020-12-03  0:44 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kees Cook, Linus Torvalds, Ard Biesheuvel, Arnd Bergmann,
	Masahiro Yamada, Michal Marek, Nathan Chancellor,
	Nick Desaulniers, Marco Elver, Randy Dunlap, Dmitry Vyukov,
	George Popescu, Herbert Xu, Peter Oberparleiter, Andrey Ryabinin,
	clang-built-linux, linux-kbuild, linux-kernel

In commit 78a5255ffb6a ("Stop the ad-hoc games with -Wno-maybe-initialized")
-Wmaybe-uninitialized was disabled globally, so keeping the disabling logic
here too doesn't make sense.

Signed-off-by: Kees Cook <keescook@chromium.org>
---
 lib/Kconfig.ubsan      | 4 ----
 scripts/Makefile.ubsan | 4 ----
 2 files changed, 8 deletions(-)

diff --git a/lib/Kconfig.ubsan b/lib/Kconfig.ubsan
index 58f8d03d037b..d8d4d6557b80 100644
--- a/lib/Kconfig.ubsan
+++ b/lib/Kconfig.ubsan
@@ -72,10 +72,6 @@ config UBSAN_MISC
 config UBSAN_SANITIZE_ALL
 	bool "Enable instrumentation for the entire kernel"
 	depends on ARCH_HAS_UBSAN_SANITIZE_ALL
-
-	# We build with -Wno-maybe-uninitilzed, but we still want to
-	# use -Wmaybe-uninitilized in allmodconfig builds.
-	# So dependsy bellow used to disable this option in allmodconfig
 	depends on !COMPILE_TEST
 	default y
 	help
diff --git a/scripts/Makefile.ubsan b/scripts/Makefile.ubsan
index 9716dab06bc7..c18fecc53605 100644
--- a/scripts/Makefile.ubsan
+++ b/scripts/Makefile.ubsan
@@ -31,7 +31,3 @@ endif
 ifdef CONFIG_UBSAN_TRAP
       CFLAGS_UBSAN += $(call cc-option, -fsanitize-undefined-trap-on-error)
 endif
-
-      # -fsanitize=* options makes GCC less smart than usual and
-      # increase number of 'maybe-uninitialized false-positives
-      CFLAGS_UBSAN += $(call cc-option, -Wno-maybe-uninitialized)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 2/7] ubsan: Move cc-option tests into Kconfig
  2020-12-03  0:44 [PATCH v2 0/7] Clean up UBSAN Makefile Kees Cook
  2020-12-03  0:44 ` [PATCH v2 1/7] ubsan: Remove redundant -Wno-maybe-uninitialized Kees Cook
@ 2020-12-03  0:44 ` Kees Cook
  2020-12-03  0:44 ` [PATCH v2 3/7] ubsan: Disable object-size sanitizer under GCC Kees Cook
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Kees Cook @ 2020-12-03  0:44 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kees Cook, Linus Torvalds, Nathan Chancellor, Ard Biesheuvel,
	Arnd Bergmann, Masahiro Yamada, Michal Marek, Nick Desaulniers,
	Marco Elver, Randy Dunlap, Dmitry Vyukov, George Popescu,
	Herbert Xu, Peter Oberparleiter, Andrey Ryabinin,
	clang-built-linux, linux-kbuild, linux-kernel

Instead of doing if/endif blocks with cc-option calls in the UBSAN
Makefile, move all the tests into Kconfig and use the Makefile to
collect the results.

Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/lkml/CAHk-=wjPasyJrDuwDnpHJS2TuQfExwe=px-SzLeN8GFMAQJPmQ@mail.gmail.com/
Reviewed-by: Nathan Chancellor <natechancellor@gmail.com>
Tested-by: Nathan Chancellor <natechancellor@gmail.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 lib/Kconfig.ubsan      | 61 +++++++++++++++++++++++++++++++++++++++---
 scripts/Makefile.ubsan | 45 +++++++++++--------------------
 2 files changed, 73 insertions(+), 33 deletions(-)

diff --git a/lib/Kconfig.ubsan b/lib/Kconfig.ubsan
index d8d4d6557b80..05147112b355 100644
--- a/lib/Kconfig.ubsan
+++ b/lib/Kconfig.ubsan
@@ -36,10 +36,17 @@ config UBSAN_KCOV_BROKEN
 	  See https://bugs.llvm.org/show_bug.cgi?id=45831 for the status
 	  in newer releases.
 
+config CC_HAS_UBSAN_BOUNDS
+	def_bool $(cc-option,-fsanitize=bounds)
+
+config CC_HAS_UBSAN_ARRAY_BOUNDS
+	def_bool $(cc-option,-fsanitize=array-bounds)
+
 config UBSAN_BOUNDS
 	bool "Perform array index bounds checking"
 	default UBSAN
 	depends on !UBSAN_KCOV_BROKEN
+	depends on CC_HAS_UBSAN_ARRAY_BOUNDS || CC_HAS_UBSAN_BOUNDS
 	help
 	  This option enables detection of directly indexed out of bounds
 	  array accesses, where the array size is known at compile time.
@@ -47,15 +54,30 @@ config UBSAN_BOUNDS
 	  to the {str,mem}*cpy() family of functions (that is addressed
 	  by CONFIG_FORTIFY_SOURCE).
 
+config UBSAN_ONLY_BOUNDS
+	def_bool CC_HAS_UBSAN_BOUNDS && !CC_HAS_UBSAN_ARRAY_BOUNDS
+	depends on UBSAN_BOUNDS
+	help
+	  This is a weird case: Clang's -fsanitize=bounds includes
+	  -fsanitize=local-bounds, but it's trapping-only, so for
+	  Clang, we must use -fsanitize=array-bounds when we want
+	  traditional array bounds checking enabled. For GCC, we
+	  want -fsanitize=bounds.
+
+config UBSAN_ARRAY_BOUNDS
+	def_bool CC_HAS_UBSAN_ARRAY_BOUNDS
+	depends on UBSAN_BOUNDS
+
 config UBSAN_LOCAL_BOUNDS
 	bool "Perform array local bounds checking"
 	depends on UBSAN_TRAP
-	depends on CC_IS_CLANG
 	depends on !UBSAN_KCOV_BROKEN
+	depends on $(cc-option,-fsanitize=local-bounds)
 	help
 	  This option enables -fsanitize=local-bounds which traps when an
-	  exception/error is detected. Therefore, it should be enabled only
-	  if trapping is expected.
+	  exception/error is detected. Therefore, it may only be enabled
+	  with CONFIG_UBSAN_TRAP.
+
 	  Enabling this option detects errors due to accesses through a
 	  pointer that is derived from an object of a statically-known size,
 	  where an added offset (which may not be known statically) is
@@ -69,6 +91,38 @@ config UBSAN_MISC
 	  own Kconfig options. Disable this if you only want to have
 	  individually selected checks.
 
+config UBSAN_SHIFT
+	def_bool UBSAN_MISC
+	depends on $(cc-option,-fsanitize=shift)
+
+config UBSAN_DIV_ZERO
+	def_bool UBSAN_MISC
+	depends on $(cc-option,-fsanitize=integer-divide-by-zero)
+
+config UBSAN_UNREACHABLE
+	def_bool UBSAN_MISC
+	depends on $(cc-option,-fsanitize=unreachable)
+
+config UBSAN_SIGNED_OVERFLOW
+	def_bool UBSAN_MISC
+	depends on $(cc-option,-fsanitize=signed-integer-overflow)
+
+config UBSAN_UNSIGNED_OVERFLOW
+	def_bool UBSAN_MISC
+	depends on $(cc-option,-fsanitize=unsigned-integer-overflow)
+
+config UBSAN_OBJECT_SIZE
+	def_bool UBSAN_MISC
+	depends on $(cc-option,-fsanitize=object-size)
+
+config UBSAN_BOOL
+	def_bool UBSAN_MISC
+	depends on $(cc-option,-fsanitize=bool)
+
+config UBSAN_ENUM
+	def_bool UBSAN_MISC
+	depends on $(cc-option,-fsanitize=enum)
+
 config UBSAN_SANITIZE_ALL
 	bool "Enable instrumentation for the entire kernel"
 	depends on ARCH_HAS_UBSAN_SANITIZE_ALL
@@ -85,6 +139,7 @@ config UBSAN_ALIGNMENT
 	bool "Enable checks for pointers alignment"
 	default !HAVE_EFFICIENT_UNALIGNED_ACCESS
 	depends on !UBSAN_TRAP
+	depends on $(cc-option,-fsanitize=alignment)
 	help
 	  This option enables the check of unaligned memory accesses.
 	  Enabling this option on architectures that support unaligned
diff --git a/scripts/Makefile.ubsan b/scripts/Makefile.ubsan
index c18fecc53605..0e53a93e8f15 100644
--- a/scripts/Makefile.ubsan
+++ b/scripts/Makefile.ubsan
@@ -1,33 +1,18 @@
 # SPDX-License-Identifier: GPL-2.0
 
-export CFLAGS_UBSAN :=
+# Enable available and selected UBSAN features.
+ubsan-cflags-$(CONFIG_UBSAN_ALIGNMENT)		+= -fsanitize=alignment
+ubsan-cflags-$(CONFIG_UBSAN_ONLY_BOUNDS)	+= -fsanitize=bounds
+ubsan-cflags-$(CONFIG_UBSAN_ARRAY_BOUNDS)	+= -fsanitize=array-bounds
+ubsan-cflags-$(CONFIG_UBSAN_LOCAL_BOUNDS)	+= -fsanitize=local-bounds
+ubsan-cflags-$(CONFIG_UBSAN_SHIFT)		+= -fsanitize=shift
+ubsan-cflags-$(CONFIG_UBSAN_DIV_ZERO)		+= -fsanitize=integer-divide-by-zero
+ubsan-cflags-$(CONFIG_UBSAN_UNREACHABLE)	+= -fsanitize=unreachable
+ubsan-cflags-$(CONFIG_UBSAN_SIGNED_OVERFLOW)	+= -fsanitize=signed-integer-overflow
+ubsan-cflags-$(CONFIG_UBSAN_UNSIGNED_OVERFLOW)	+= -fsanitize=unsigned-integer-overflow
+ubsan-cflags-$(CONFIG_UBSAN_OBJECT_SIZE)	+= -fsanitize=object-size
+ubsan-cflags-$(CONFIG_UBSAN_BOOL)		+= -fsanitize=bool
+ubsan-cflags-$(CONFIG_UBSAN_ENUM)		+= -fsanitize=enum
+ubsan-cflags-$(CONFIG_UBSAN_TRAP)		+= -fsanitize-undefined-trap-on-error
 
-ifdef CONFIG_UBSAN_ALIGNMENT
-      CFLAGS_UBSAN += $(call cc-option, -fsanitize=alignment)
-endif
-
-ifdef CONFIG_UBSAN_BOUNDS
-      ifdef CONFIG_CC_IS_CLANG
-            CFLAGS_UBSAN += -fsanitize=array-bounds
-      else
-            CFLAGS_UBSAN += $(call cc-option, -fsanitize=bounds)
-      endif
-endif
-
-ifdef CONFIG_UBSAN_LOCAL_BOUNDS
-      CFLAGS_UBSAN += -fsanitize=local-bounds
-endif
-
-ifdef CONFIG_UBSAN_MISC
-      CFLAGS_UBSAN += $(call cc-option, -fsanitize=shift)
-      CFLAGS_UBSAN += $(call cc-option, -fsanitize=integer-divide-by-zero)
-      CFLAGS_UBSAN += $(call cc-option, -fsanitize=unreachable)
-      CFLAGS_UBSAN += $(call cc-option, -fsanitize=signed-integer-overflow)
-      CFLAGS_UBSAN += $(call cc-option, -fsanitize=object-size)
-      CFLAGS_UBSAN += $(call cc-option, -fsanitize=bool)
-      CFLAGS_UBSAN += $(call cc-option, -fsanitize=enum)
-endif
-
-ifdef CONFIG_UBSAN_TRAP
-      CFLAGS_UBSAN += $(call cc-option, -fsanitize-undefined-trap-on-error)
-endif
+export CFLAGS_UBSAN := $(ubsan-cflags-y)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 3/7] ubsan: Disable object-size sanitizer under GCC
  2020-12-03  0:44 [PATCH v2 0/7] Clean up UBSAN Makefile Kees Cook
  2020-12-03  0:44 ` [PATCH v2 1/7] ubsan: Remove redundant -Wno-maybe-uninitialized Kees Cook
  2020-12-03  0:44 ` [PATCH v2 2/7] ubsan: Move cc-option tests into Kconfig Kees Cook
@ 2020-12-03  0:44 ` Kees Cook
  2020-12-03  0:44 ` [PATCH v2 4/7] ubsan: Disable UBSAN_TRAP for all*config Kees Cook
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Kees Cook @ 2020-12-03  0:44 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kees Cook, Linus Torvalds, Nathan Chancellor, Ard Biesheuvel,
	Arnd Bergmann, Masahiro Yamada, Michal Marek, Nick Desaulniers,
	Marco Elver, Randy Dunlap, Dmitry Vyukov, George Popescu,
	Herbert Xu, Peter Oberparleiter, Andrey Ryabinin,
	clang-built-linux, linux-kbuild, linux-kernel

GCC's -fsanitize=object-size (as part of CONFIG_UBSAN_MISC) greatly
increases stack utilization. Do not allow this under GCC.

Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/lkml/CAHk-=wjPasyJrDuwDnpHJS2TuQfExwe=px-SzLeN8GFMAQJPmQ@mail.gmail.com/
Reviewed-by: Nathan Chancellor <natechancellor@gmail.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 lib/Kconfig.ubsan | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/lib/Kconfig.ubsan b/lib/Kconfig.ubsan
index 05147112b355..4190a99b1eaa 100644
--- a/lib/Kconfig.ubsan
+++ b/lib/Kconfig.ubsan
@@ -113,6 +113,9 @@ config UBSAN_UNSIGNED_OVERFLOW
 
 config UBSAN_OBJECT_SIZE
 	def_bool UBSAN_MISC
+	# gcc hugely expands stack usage with -fsanitize=object-size
+	# https://lore.kernel.org/lkml/CAHk-=wjPasyJrDuwDnpHJS2TuQfExwe=px-SzLeN8GFMAQJPmQ@mail.gmail.com/
+	depends on !CC_IS_GCC
 	depends on $(cc-option,-fsanitize=object-size)
 
 config UBSAN_BOOL
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 4/7] ubsan: Disable UBSAN_TRAP for all*config
  2020-12-03  0:44 [PATCH v2 0/7] Clean up UBSAN Makefile Kees Cook
                   ` (2 preceding siblings ...)
  2020-12-03  0:44 ` [PATCH v2 3/7] ubsan: Disable object-size sanitizer under GCC Kees Cook
@ 2020-12-03  0:44 ` Kees Cook
  2020-12-03  0:44 ` [PATCH v2 5/7] ubsan: Enable for all*config builds Kees Cook
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Kees Cook @ 2020-12-03  0:44 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kees Cook, Nathan Chancellor, Linus Torvalds, Ard Biesheuvel,
	Arnd Bergmann, Masahiro Yamada, Michal Marek, Nick Desaulniers,
	Marco Elver, Randy Dunlap, Dmitry Vyukov, George Popescu,
	Herbert Xu, Peter Oberparleiter, Andrey Ryabinin,
	clang-built-linux, linux-kbuild, linux-kernel

Doing all*config builds attempts to build as much as possible. UBSAN_TRAP
effectively short-circuits lib/usban.c, so it should be disabled for
COMPILE_TEST so that the lib/ubsan.c code gets built.

Reviewed-by: Nathan Chancellor <natechancellor@gmail.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 lib/Kconfig.ubsan | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/Kconfig.ubsan b/lib/Kconfig.ubsan
index 4190a99b1eaa..6e8b67d4b0d9 100644
--- a/lib/Kconfig.ubsan
+++ b/lib/Kconfig.ubsan
@@ -14,6 +14,7 @@ if UBSAN
 
 config UBSAN_TRAP
 	bool "On Sanitizer warnings, abort the running kernel code"
+	depends on !COMPILE_TEST
 	depends on $(cc-option, -fsanitize-undefined-trap-on-error)
 	help
 	  Building kernels with Sanitizer features enabled tends to grow
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 5/7] ubsan: Enable for all*config builds
  2020-12-03  0:44 [PATCH v2 0/7] Clean up UBSAN Makefile Kees Cook
                   ` (3 preceding siblings ...)
  2020-12-03  0:44 ` [PATCH v2 4/7] ubsan: Disable UBSAN_TRAP for all*config Kees Cook
@ 2020-12-03  0:44 ` Kees Cook
  2020-12-03  8:51   ` Arnd Bergmann
  2020-12-03  0:44 ` [PATCH v2 6/7] ubsan: Remove UBSAN_MISC in favor of individual options Kees Cook
  2020-12-03  0:44 ` [PATCH v2 7/7] ubsan: Expand tests and reporting Kees Cook
  6 siblings, 1 reply; 12+ messages in thread
From: Kees Cook @ 2020-12-03  0:44 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kees Cook, Linus Torvalds, Ard Biesheuvel, Arnd Bergmann,
	Masahiro Yamada, Michal Marek, Nathan Chancellor,
	Nick Desaulniers, Marco Elver, Randy Dunlap, Dmitry Vyukov,
	George Popescu, Herbert Xu, Peter Oberparleiter, Andrey Ryabinin,
	clang-built-linux, linux-kbuild, linux-kernel

With UBSAN_OBJECT_SIZE disabled for GCC, only UBSAN_ALIGNMENT remained
a noisy UBSAN option. Disable it for COMPILE_TEST so the rest of UBSAN
can be used for full all*config builds or other large combinations.

Link: https://lore.kernel.org/lkml/CAHk-=wgXW=YLxGN0QVpp-1w5GDd2pf1W-FqY15poKzoVfik2qA@mail.gmail.com/
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 lib/Kconfig.ubsan | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/lib/Kconfig.ubsan b/lib/Kconfig.ubsan
index 6e8b67d4b0d9..fa78f0f3c1dc 100644
--- a/lib/Kconfig.ubsan
+++ b/lib/Kconfig.ubsan
@@ -130,7 +130,6 @@ config UBSAN_ENUM
 config UBSAN_SANITIZE_ALL
 	bool "Enable instrumentation for the entire kernel"
 	depends on ARCH_HAS_UBSAN_SANITIZE_ALL
-	depends on !COMPILE_TEST
 	default y
 	help
 	  This option activates instrumentation for the entire kernel.
@@ -142,7 +141,7 @@ config UBSAN_SANITIZE_ALL
 config UBSAN_ALIGNMENT
 	bool "Enable checks for pointers alignment"
 	default !HAVE_EFFICIENT_UNALIGNED_ACCESS
-	depends on !UBSAN_TRAP
+	depends on !UBSAN_TRAP && !COMPILE_TEST
 	depends on $(cc-option,-fsanitize=alignment)
 	help
 	  This option enables the check of unaligned memory accesses.
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 6/7] ubsan: Remove UBSAN_MISC in favor of individual options
  2020-12-03  0:44 [PATCH v2 0/7] Clean up UBSAN Makefile Kees Cook
                   ` (4 preceding siblings ...)
  2020-12-03  0:44 ` [PATCH v2 5/7] ubsan: Enable for all*config builds Kees Cook
@ 2020-12-03  0:44 ` Kees Cook
  2020-12-03  0:44 ` [PATCH v2 7/7] ubsan: Expand tests and reporting Kees Cook
  6 siblings, 0 replies; 12+ messages in thread
From: Kees Cook @ 2020-12-03  0:44 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kees Cook, Linus Torvalds, Ard Biesheuvel, Arnd Bergmann,
	Masahiro Yamada, Michal Marek, Nathan Chancellor,
	Nick Desaulniers, Marco Elver, Randy Dunlap, Dmitry Vyukov,
	George Popescu, Herbert Xu, Peter Oberparleiter, Andrey Ryabinin,
	clang-built-linux, linux-kbuild, linux-kernel

Make each UBSAN option individually selectable and remove UBSAN_MISC
which no longer has any purpose. Add help text for each Kconfig, and
include a reference to the Clang sanitizer documentation. Disable
unsigned overflow by default (not available with GCC and makes x86
unbootable with Clang). Disable unreachable when objtool is in use
(redundant and confuses things: instrumentation appears at unreachable
locations).

Signed-off-by: Kees Cook <keescook@chromium.org>
---
 Documentation/dev-tools/ubsan.rst |  1 +
 lib/Kconfig.ubsan                 | 82 +++++++++++++++++++++----------
 2 files changed, 57 insertions(+), 26 deletions(-)

diff --git a/Documentation/dev-tools/ubsan.rst b/Documentation/dev-tools/ubsan.rst
index 655e6b63c227..1be6618e232d 100644
--- a/Documentation/dev-tools/ubsan.rst
+++ b/Documentation/dev-tools/ubsan.rst
@@ -86,3 +86,4 @@ References
 
 .. _1: https://gcc.gnu.org/onlinedocs/gcc-4.9.0/gcc/Debugging-Options.html
 .. _2: https://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html
+.. _3: https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
diff --git a/lib/Kconfig.ubsan b/lib/Kconfig.ubsan
index fa78f0f3c1dc..8b635fd75fe4 100644
--- a/lib/Kconfig.ubsan
+++ b/lib/Kconfig.ubsan
@@ -84,48 +84,88 @@ config UBSAN_LOCAL_BOUNDS
 	  where an added offset (which may not be known statically) is
 	  out-of-bounds.
 
-config UBSAN_MISC
-	bool "Enable all other Undefined Behavior sanity checks"
-	default UBSAN
-	help
-	  This option enables all sanity checks that don't have their
-	  own Kconfig options. Disable this if you only want to have
-	  individually selected checks.
-
 config UBSAN_SHIFT
-	def_bool UBSAN_MISC
+	bool "Perform checking for bit-shift overflows"
+	default UBSAN
 	depends on $(cc-option,-fsanitize=shift)
+	help
+	  This option enables -fsanitize=shift which checks for bit-shift
+	  operations that overflow to the left or go switch to negative
+	  for signed types.
 
 config UBSAN_DIV_ZERO
-	def_bool UBSAN_MISC
+	bool "Perform checking for integer divide-by-zero"
 	depends on $(cc-option,-fsanitize=integer-divide-by-zero)
+	help
+	  This option enables -fsanitize=integer-divide-by-zero which checks
+	  for integer division by zero. This is effectively redundant with the
+	  kernel's existing exception handling, though it can provide greater
+	  debugging information under CONFIG_UBSAN_REPORT_FULL.
 
 config UBSAN_UNREACHABLE
-	def_bool UBSAN_MISC
+	bool "Perform checking for unreachable code"
+	# objtool already handles unreachable checking and gets angry about
+	# seeing UBSan instrumentation located in unreachable places.
+	depends on !STACK_VALIDATION
 	depends on $(cc-option,-fsanitize=unreachable)
+	help
+	  This option enables -fsanitize=unreachable which checks for control
+	  flow reaching an expected-to-be-unreachable position.
 
 config UBSAN_SIGNED_OVERFLOW
-	def_bool UBSAN_MISC
+	bool "Perform checking for signed arithmetic overflow"
+	default UBSAN
 	depends on $(cc-option,-fsanitize=signed-integer-overflow)
+	help
+	  This option enables -fsanitize=signed-integer-overflow which checks
+	  for overflow of any arithmetic operations with signed integers.
 
 config UBSAN_UNSIGNED_OVERFLOW
-	def_bool UBSAN_MISC
+	bool "Perform checking for unsigned arithmetic overflow"
 	depends on $(cc-option,-fsanitize=unsigned-integer-overflow)
+	help
+	  This option enables -fsanitize=unsigned-integer-overflow which checks
+	  for overflow of any arithmetic operations with unsigned integers. This
+	  currently causes x86 to fail to boot.
 
 config UBSAN_OBJECT_SIZE
-	def_bool UBSAN_MISC
+	bool "Perform checking for accesses beyond the end of objects"
+	default UBSAN
 	# gcc hugely expands stack usage with -fsanitize=object-size
 	# https://lore.kernel.org/lkml/CAHk-=wjPasyJrDuwDnpHJS2TuQfExwe=px-SzLeN8GFMAQJPmQ@mail.gmail.com/
 	depends on !CC_IS_GCC
 	depends on $(cc-option,-fsanitize=object-size)
+	help
+	  This option enables -fsanitize=object-size which checks for accesses
+	  beyond the end of objects where the optimizer can determine both the
+	  object being operated on and its size, usually seen with bad downcasts,
+	  or access to struct members from NULL pointers.
 
 config UBSAN_BOOL
-	def_bool UBSAN_MISC
+	bool "Perform checking for non-boolean values used as boolean"
+	default UBSAN
 	depends on $(cc-option,-fsanitize=bool)
+	help
+	  This option enables -fsanitize=bool which checks for boolean values being
+	  loaded that are neither 0 nor 1.
 
 config UBSAN_ENUM
-	def_bool UBSAN_MISC
+	bool "Perform checking for out of bounds enum values"
+	default UBSAN
 	depends on $(cc-option,-fsanitize=enum)
+	help
+	  This option enables -fsanitize=enum which checks for values being loaded
+	  into an enum that are outside the range of given values for the given enum.
+
+config UBSAN_ALIGNMENT
+	bool "Perform checking for misaligned pointer usage"
+	default !HAVE_EFFICIENT_UNALIGNED_ACCESS
+	depends on !UBSAN_TRAP && !COMPILE_TEST
+	depends on $(cc-option,-fsanitize=alignment)
+	help
+	  This option enables the check of unaligned memory accesses.
+	  Enabling this option on architectures that support unaligned
+	  accesses may produce a lot of false positives.
 
 config UBSAN_SANITIZE_ALL
 	bool "Enable instrumentation for the entire kernel"
@@ -138,16 +178,6 @@ config UBSAN_SANITIZE_ALL
 	  Enabling this option will get kernel image size increased
 	  significantly.
 
-config UBSAN_ALIGNMENT
-	bool "Enable checks for pointers alignment"
-	default !HAVE_EFFICIENT_UNALIGNED_ACCESS
-	depends on !UBSAN_TRAP && !COMPILE_TEST
-	depends on $(cc-option,-fsanitize=alignment)
-	help
-	  This option enables the check of unaligned memory accesses.
-	  Enabling this option on architectures that support unaligned
-	  accesses may produce a lot of false positives.
-
 config TEST_UBSAN
 	tristate "Module for testing for undefined behavior detection"
 	depends on m
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 7/7] ubsan: Expand tests and reporting
  2020-12-03  0:44 [PATCH v2 0/7] Clean up UBSAN Makefile Kees Cook
                   ` (5 preceding siblings ...)
  2020-12-03  0:44 ` [PATCH v2 6/7] ubsan: Remove UBSAN_MISC in favor of individual options Kees Cook
@ 2020-12-03  0:44 ` Kees Cook
  6 siblings, 0 replies; 12+ messages in thread
From: Kees Cook @ 2020-12-03  0:44 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kees Cook, Linus Torvalds, Ard Biesheuvel, Arnd Bergmann,
	Masahiro Yamada, Michal Marek, Nathan Chancellor,
	Nick Desaulniers, Marco Elver, Randy Dunlap, Dmitry Vyukov,
	George Popescu, Herbert Xu, Peter Oberparleiter, Andrey Ryabinin,
	clang-built-linux, linux-kbuild, linux-kernel

Expand the UBSAN tests to include some additional UB cases. Notably the
out-of-bounds enum loading appears not to work. Also include per-test
reporting, including the relevant CONFIG_UBSAN... Kconfigs.

Signed-off-by: Kees Cook <keescook@chromium.org>
---
 lib/test_ubsan.c | 74 ++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 66 insertions(+), 8 deletions(-)

diff --git a/lib/test_ubsan.c b/lib/test_ubsan.c
index 9ea10adf7a66..5e5d9355ef49 100644
--- a/lib/test_ubsan.c
+++ b/lib/test_ubsan.c
@@ -5,32 +5,54 @@
 
 typedef void(*test_ubsan_fp)(void);
 
+#define UBSAN_TEST(config, ...)	do {					\
+		pr_info("%s " __VA_ARGS__ "%s(%s=%s)\n", __func__,	\
+			sizeof(" " __VA_ARGS__) > 2 ? " " : "",		\
+			#config, IS_ENABLED(config) ? "y" : "n");	\
+	} while (0)
+
 static void test_ubsan_add_overflow(void)
 {
 	volatile int val = INT_MAX;
+	volatile unsigned int uval = UINT_MAX;
 
+	UBSAN_TEST(CONFIG_UBSAN_SIGNED_OVERFLOW);
 	val += 2;
+
+	UBSAN_TEST(CONFIG_UBSAN_UNSIGNED_OVERFLOW);
+	uval += 2;
 }
 
 static void test_ubsan_sub_overflow(void)
 {
 	volatile int val = INT_MIN;
+	volatile unsigned int uval = 0;
 	volatile int val2 = 2;
 
+	UBSAN_TEST(CONFIG_UBSAN_SIGNED_OVERFLOW);
 	val -= val2;
+
+	UBSAN_TEST(CONFIG_UBSAN_UNSIGNED_OVERFLOW);
+	uval -= val2;
 }
 
 static void test_ubsan_mul_overflow(void)
 {
 	volatile int val = INT_MAX / 2;
+	volatile unsigned int uval = UINT_MAX / 2;
 
+	UBSAN_TEST(CONFIG_UBSAN_SIGNED_OVERFLOW);
 	val *= 3;
+
+	UBSAN_TEST(CONFIG_UBSAN_UNSIGNED_OVERFLOW);
+	uval *= 3;
 }
 
 static void test_ubsan_negate_overflow(void)
 {
 	volatile int val = INT_MIN;
 
+	UBSAN_TEST(CONFIG_UBSAN_SIGNED_OVERFLOW);
 	val = -val;
 }
 
@@ -39,37 +61,67 @@ static void test_ubsan_divrem_overflow(void)
 	volatile int val = 16;
 	volatile int val2 = 0;
 
+	UBSAN_TEST(CONFIG_UBSAN_DIV_ZERO);
 	val /= val2;
 }
 
 static void test_ubsan_shift_out_of_bounds(void)
 {
-	volatile int val = -1;
-	int val2 = 10;
+	volatile int neg = -1, wrap = 4;
+	int val1 = 10;
+	int val2 = INT_MAX;
+
+	UBSAN_TEST(CONFIG_UBSAN_SHIFT, "negative exponent");
+	val1 <<= neg;
 
-	val2 <<= val;
+	UBSAN_TEST(CONFIG_UBSAN_SHIFT, "left overflow");
+	val2 <<= wrap;
 }
 
 static void test_ubsan_out_of_bounds(void)
 {
-	volatile int i = 4, j = 5;
+	volatile int i = 4, j = 5, k = -1;
+	volatile char above[4] = { }; /* Protect surrounding memory. */
 	volatile int arr[4];
+	volatile char below[4] = { }; /* Protect surrounding memory. */
 
+	above[0] = below[0];
+
+	UBSAN_TEST(CONFIG_UBSAN_BOUNDS, "above");
 	arr[j] = i;
+
+	UBSAN_TEST(CONFIG_UBSAN_BOUNDS, "below");
+	arr[k] = i;
 }
 
+enum ubsan_test_enum {
+	UBSAN_TEST_ZERO = 0,
+	UBSAN_TEST_ONE,
+	UBSAN_TEST_MAX,
+};
+
 static void test_ubsan_load_invalid_value(void)
 {
 	volatile char *dst, *src;
 	bool val, val2, *ptr;
-	char c = 4;
+	enum ubsan_test_enum eval, eval2, *eptr;
+	unsigned char c = 0xff;
 
+	UBSAN_TEST(CONFIG_UBSAN_BOOL, "bool");
 	dst = (char *)&val;
 	src = &c;
 	*dst = *src;
 
 	ptr = &val2;
 	val2 = val;
+
+	UBSAN_TEST(CONFIG_UBSAN_ENUM, "enum");
+	dst = (char *)&eval;
+	src = &c;
+	*dst = *src;
+
+	eptr = &eval2;
+	eval2 = eval;
 }
 
 static void test_ubsan_null_ptr_deref(void)
@@ -77,6 +129,7 @@ static void test_ubsan_null_ptr_deref(void)
 	volatile int *ptr = NULL;
 	int val;
 
+	UBSAN_TEST(CONFIG_UBSAN_OBJECT_SIZE);
 	val = *ptr;
 }
 
@@ -85,6 +138,7 @@ static void test_ubsan_misaligned_access(void)
 	volatile char arr[5] __aligned(4) = {1, 2, 3, 4, 5};
 	volatile int *ptr, val = 6;
 
+	UBSAN_TEST(CONFIG_UBSAN_ALIGNMENT);
 	ptr = (int *)(arr + 1);
 	*ptr = val;
 }
@@ -95,6 +149,7 @@ static void test_ubsan_object_size_mismatch(void)
 	volatile int val __aligned(8) = 4;
 	volatile long long *ptr, val2;
 
+	UBSAN_TEST(CONFIG_UBSAN_OBJECT_SIZE);
 	ptr = (long long *)&val;
 	val2 = *ptr;
 }
@@ -104,15 +159,19 @@ static const test_ubsan_fp test_ubsan_array[] = {
 	test_ubsan_sub_overflow,
 	test_ubsan_mul_overflow,
 	test_ubsan_negate_overflow,
-	test_ubsan_divrem_overflow,
 	test_ubsan_shift_out_of_bounds,
 	test_ubsan_out_of_bounds,
 	test_ubsan_load_invalid_value,
-	//test_ubsan_null_ptr_deref, /* exclude it because there is a crash */
 	test_ubsan_misaligned_access,
 	test_ubsan_object_size_mismatch,
 };
 
+/* Excluded because they Oops the module. */
+static const test_ubsan_fp skip_ubsan_array[] = {
+	test_ubsan_divrem_overflow,
+	test_ubsan_null_ptr_deref,
+};
+
 static int __init test_ubsan_init(void)
 {
 	unsigned int i;
@@ -120,7 +179,6 @@ static int __init test_ubsan_init(void)
 	for (i = 0; i < ARRAY_SIZE(test_ubsan_array); i++)
 		test_ubsan_array[i]();
 
-	(void)test_ubsan_null_ptr_deref; /* to avoid unsed-function warning */
 	return 0;
 }
 module_init(test_ubsan_init);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 5/7] ubsan: Enable for all*config builds
  2020-12-03  0:44 ` [PATCH v2 5/7] ubsan: Enable for all*config builds Kees Cook
@ 2020-12-03  8:51   ` Arnd Bergmann
  2020-12-05  0:46     ` Kees Cook
  2020-12-09 18:46     ` Kees Cook
  0 siblings, 2 replies; 12+ messages in thread
From: Arnd Bergmann @ 2020-12-03  8:51 UTC (permalink / raw)
  To: Kees Cook
  Cc: Andrew Morton, Linus Torvalds, Ard Biesheuvel, Arnd Bergmann,
	Masahiro Yamada, Michal Marek, Nathan Chancellor,
	Nick Desaulniers, Marco Elver, Randy Dunlap, Dmitry Vyukov,
	George Popescu, Herbert Xu, Peter Oberparleiter, Andrey Ryabinin,
	clang-built-linux, Linux Kbuild mailing list, linux-kernel

On Thu, Dec 3, 2020 at 1:44 AM Kees Cook <keescook@chromium.org> wrote:
>
> With UBSAN_OBJECT_SIZE disabled for GCC, only UBSAN_ALIGNMENT remained
> a noisy UBSAN option. Disable it for COMPILE_TEST so the rest of UBSAN
> can be used for full all*config builds or other large combinations.
>
> Link: https://lore.kernel.org/lkml/CAHk-=wgXW=YLxGN0QVpp-1w5GDd2pf1W-FqY15poKzoVfik2qA@mail.gmail.com/
> Signed-off-by: Kees Cook <keescook@chromium.org>

Have you checked if this has a notable impact on allmodconfig compile speed
with gcc or clang? I think I've seen significant increases in build times before
with this, but I don't remember the actual magnitude.

Making it 20% slower would probably be ok, but making it twice as slow might
be too much.

       Arnd

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 5/7] ubsan: Enable for all*config builds
  2020-12-03  8:51   ` Arnd Bergmann
@ 2020-12-05  0:46     ` Kees Cook
  2020-12-09 18:46     ` Kees Cook
  1 sibling, 0 replies; 12+ messages in thread
From: Kees Cook @ 2020-12-05  0:46 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Andrew Morton, Linus Torvalds, Ard Biesheuvel, Arnd Bergmann,
	Masahiro Yamada, Michal Marek, Nathan Chancellor,
	Nick Desaulniers, Marco Elver, Randy Dunlap, Dmitry Vyukov,
	George Popescu, Herbert Xu, Peter Oberparleiter, Andrey Ryabinin,
	clang-built-linux, Linux Kbuild mailing list, linux-kernel

On Thu, Dec 03, 2020 at 09:51:40AM +0100, Arnd Bergmann wrote:
> On Thu, Dec 3, 2020 at 1:44 AM Kees Cook <keescook@chromium.org> wrote:
> >
> > With UBSAN_OBJECT_SIZE disabled for GCC, only UBSAN_ALIGNMENT remained
> > a noisy UBSAN option. Disable it for COMPILE_TEST so the rest of UBSAN
> > can be used for full all*config builds or other large combinations.
> >
> > Link: https://lore.kernel.org/lkml/CAHk-=wgXW=YLxGN0QVpp-1w5GDd2pf1W-FqY15poKzoVfik2qA@mail.gmail.com/
> > Signed-off-by: Kees Cook <keescook@chromium.org>
> 
> Have you checked if this has a notable impact on allmodconfig compile speed
> with gcc or clang? I think I've seen significant increases in build times before
> with this, but I don't remember the actual magnitude.
> 
> Making it 20% slower would probably be ok, but making it twice as slow might
> be too much.

For an x86_64 gcc allmodconfig before, I was seeing around 6m2s. After,
I'm seeing around 6m17s, so that's about 8% longer build time.

I will double-check clang...

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 5/7] ubsan: Enable for all*config builds
  2020-12-03  8:51   ` Arnd Bergmann
  2020-12-05  0:46     ` Kees Cook
@ 2020-12-09 18:46     ` Kees Cook
  2020-12-09 19:25       ` Arnd Bergmann
  1 sibling, 1 reply; 12+ messages in thread
From: Kees Cook @ 2020-12-09 18:46 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Andrew Morton, Linus Torvalds, Ard Biesheuvel, Arnd Bergmann,
	Masahiro Yamada, Michal Marek, Nathan Chancellor,
	Nick Desaulniers, Marco Elver, Randy Dunlap, Dmitry Vyukov,
	George Popescu, Herbert Xu, Peter Oberparleiter, Andrey Ryabinin,
	clang-built-linux, Linux Kbuild mailing list, linux-kernel

On Thu, Dec 03, 2020 at 09:51:40AM +0100, Arnd Bergmann wrote:
> On Thu, Dec 3, 2020 at 1:44 AM Kees Cook <keescook@chromium.org> wrote:
> >
> > With UBSAN_OBJECT_SIZE disabled for GCC, only UBSAN_ALIGNMENT remained
> > a noisy UBSAN option. Disable it for COMPILE_TEST so the rest of UBSAN
> > can be used for full all*config builds or other large combinations.
> >
> > Link: https://lore.kernel.org/lkml/CAHk-=wgXW=YLxGN0QVpp-1w5GDd2pf1W-FqY15poKzoVfik2qA@mail.gmail.com/
> > Signed-off-by: Kees Cook <keescook@chromium.org>
> 
> Have you checked if this has a notable impact on allmodconfig compile speed
> with gcc or clang? I think I've seen significant increases in build times before
> with this, but I don't remember the actual magnitude.
> 
> Making it 20% slower would probably be ok, but making it twice as slow might
> be too much.

And for Clang, it's about 7m40s before and 8m30s after, so roughly 12% slower.

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 5/7] ubsan: Enable for all*config builds
  2020-12-09 18:46     ` Kees Cook
@ 2020-12-09 19:25       ` Arnd Bergmann
  0 siblings, 0 replies; 12+ messages in thread
From: Arnd Bergmann @ 2020-12-09 19:25 UTC (permalink / raw)
  To: Kees Cook
  Cc: Andrew Morton, Linus Torvalds, Ard Biesheuvel, Arnd Bergmann,
	Masahiro Yamada, Michal Marek, Nathan Chancellor,
	Nick Desaulniers, Marco Elver, Randy Dunlap, Dmitry Vyukov,
	George Popescu, Herbert Xu, Peter Oberparleiter, Andrey Ryabinin,
	clang-built-linux, Linux Kbuild mailing list, linux-kernel

On Wed, Dec 9, 2020 at 7:46 PM Kees Cook <keescook@chromium.org> wrote:
>
> On Thu, Dec 03, 2020 at 09:51:40AM +0100, Arnd Bergmann wrote:
> > On Thu, Dec 3, 2020 at 1:44 AM Kees Cook <keescook@chromium.org> wrote:
> > >
> > > With UBSAN_OBJECT_SIZE disabled for GCC, only UBSAN_ALIGNMENT remained
> > > a noisy UBSAN option. Disable it for COMPILE_TEST so the rest of UBSAN
> > > can be used for full all*config builds or other large combinations.
> > >
> > > Link: https://lore.kernel.org/lkml/CAHk-=wgXW=YLxGN0QVpp-1w5GDd2pf1W-FqY15poKzoVfik2qA@mail.gmail.com/
> > > Signed-off-by: Kees Cook <keescook@chromium.org>
> >
> > Have you checked if this has a notable impact on allmodconfig compile speed
> > with gcc or clang? I think I've seen significant increases in build times before
> > with this, but I don't remember the actual magnitude.
> >
> > Making it 20% slower would probably be ok, but making it twice as slow might
> > be too much.
>
> And for Clang, it's about 7m40s before and 8m30s after, so roughly 12% slower.

Ok, that doesn't sound too bad then.

       Arnd

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2020-12-09 19:26 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-03  0:44 [PATCH v2 0/7] Clean up UBSAN Makefile Kees Cook
2020-12-03  0:44 ` [PATCH v2 1/7] ubsan: Remove redundant -Wno-maybe-uninitialized Kees Cook
2020-12-03  0:44 ` [PATCH v2 2/7] ubsan: Move cc-option tests into Kconfig Kees Cook
2020-12-03  0:44 ` [PATCH v2 3/7] ubsan: Disable object-size sanitizer under GCC Kees Cook
2020-12-03  0:44 ` [PATCH v2 4/7] ubsan: Disable UBSAN_TRAP for all*config Kees Cook
2020-12-03  0:44 ` [PATCH v2 5/7] ubsan: Enable for all*config builds Kees Cook
2020-12-03  8:51   ` Arnd Bergmann
2020-12-05  0:46     ` Kees Cook
2020-12-09 18:46     ` Kees Cook
2020-12-09 19:25       ` Arnd Bergmann
2020-12-03  0:44 ` [PATCH v2 6/7] ubsan: Remove UBSAN_MISC in favor of individual options Kees Cook
2020-12-03  0:44 ` [PATCH v2 7/7] ubsan: Expand tests and reporting Kees Cook

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).