ubsan/overflow: Enable pattern exclusions
Subsystems (4)
Kees Cook
maintainercover ubsan/overflow: Enable pattern exclusions
Hi,
This brings Linux's integer overflow mitigation integration up to the current set of features available in Clang for handling things sanely (i.e. pattern exclusions). While this isn't over yet, it puts all the infrastructure in place to continue keeping up to date with current Clang development. The next step is to add support for the coming canonical wrapping and non-wrapping types[1].
-Kees
[1] https://discourse.llvm.org/t/rfc-clang-canonical-wrapping-and-non-wrapping-types/84356
Kees Cook (3):
ubsan/overflow: Rework integer overflow sanitizer option to turn on
everything
ubsan/overflow: Enable pattern exclusions ubsan/overflow: Enable ignorelist parsing and add type filter
include/linux/compiler_types.h | 2 +- kernel/configs/hardening.config | 2 +- lib/Kconfig.ubsan | 25 +++++++++++++------------ lib/test_ubsan.c | 18 ++++++++++++++---- lib/ubsan.c | 28 ++++++++++++++++++++++++++-- lib/ubsan.h | 8 ++++++++ scripts/Makefile.lib | 4 ++-- scripts/Makefile.ubsan | 10 ++++++++-- scripts/integer-wrap-ignore.scl | 3 +++ 9 files changed, 76 insertions(+), 24 deletions(-) create mode 100644 scripts/integer-wrap-ignore.scl
Signature · 1 line
2.34.1
Kees Cook
maintainerPATCH 1/3 ubsan/overflow: Rework integer overflow sanitizer option to turn on everything
Since we're going to approach integer overflow mitigation a type at a time, we need to enable all of the associated sanitizers, and then opt into types one at a time.
Rename the existing "signed wrap" sanitizer to just the entire topic area:
"integer wrap". Enable the implicit integer truncation sanitizers, with required callbacks and tests.
Notably, this requires features (currently) only available in Clang, so we can depend on the cc-option tests to determine availability instead of doing version tests.
---
Cc: Justin Stitt <[email protected]>
Cc: "Gustavo A. R. Silva" <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Marco Elver <[email protected]>
Cc: Andrey Konovalov <[email protected]>
Cc: Andrey Ryabinin <[email protected]>
Cc: Masahiro Yamada <[email protected]>
Cc: Nathan Chancellor <[email protected]>
Cc: Nicolas Schier <[email protected]>
Cc: Miguel Ojeda <[email protected]>
Cc: Nick Desaulniers <[email protected]>
Cc: Hao Luo <[email protected]>
Cc: Przemek Kitszel <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
--- include/linux/compiler_types.h | 2 +- kernel/configs/hardening.config | 2 +- lib/Kconfig.ubsan | 23 +++++++++++------------ lib/test_ubsan.c | 18 ++++++++++++++---- lib/ubsan.c | 28 ++++++++++++++++++++++++++-- lib/ubsan.h | 8 ++++++++ scripts/Makefile.lib | 4 ++-- scripts/Makefile.ubsan | 8 ++++++-- 8 files changed, 69 insertions(+), 24 deletions(-)
include/linux/compiler_types.h +1 -1
@@ -360,7 +360,7 @@ struct ftrace_likely_data {#endif /* Do not trap wrapping arithmetic within an annotated function. */ -#ifdef CONFIG_UBSAN_SIGNED_WRAP +#ifdef CONFIG_UBSAN_INTEGER_WRAP # define __signed_wrap __attribute__((no_sanitize("signed-integer-overflow")))#else # define __signed_wrap
kernel/configs/hardening.config +1 -1
@@ -46,7 +46,7 @@ CONFIG_UBSAN_BOUNDS=y # CONFIG_UBSAN_SHIFT is not set # CONFIG_UBSAN_DIV_ZERO is not set # CONFIG_UBSAN_UNREACHABLE is not set -# CONFIG_UBSAN_SIGNED_WRAP is not set +# CONFIG_UBSAN_INTEGER_WRAP is not set # CONFIG_UBSAN_BOOL is not set # CONFIG_UBSAN_ENUM is not set # CONFIG_UBSAN_ALIGNMENT is not set
lib/Kconfig.ubsan +11 -12
@@ -116,21 +116,20 @@ config UBSAN_UNREACHABLE This option enables -fsanitize=unreachable which checks for control flow reaching an expected-to-be-unreachable position. -config UBSAN_SIGNED_WRAP - bool "Perform checking for signed arithmetic wrap-around" +config UBSAN_INTEGER_WRAP + bool "Perform checking for integer arithmetic wrap-around" default UBSAN depends on !COMPILE_TEST - # The no_sanitize attribute was introduced in GCC with version 8. - depends on !CC_IS_GCC || GCC_VERSION >= 80000 depends on $(cc-option,-fsanitize=signed-integer-overflow) - help - This option enables -fsanitize=signed-integer-overflow which checks - for wrap-around of any arithmetic operations with signed integers. - This currently performs nearly no instrumentation due to the - kernel's use of -fno-strict-overflow which converts all would-be - arithmetic undefined behavior into wrap-around arithmetic. Future - sanitizer versions will allow for wrap-around checking (rather than - exclusively undefined behavior). + depends on $(cc-option,-fsanitize=unsigned-integer-overflow) + depends on $(cc-option,-fsanitize=implicit-signed-integer-truncation) + depends on $(cc-option,-fsanitize=implicit-unsigned-integer-truncation) + help + This option enables all of the sanitizers involved in integer overflow + (wrap-around) mitigation: signed-integer-overflow, unsigned-integer-overflow, + implicit-signed-integer-truncation, and implicit-unsigned-integer-truncation. + This is currently limited only to the size_t type while testing and + compiler development continues. config UBSAN_BOOL bool "Perform checking for non-boolean values used as boolean"
lib/test_ubsan.c +14 -4
@@ -15,7 +15,7 @@ static void test_ubsan_add_overflow(void) {volatile int val =INT_MAX ; -UBSAN_TEST (CONFIG_UBSAN_SIGNED_WRAP ); +UBSAN_TEST (CONFIG_UBSAN_INTEGER_WRAP ); val +=2 ; }
@@ -24,7 +24,7 @@ static void test_ubsan_sub_overflow(void)volatile int val =INT_MIN ;volatile int val2 =2 ; -UBSAN_TEST (CONFIG_UBSAN_SIGNED_WRAP ); +UBSAN_TEST (CONFIG_UBSAN_INTEGER_WRAP ); val -= val2; }
@@ -32,7 +32,7 @@ static void test_ubsan_mul_overflow(void) {volatile int val =INT_MAX /2 ; -UBSAN_TEST (CONFIG_UBSAN_SIGNED_WRAP ); +UBSAN_TEST (CONFIG_UBSAN_INTEGER_WRAP ); val *=3 ; }
@@ -40,7 +40,7 @@ static void test_ubsan_negate_overflow(void) {volatile int val =INT_MIN ; -UBSAN_TEST (CONFIG_UBSAN_SIGNED_WRAP ); +UBSAN_TEST (CONFIG_UBSAN_INTEGER_WRAP ); val = -val; }
@@ -53,6 +53,15 @@ static void test_ubsan_divrem_overflow(void) val /= val2; } +static void test_ubsan_truncate_signed (void ) +{ +volatile long val =LONG_MAX ; +volatile int val2 =0 ; + +UBSAN_TEST (CONFIG_UBSAN_INTEGER_WRAP ); + val2 = val; +} +static void test_ubsan_shift_out_of_bounds (void ) {volatile int neg =-1 , wrap =4 ;
@@ -127,6 +136,7 @@ static const test_ubsan_fp test_ubsan_array[] = { test_ubsan_sub_overflow, test_ubsan_mul_overflow, test_ubsan_negate_overflow, + test_ubsan_truncate_signed, test_ubsan_shift_out_of_bounds, test_ubsan_out_of_bounds, test_ubsan_load_invalid_value,
lib/ubsan.c +26 -2
@@ -44,7 +44,7 @@ const char *report_ubsan_failure(struct pt_regs *regs, u32 check_type)case ubsan_shift_out_of_bounds:return "UBSAN: shift out of bounds" ;#endif -#if defined(CONFIG_UBSAN_DIV_ZERO ) || defined(CONFIG_UBSAN_SIGNED_WRAP ) +#if defined(CONFIG_UBSAN_DIV_ZERO ) || defined(CONFIG_UBSAN_INTEGER_WRAP )/* * SanitizerKind::IntegerDivideByZero and * SanitizerKind::SignedIntegerOverflow emit
@@ -79,7 +79,7 @@ const char *report_ubsan_failure(struct pt_regs *regs, u32 check_type)case ubsan_type_mismatch:return "UBSAN: type mismatch" ;#endif -#ifdef CONFIG_UBSAN_SIGNED_WRAP +#ifdef CONFIG_UBSAN_INTEGER_WRAP /* * SanitizerKind::SignedIntegerOverflow emits * SanitizerHandler::AddOverflow, SanitizerHandler::SubOverflow,
@@ -303,6 +303,30 @@ void __ubsan_handle_negate_overflow(void *_data, void *old_val) }EXPORT_SYMBOL (__ubsan_handle_negate_overflow); +void __ubsan_handle_implicit_conversion (void *_data,void *from_val,void *to_val) +{ +struct implicit_conversion_data *data = _data; +char from_val_str[VALUE_LENGTH ]; +char to_val_str[VALUE_LENGTH ]; + +if (suppress_report (&data->location)) +return ; + +val_to_string (from_val_str,sizeof (from_val_str), data->from_type, from_val); +val_to_string (to_val_str,sizeof (to_val_str), data->to_type, to_val); + +ubsan_prologue (&data->location,"implicit-conversion" ); + +pr_err ("cannot represent %s value %s during %s %s, truncated to %s\n" , + data->from_type->type_name, + from_val_str, + type_check_kinds[data->type_check_kind], + data->to_type->type_name, + to_val_str); + +ubsan_epilogue (); +} +EXPORT_SYMBOL (__ubsan_handle_implicit_conversion);void __ubsan_handle_divrem_overflow (void *_data,void *lhs,void *rhs) {
lib/ubsan.h +8 -0
@@ -62,6 +62,13 @@ struct overflow_data {struct type_descriptor *type; }; +struct implicit_conversion_data { +struct source_location location; +struct type_descriptor *from_type; +struct type_descriptor *to_type; +unsigned char type_check_kind; +}; +struct type_mismatch_data {struct source_location location;struct type_descriptor *type;
@@ -142,6 +149,7 @@ void ubsan_linkage __ubsan_handle_sub_overflow(void *data, void *lhs, void *rhs) void ubsan_linkage __ubsan_handle_mul_overflow(void *data, void *lhs, void *rhs); void ubsan_linkage __ubsan_handle_negate_overflow(void *_data, void *old_val); void ubsan_linkage __ubsan_handle_divrem_overflow(void *_data, void *lhs, void *rhs); +void ubsan_linkage __ubsan_handle_implicit_conversion(void *_data, void *lhs, void *rhs); void ubsan_linkage __ubsan_handle_type_mismatch(struct type_mismatch_data *data, void *ptr); void ubsan_linkage __ubsan_handle_type_mismatch_v1(void *_data, void *ptr); void ubsan_linkage __ubsan_handle_out_of_bounds(void *_data, void *index);
scripts/Makefile.lib +2 -2
@@ -166,8 +166,8 @@ _c_flags += $(if $(patsubst n%,, \ $(UBSAN_SANITIZE_$(target-stem).o)$(UBSAN_SANITIZE)$(is-kernel-object)), \ $(CFLAGS_UBSAN)) _c_flags += $(if $(patsubst n%,, \ - $(UBSAN_SIGNED_WRAP_$(target-stem).o)$(UBSAN_SANITIZE_$(target-stem).o)$(UBSAN_SIGNED_WRAP)$(UBSAN_SANITIZE)$(is-kernel-object)), \ - $(CFLAGS_UBSAN_SIGNED_WRAP)) + $(UBSAN_INTEGER_WRAP_$(target-stem).o)$(UBSAN_SANITIZE_$(target-stem).o)$(UBSAN_INTEGER_WRAP)$(UBSAN_SANITIZE)$(is-kernel-object)), \ + $(CFLAGS_UBSAN_INTEGER_WRAP)) endif ifeq ($(CONFIG_KCOV),y)
scripts/Makefile.ubsan +6 -2
@@ -14,5 +14,9 @@ ubsan-cflags-$(CONFIG_UBSAN_TRAP) += $(call cc-option,-fsanitize-trap=undefined export CFLAGS_UBSAN := $(ubsan-cflags-y) -ubsan-signed-wrap-cflags-$(CONFIG_UBSAN_SIGNED_WRAP) += -fsanitize=signed-integer-overflow -export CFLAGS_UBSAN_SIGNED_WRAP := $(ubsan-signed-wrap-cflags-y) +ubsan-integer-wrap-cflags-$(CONFIG_UBSAN_INTEGER_WRAP) += \ + -fsanitize=signed-integer-overflow \ + -fsanitize=unsigned-integer-overflow \ + -fsanitize=implicit-signed-integer-truncation \ + -fsanitize=implicit-unsigned-integer-truncation +export CFLAGS_UBSAN_INTEGER_WRAP := $(ubsan-integer-wrap-cflags-y)
Signature · 1 line
2.34.1
kernel test robot
build botRe: [PATCH 1/3] ubsan/overflow: Rework integer overflow sanitizer option to turn on everything
kernel test robot noticed the following build warnings:
Hi Kees,
kernel test robot noticed the following build warnings:
[auto build test WARNING on kees/for-next/hardening]
[also build test WARNING on masahiroy-kbuild/for-next masahiroy-kbuild/fixes kees/for-next/pstore linus/master v6.14-rc6 next-20250307] [cannot apply to kees/for-next/kspp]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Kees-Cook/ubsan-overflow-Rework-integer-overflow-sanitizer-option-to-turn-on-everything/20250307-122130 base: https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening patch link: https://lore.kernel.org/r/20250307041914.937329-1-kees%40kernel.org patch subject: [PATCH 1/3] ubsan/overflow: Rework integer overflow sanitizer option to turn on everything config: s390-randconfig-r112-20250310 (https://download.01.org/0day-ci/archive/20250310/[email protected]/config) compiler: s390-linux-gcc (GCC) 14.2.0 reproduce: (https://download.01.org/0day-ci/archive/20250310/[email protected]/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
sparse warnings: (new ones prefixed by >>)
>> lib/test_ubsan.c:62:16: sparse: sparse: cast truncates bits from constant value (7fffffffffffffff becomes ffffffff)
lib/test_ubsan.c:72:18: sparse: sparse: shift count is negative (-1)
vim +62 lib/test_ubsan.c
55
56 static void test_ubsan_truncate_signed(void)
57 {
58 volatile long val = LONG_MAX;
59 volatile int val2 = 0;
60
61 UBSAN_TEST(CONFIG_UBSAN_INTEGER_WRAP);
> 62 val2 = val;
63 }
64 Signature · 2 lines
0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
Kees Cook
maintainerRe: [PATCH 1/3] ubsan/overflow: Rework integer overflow sanitizer option to turn on everything
Quoted 19 lines · kernel test robot
Hi Kees,
kernel test robot noticed the following build warnings:
[auto build test WARNING on kees/for-next/hardening]
[also build test WARNING on masahiroy-kbuild/for-next masahiroy-kbuild/fixes kees/for-next/pstore linus/master v6.14-rc6 next-20250307] [cannot apply to kees/for-next/kspp]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]url: https://github.com/intel-lab-lkp/linux/commits/Kees-Cook/ubsan-overflow-Rework-integer-overflow-sanitizer-option-to-turn-on-everything/20250307-122130 base: https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening patch link: https://lore.kernel.org/r/20250307041914.937329-1-kees%40kernel.org patch subject: [PATCH 1/3] ubsan/overflow: Rework integer overflow sanitizer option to turn on everything config: s390-randconfig-r112-20250310 (https://download.01.org/0day-ci/archive/20250310/[email protected]/config) compiler: s390-linux-gcc (GCC) 14.2.0 reproduce: (https://download.01.org/0day-ci/archive/20250310/[email protected]/reproduce)
Quoted 8 lines
If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/sparse warnings: (new ones prefixed by >>)
Quoted 1 line
Quoted 1 line
lib/test_ubsan.c:62:16: sparse: sparse: cast truncates bits from constant value (7fffffffffffffffbecomes ffffffff)
lib/test_ubsan.c:72:18: sparse: sparse: shift count is negative (-1)
Can we exclude certain source files from sparse? This whole file is basically an endless series of intentionally bad operations. :)
-Kees
Quoted 17 lines
vim +62
lib/test_ubsan.c55 56 static void test_ubsan_truncate_signed(void) 57 { 58 volatile long val = LONG_MAX; 59 volatile int val2 = 0; 60 61 UBSAN_TEST(CONFIG_UBSAN_INTEGER_WRAP);Quoted 1 line
62 val2 = val;
63 } 64Signature · 2 lines
0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
Signature · 1 line
Kees Cook
Re: [PATCH 1/3] ubsan/overflow: Rework integer overflow sanitizer option to turn on everything
Quoted 25 lines · Kees Cook
Quoted 24 lines · kernel test robot
Hi Kees,
kernel test robot noticed the following build warnings:
[auto build test WARNING on kees/for-next/hardening]
[also build test WARNING on masahiroy-kbuild/for-next masahiroy-kbuild/fixes kees/for-next/pstore linus/master v6.14-rc6 next-20250307] [cannot apply to kees/for-next/kspp]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]url: https://github.com/intel-lab-lkp/linux/commits/Kees-Cook/ubsan-overflow-Rework-integer-overflow-sanitizer-option-to-turn-on-everything/20250307-122130 base: https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening patch link: https://lore.kernel.org/r/20250307041914.937329-1-kees%40kernel.org patch subject: [PATCH 1/3] ubsan/overflow: Rework integer overflow sanitizer option to turn on everything config: s390-randconfig-r112-20250310 (https://download.01.org/0day-ci/archive/20250310/[email protected]/config) compiler: s390-linux-gcc (GCC) 14.2.0 reproduce: (https://download.01.org/0day-ci/archive/20250310/[email protected]/reproduce)If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
Quoted 6 lines
Quoted 3 lines
sparse warnings: (new ones prefixed by >>)
Quoted 1 line
Quoted 1 line
lib/test_ubsan.c:62:16: sparse: sparse: cast truncates bits from constant value (7fffffffffffffffbecomes ffffffff)
lib/test_ubsan.c:72:18: sparse: sparse: shift count is negative (-1)Can we exclude certain source files from sparse? This whole file is basically an endless series of intentionally bad operations. :)
Thanks Kees, got it, I will update the bot to handle this to exclude this file firstly from sparse.
Quoted 24 lines
-Kees
Quoted 17 lines
vim +62
lib/test_ubsan.c55 56 static void test_ubsan_truncate_signed(void) 57 { 58 volatile long val = LONG_MAX; 59 volatile int val2 = 0; 60 61 UBSAN_TEST(CONFIG_UBSAN_INTEGER_WRAP);Quoted 1 line
62 val2 = val;
63 } 64Signature · 2 lines
0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wikiSignature · 1 line
Kees Cook
Marco Elver
reviewerRe: [PATCH 1/3] ubsan/overflow: Rework integer overflow sanitizer option to turn on everything
In reply to Kees CookQuoted 86 lines · Kees Cook
Since we're going to approach integer overflow mitigation a type at a time, we need to enable all of the associated sanitizers, and then opt into types one at a time.
Rename the existing "signed wrap" sanitizer to just the entire topic area:
"integer wrap". Enable the implicit integer truncation sanitizers, with required callbacks and tests.Notably, this requires features (currently) only available in Clang, so we can depend on the cc-option tests to determine availability instead of doing version tests.
Signed-off-by Kees Cook <[email protected]>---
Cc: Justin Stitt <[email protected]>
Cc: "Gustavo A. R. Silva" <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Marco Elver <[email protected]>
Cc: Andrey Konovalov <[email protected]>
Cc: Andrey Ryabinin <[email protected]>
Cc: Masahiro Yamada <[email protected]>
Cc: Nathan Chancellor <[email protected]>
Cc: Nicolas Schier <[email protected]>
Cc: Miguel Ojeda <[email protected]>
Cc: Nick Desaulniers <[email protected]>
Cc: Hao Luo <[email protected]>
Cc: Przemek Kitszel <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]--- include/linux/compiler_types.h | 2 +- kernel/configs/hardening.config | 2 +- lib/Kconfig.ubsan | 23 +++++++++++------------ lib/test_ubsan.c | 18 ++++++++++++++---- lib/ubsan.c | 28 ++++++++++++++++++++++++++-- lib/ubsan.h | 8 ++++++++ scripts/Makefile.lib | 4 ++-- scripts/Makefile.ubsan | 8 ++++++-- 8 files changed, 69 insertions(+), 24 deletions(-)include/linux/compiler_types.h +1
-1@@ -360,7 +360,7 @@ struct ftrace_likely_data {#endif /* Do not trap wrapping arithmetic within an annotated function. */ -#ifdef CONFIG_UBSAN_SIGNED_WRAP +#ifdef CONFIG_UBSAN_INTEGER_WRAP # define __signed_wrap __attribute__((no_sanitize("signed-integer-overflow")))#else # define __signed_wrapkernel/configs/hardening.config +1
-1@@ -46,7 +46,7 @@ CONFIG_UBSAN_BOUNDS=y # CONFIG_UBSAN_SHIFT is not set # CONFIG_UBSAN_DIV_ZERO is not set # CONFIG_UBSAN_UNREACHABLE is not set -# CONFIG_UBSAN_SIGNED_WRAP is not set +# CONFIG_UBSAN_INTEGER_WRAP is not set # CONFIG_UBSAN_BOOL is not set # CONFIG_UBSAN_ENUM is not set # CONFIG_UBSAN_ALIGNMENT is not setlib/Kconfig.ubsan +2
-5@@ -116,21 +116,20 @@ config UBSAN_UNREACHABLE This option enables -fsanitize=unreachable which checks for control flow reaching an expected-to-be-unreachable position. -config UBSAN_SIGNED_WRAP - bool "Perform checking for signed arithmetic wrap-around" +config UBSAN_INTEGER_WRAP + bool "Perform checking for integer arithmetic wrap-around" default UBSAN depends on !COMPILE_TEST - # The no_sanitize attribute was introduced in GCC with version 8. - depends on !CC_IS_GCC || GCC_VERSION >= 80000 depends on $(cc-option,-fsanitize=signed-integer-overflow) - help
lib/Kconfig.ubsan config UBSAN_UNREACHABLE · line 126
Quoted 10 lines
lib/Kconfig.ubsan +3
-7- This option enables -fsanitize=signed-integer-overflow which checks - for wrap-around of any arithmetic operations with signed integers. - This currently performs nearly no instrumentation due to the - kernel's use of -fno-strict-overflow which converts all would-be - arithmetic undefined behavior into wrap-around arithmetic. Future - sanitizer versions will allow for wrap-around checking (rather than - exclusively undefined behavior). + depends on $(cc-option,-fsanitize=unsigned-integer-overflow) + depends on $(cc-option,-fsanitize=implicit-signed-integer-truncation) + depends on $(cc-option,-fsanitize=implicit-unsigned-integer-truncation)
Can these be in 1 cc-option? I know it might look slightly more ugly, but having 3 different ones will shell out to the compiler 3 times, which is a little less efficient. At some point it might noticeably increase the build initialization latency.
Kees Cook
maintainerRe: [PATCH 1/3] ubsan/overflow: Rework integer overflow sanitizer option to turn on everything
Quoted 94 lines · Marco Elver
Quoted 93 lines · Kees Cook
Since we're going to approach integer overflow mitigation a type at a time, we need to enable all of the associated sanitizers, and then opt into types one at a time.
Rename the existing "signed wrap" sanitizer to just the entire topic area:
"integer wrap". Enable the implicit integer truncation sanitizers, with required callbacks and tests.Notably, this requires features (currently) only available in Clang, so we can depend on the cc-option tests to determine availability instead of doing version tests.
Signed-off-by Kees Cook <[email protected]>---
Cc: Justin Stitt <[email protected]>
Cc: "Gustavo A. R. Silva" <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Marco Elver <[email protected]>
Cc: Andrey Konovalov <[email protected]>
Cc: Andrey Ryabinin <[email protected]>
Cc: Masahiro Yamada <[email protected]>
Cc: Nathan Chancellor <[email protected]>
Cc: Nicolas Schier <[email protected]>
Cc: Miguel Ojeda <[email protected]>
Cc: Nick Desaulniers <[email protected]>
Cc: Hao Luo <[email protected]>
Cc: Przemek Kitszel <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]--- include/linux/compiler_types.h | 2 +- kernel/configs/hardening.config | 2 +- lib/Kconfig.ubsan | 23 +++++++++++------------ lib/test_ubsan.c | 18 ++++++++++++++---- lib/ubsan.c | 28 ++++++++++++++++++++++++++-- lib/ubsan.h | 8 ++++++++ scripts/Makefile.lib | 4 ++-- scripts/Makefile.ubsan | 8 ++++++-- 8 files changed, 69 insertions(+), 24 deletions(-)include/linux/compiler_types.h +1
-1@@ -360,7 +360,7 @@ struct ftrace_likely_data {#endif /* Do not trap wrapping arithmetic within an annotated function. */ -#ifdef CONFIG_UBSAN_SIGNED_WRAP +#ifdef CONFIG_UBSAN_INTEGER_WRAP # define __signed_wrap __attribute__((no_sanitize("signed-integer-overflow")))#else # define __signed_wrapkernel/configs/hardening.config +1
-1@@ -46,7 +46,7 @@ CONFIG_UBSAN_BOUNDS=y # CONFIG_UBSAN_SHIFT is not set # CONFIG_UBSAN_DIV_ZERO is not set # CONFIG_UBSAN_UNREACHABLE is not set -# CONFIG_UBSAN_SIGNED_WRAP is not set +# CONFIG_UBSAN_INTEGER_WRAP is not set # CONFIG_UBSAN_BOOL is not set # CONFIG_UBSAN_ENUM is not set # CONFIG_UBSAN_ALIGNMENT is not setlib/Kconfig.ubsan +2
-12@@ -116,21 +116,20 @@ config UBSAN_UNREACHABLE This option enables -fsanitize=unreachable which checks for control flow reaching an expected-to-be-unreachable position. -config UBSAN_SIGNED_WRAP - bool "Perform checking for signed arithmetic wrap-around" +config UBSAN_INTEGER_WRAP + bool "Perform checking for integer arithmetic wrap-around" default UBSAN depends on !COMPILE_TEST - # The no_sanitize attribute was introduced in GCC with version 8. - depends on !CC_IS_GCC || GCC_VERSION >= 80000 depends on $(cc-option,-fsanitize=signed-integer-overflow) - help - This option enables -fsanitize=signed-integer-overflow which checks - for wrap-around of any arithmetic operations with signed integers. - This currently performs nearly no instrumentation due to the - kernel's use of -fno-strict-overflow which converts all would-be - arithmetic undefined behavior into wrap-around arithmetic. Future - sanitizer versions will allow for wrap-around checking (rather than - exclusively undefined behavior).
Quoted 8 lines
lib/Kconfig.ubsan config UBSAN_UNREACHABLE · line 126
Quoted 3 lines
lib/Kconfig.ubsan +3
-0+ depends on $(cc-option,-fsanitize=unsigned-integer-overflow) + depends on $(cc-option,-fsanitize=implicit-signed-integer-truncation) + depends on $(cc-option,-fsanitize=implicit-unsigned-integer-truncation)Can these be in 1 cc-option? I know it might look slightly more ugly, but having 3 different ones will shell out to the compiler 3 times, which is a little less efficient. At some point it might noticeably increase the build initialization latency.
Yeah, good point. I could probably just test the most recently added option, as it implies all the rest, too. I'll send an update!
-Kees
Signature · 1 line
Kees Cook
Kees Cook
maintainerPATCH 2/3 ubsan/overflow: Enable pattern exclusions
In reply to Kees CookTo make integer wrap-around mitigation actually useful, the associated sanitizers must not instrument cases where the wrap-around is explicitly defined (e.g. "-2UL"), being tested for (e.g. "if (a + b < a)"), or where it has no impact on code flow (e.g. "while (var--)"). Enable pattern exclusions for the integer wrap sanitizers.
---
Cc: Justin Stitt <[email protected]>
Cc: "Gustavo A. R. Silva" <[email protected]>
Cc: Masahiro Yamada <[email protected]>
Cc: Nathan Chancellor <[email protected]>
Cc: Nicolas Schier <[email protected]>
Cc: Marco Elver <[email protected]>
Cc: Andrey Konovalov <[email protected]>
Cc: Andrey Ryabinin <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
--- lib/Kconfig.ubsan | 1 + scripts/Makefile.ubsan | 1 + 2 files changed, 2 insertions(+)
lib/Kconfig.ubsan +1 -0
@@ -120,6 +120,7 @@ config UBSAN_INTEGER_WRAP bool "Perform checking for integer arithmetic wrap-around" default UBSAN depends on !COMPILE_TEST + depends on $(cc-option,-fsanitize-undefined-ignore-overflow-pattern=all) depends on $(cc-option,-fsanitize=signed-integer-overflow) depends on $(cc-option,-fsanitize=unsigned-integer-overflow) depends on $(cc-option,-fsanitize=implicit-signed-integer-truncation)
scripts/Makefile.ubsan +1 -0
@@ -15,6 +15,7 @@ ubsan-cflags-$(CONFIG_UBSAN_TRAP) += $(call cc-option,-fsanitize-trap=undefined export CFLAGS_UBSAN := $(ubsan-cflags-y) ubsan-integer-wrap-cflags-$(CONFIG_UBSAN_INTEGER_WRAP) += \ + -fsanitize-undefined-ignore-overflow-pattern=all \ -fsanitize=signed-integer-overflow \ -fsanitize=unsigned-integer-overflow \ -fsanitize=implicit-signed-integer-truncation \
Signature · 1 line
2.34.1
Hi,
Quoted 29 lines · Kees Cook
To make integer wrap-around mitigation actually useful, the associated sanitizers must not instrument cases where the wrap-around is explicitly defined (e.g. "-2UL"), being tested for (e.g. "if (a + b < a)"), or where it has no impact on code flow (e.g. "while (var--)"). Enable pattern exclusions for the integer wrap sanitizers.
Signed-off-by Kees Cook <[email protected]>---
Cc: Justin Stitt <[email protected]>
Cc: "Gustavo A. R. Silva" <[email protected]>
Cc: Masahiro Yamada <[email protected]>
Cc: Nathan Chancellor <[email protected]>
Cc: Nicolas Schier <[email protected]>
Cc: Marco Elver <[email protected]>
Cc: Andrey Konovalov <[email protected]>
Cc: Andrey Ryabinin <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]--- lib/Kconfig.ubsan | 1 + scripts/Makefile.ubsan | 1 + 2 files changed, 2 insertions(+)lib/Kconfig.ubsan +0
-0
lib/Kconfig.ubsan config UBSAN_INTEGER_WRAP · line 123
Quoted 4 lines
lib/Kconfig.ubsan +1
-0@@ -120,6 +120,7 @@ config UBSAN_INTEGER_WRAP bool "Perform checking for integer arithmetic wrap-around" default UBSAN depends on !COMPILE_TEST + depends on $(cc-option,-fsanitize-undefined-ignore-overflow-pattern=all)
This option group "all" may be expanded in the future, e.g., negations of unsigned integers (not just unsigned integer literals). As these are deliberately designed for the kernel, I think we will want them anyways. So, all is good.
Quoted 18 lines
lib/Kconfig.ubsan +0
-0depends on $(cc-option,-fsanitize=signed-integer-overflow) depends on $(cc-option,-fsanitize=unsigned-integer-overflow) depends on $(cc-option,-fsanitize=implicit-signed-integer-truncation)scripts/Makefile.ubsan +1
-0@@ -15,6 +15,7 @@ ubsan-cflags-$(CONFIG_UBSAN_TRAP) += $(call cc-option,-fsanitize-trap=undefined export CFLAGS_UBSAN := $(ubsan-cflags-y) ubsan-integer-wrap-cflags-$(CONFIG_UBSAN_INTEGER_WRAP) += \ + -fsanitize-undefined-ignore-overflow-pattern=all \ -fsanitize=signed-integer-overflow \ -fsanitize=unsigned-integer-overflow \ -fsanitize=implicit-signed-integer-truncation \Signature · 1 line
2.34.1
Justin
Kees Cook
maintainerPATCH 3/3 ubsan/overflow: Enable ignorelist parsing and add type filter
In reply to Kees CookLimit integer wrap-around mitigation to only the "size_t" type (for now). Notably this covers all special functions/builtins that return "size_t", like sizeof(). This remains an experimental feature and is likely to be replaced with type annotations.
---
Cc: Justin Stitt <[email protected]>
Cc: "Gustavo A. R. Silva" <[email protected]>
Cc: Marco Elver <[email protected]>
Cc: Andrey Konovalov <[email protected]>
Cc: Andrey Ryabinin <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Masahiro Yamada <[email protected]>
Cc: Nathan Chancellor <[email protected]>
Cc: Nicolas Schier <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
--- lib/Kconfig.ubsan | 1 + scripts/Makefile.ubsan | 3 ++- scripts/integer-wrap-ignore.scl | 3 +++ 3 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 scripts/integer-wrap-ignore.scl
lib/Kconfig.ubsan +1 -0
@@ -125,6 +125,7 @@ config UBSAN_INTEGER_WRAP depends on $(cc-option,-fsanitize=unsigned-integer-overflow) depends on $(cc-option,-fsanitize=implicit-signed-integer-truncation) depends on $(cc-option,-fsanitize=implicit-unsigned-integer-truncation) + depends on $(cc-option,-fsanitize-ignorelist=/dev/null) help This option enables all of the sanitizers involved in integer overflow (wrap-around) mitigation: signed-integer-overflow, unsigned-integer-overflow,
scripts/Makefile.ubsan +2 -1
@@ -19,5 +19,6 @@ ubsan-integer-wrap-cflags-$(CONFIG_UBSAN_INTEGER_WRAP) += \ -fsanitize=signed-integer-overflow \ -fsanitize=unsigned-integer-overflow \ -fsanitize=implicit-signed-integer-truncation \ - -fsanitize=implicit-unsigned-integer-truncation + -fsanitize=implicit-unsigned-integer-truncation \ + -fsanitize-ignorelist=$(srctree)/scripts/integer-wrap-ignore.scl export CFLAGS_UBSAN_INTEGER_WRAP := $(ubsan-integer-wrap-cflags-y)
scripts/integer-wrap-ignore.scl new file +3 -0
@@ -0,0 +1,3 @@ +[{unsigned-integer-overflow,signed-integer-overflow,implicit-signed-integer-truncation,implicit-unsigned-integer-truncation}] +type:* +type:size_t=sanitize
Signature · 1 line
2.34.1
Re: [PATCH 3/3] ubsan/overflow: Enable ignorelist parsing and add type filter
Hi,
Quoted 4 lines · Kees Cook
Limit integer wrap-around mitigation to only the "
size_t" type (for now). Notably this covers all special functions/builtins that return "size_t", likesizeof(). This remains an experimental feature and is likely to be replaced with type annotations.
For future travelers, track the progress of type annotations over at [1]. There's still discussion on how these will be implemented in Clang.
Quoted 52 lines
Signed-off-by Kees Cook <[email protected]>---
Cc: Justin Stitt <[email protected]>
Cc: "Gustavo A. R. Silva" <[email protected]>
Cc: Marco Elver <[email protected]>
Cc: Andrey Konovalov <[email protected]>
Cc: Andrey Ryabinin <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Masahiro Yamada <[email protected]>
Cc: Nathan Chancellor <[email protected]>
Cc: Nicolas Schier <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]--- lib/Kconfig.ubsan | 1 + scripts/Makefile.ubsan | 3 ++- scripts/integer-wrap-ignore.scl | 3 +++ 3 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 scripts/integer-wrap-ignore.scllib/Kconfig.ubsan +1
-0@@ -125,6 +125,7 @@ config UBSAN_INTEGER_WRAP depends on $(cc-option,-fsanitize=unsigned-integer-overflow) depends on $(cc-option,-fsanitize=implicit-signed-integer-truncation) depends on $(cc-option,-fsanitize=implicit-unsigned-integer-truncation) + depends on $(cc-option,-fsanitize-ignorelist=/dev/null) help This option enables all of the sanitizers involved in integer overflow (wrap-around) mitigation: signed-integer-overflow, unsigned-integer-overflow,scripts/Makefile.ubsan +2
-1@@ -19,5 +19,6 @@ ubsan-integer-wrap-cflags-$(CONFIG_UBSAN_INTEGER_WRAP) += \ -fsanitize=signed-integer-overflow \ -fsanitize=unsigned-integer-overflow \ -fsanitize=implicit-signed-integer-truncation \ - -fsanitize=implicit-unsigned-integer-truncation + -fsanitize=implicit-unsigned-integer-truncation \ + -fsanitize-ignorelist=$(srctree)/scripts/integer-wrap-ignore.scl export CFLAGS_UBSAN_INTEGER_WRAP := $(ubsan-integer-wrap-cflags-y)scripts/integer-wrap-ignore.scl new file +0
-0
scripts/integer-wrap-ignore.scl line 3
Quoted 3 lines
scripts/integer-wrap-ignore.scl new file +3
-0@@ -0,0 +1,3 @@ +[{unsigned-integer-overflow,signed-integer-overflow,implicit-signed-integer-truncation,implicit-unsigned-integer-truncation}] +type:* +type:size_t=sanitize
Hi again future travelers, sanitizer special case list support for overflow/truncation sanitizers as well as the "=sanitize" comes from a new Clang 20 feature allowing SCL's to specify sanitize categories, see [2].
Quoted 4 lines
Signature · 1 line
2.34.1
The plumbing looks correct,
[1]: https://discourse.llvm.org/t/rfc-clang-canonical-wrapping-and-non-wrapping-types/84356
[2]: https://github.com/llvm/llvm-project/pull/107332
Thanks
Justin
Re: [PATCH 3/3] ubsan/overflow: Enable ignorelist parsing and add type filter
In reply to Kees CookQuoted 56 lines · Kees Cook
Limit integer wrap-around mitigation to only the "
size_t" type (for now). Notably this covers all special functions/builtins that return "size_t", likesizeof(). This remains an experimental feature and is likely to be replaced with type annotations.Signed-off-by Kees Cook <[email protected]>---
Cc: Justin Stitt <[email protected]>
Cc: "Gustavo A. R. Silva" <[email protected]>
Cc: Marco Elver <[email protected]>
Cc: Andrey Konovalov <[email protected]>
Cc: Andrey Ryabinin <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Masahiro Yamada <[email protected]>
Cc: Nathan Chancellor <[email protected]>
Cc: Nicolas Schier <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]--- lib/Kconfig.ubsan | 1 + scripts/Makefile.ubsan | 3 ++- scripts/integer-wrap-ignore.scl | 3 +++ 3 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 scripts/integer-wrap-ignore.scllib/Kconfig.ubsan +1
-0@@ -125,6 +125,7 @@ config UBSAN_INTEGER_WRAP depends on $(cc-option,-fsanitize=unsigned-integer-overflow) depends on $(cc-option,-fsanitize=implicit-signed-integer-truncation) depends on $(cc-option,-fsanitize=implicit-unsigned-integer-truncation) + depends on $(cc-option,-fsanitize-ignorelist=/dev/null) help This option enables all of the sanitizers involved in integer overflow (wrap-around) mitigation: signed-integer-overflow, unsigned-integer-overflow,scripts/Makefile.ubsan +2
-1@@ -19,5 +19,6 @@ ubsan-integer-wrap-cflags-$(CONFIG_UBSAN_INTEGER_WRAP) += \ -fsanitize=signed-integer-overflow \ -fsanitize=unsigned-integer-overflow \ -fsanitize=implicit-signed-integer-truncation \ - -fsanitize=implicit-unsigned-integer-truncation + -fsanitize=implicit-unsigned-integer-truncation \ + -fsanitize-ignorelist=$(srctree)/scripts/integer-wrap-ignore.scl export CFLAGS_UBSAN_INTEGER_WRAP := $(ubsan-integer-wrap-cflags-y)scripts/integer-wrap-ignore.scl new file +0
-0
scripts/integer-wrap-ignore.scl line 3
Quoted 3 lines
scripts/integer-wrap-ignore.scl new file +3
-0@@ -0,0 +1,3 @@ +[{unsigned-integer-overflow,signed-integer-overflow,implicit-signed-integer-truncation,implicit-unsigned-integer-truncation}] +type:* +type:size_t=sanitize
Forgot to mention this in my intial reply but we have to be careful with what types are added here. Kees, I know we're on the same page from offline chats but for others: using sanitizer case lists to discriminate against types for the purposes of sanitizer instrumentation may not work properly through various arithmetic conversions. Mainly, implicit promotions which tend to break this particular approach.
Now, for size_t we got kind of "lucky" because there are no implicit promotions with size_t, it doesn't get promoted. This is not the case for other types. This further necessitates the need for canonical wrapping types backed by in-source annotations/qualification -- coming soon in Clang.
Quoted 3 lines
Signature · 1 line
2.34.1
Justin