From e0478542cfd4d993e38d5f92a3f3ecd238805e96 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Wed, 10 Apr 2019 22:27:25 +0200 Subject: [PATCH 1/4] overflow.h: Add comment documenting __ab_c_size() __ab_c_size() is a somewhat opaque name. Document its purpose, and while at it, rename the parameters to actually match the abc naming. [ bp: glued a complete patch from chunks on LKML. ] Reported-by: Borislav Petkov Signed-off-by: Rasmus Villemoes Signed-off-by: Borislav Petkov Acked-by: Kees Cook Cc: Matthew Wilcox Link: https://lkml.kernel.org/r/20190405045711.30339-1-bp@alien8.de --- include/linux/overflow.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/include/linux/overflow.h b/include/linux/overflow.h index 40b48e2133cb..6534a727cadb 100644 --- a/include/linux/overflow.h +++ b/include/linux/overflow.h @@ -278,11 +278,15 @@ static inline __must_check size_t array3_size(size_t a, size_t b, size_t c) return bytes; } -static inline __must_check size_t __ab_c_size(size_t n, size_t size, size_t c) +/* + * Compute a*b+c, returning SIZE_MAX on overflow. Internal helper for + * struct_size() below. + */ +static inline __must_check size_t __ab_c_size(size_t a, size_t b, size_t c) { size_t bytes; - if (check_mul_overflow(n, size, &bytes)) + if (check_mul_overflow(a, b, &bytes)) return SIZE_MAX; if (check_add_overflow(bytes, c, &bytes)) return SIZE_MAX; From e6da9567959e164f82bc81967e0d5b10dee870b4 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Mon, 13 May 2019 12:01:31 -0500 Subject: [PATCH 2/4] objtool: Don't use ignore flag for fake jumps The ignore flag is set on fake jumps in order to keep add_jump_destinations() from setting their jump_dest, since it already got set when the fake jump was created. But using the ignore flag is a bit of a hack. It's normally used to skip validation of an instruction, which doesn't really make sense for fake jumps. Also, after the next patch, using the ignore flag for fake jumps can trigger a false "why am I validating an ignored function?" warning. Instead just add an explicit check in add_jump_destinations() to skip fake jumps. Signed-off-by: Josh Poimboeuf Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/71abc072ff48b2feccc197723a9c52859476c068.1557766718.git.jpoimboe@redhat.com Signed-off-by: Ingo Molnar --- tools/objtool/check.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index ac743a1d53ab..90226791df6b 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -28,6 +28,8 @@ #include #include +#define FAKE_JUMP_OFFSET -1 + struct alternative { struct list_head list; struct instruction *insn; @@ -568,7 +570,7 @@ static int add_jump_destinations(struct objtool_file *file) insn->type != INSN_JUMP_UNCONDITIONAL) continue; - if (insn->ignore) + if (insn->ignore || insn->offset == FAKE_JUMP_OFFSET) continue; rela = find_rela_by_dest_range(insn->sec, insn->offset, @@ -745,10 +747,10 @@ static int handle_group_alt(struct objtool_file *file, clear_insn_state(&fake_jump->state); fake_jump->sec = special_alt->new_sec; - fake_jump->offset = -1; + fake_jump->offset = FAKE_JUMP_OFFSET; fake_jump->type = INSN_JUMP_UNCONDITIONAL; fake_jump->jump_dest = list_next_entry(last_orig_insn, list); - fake_jump->ignore = true; + fake_jump->func = orig_insn->func; } if (!special_alt->new_len) { From e6f393bc939d566ce3def71232d8013de9aaadde Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Mon, 13 May 2019 12:01:32 -0500 Subject: [PATCH 3/4] objtool: Fix function fallthrough detection When a function falls through to the next function due to a compiler bug, objtool prints some obscure warnings. For example: drivers/regulator/core.o: warning: objtool: regulator_count_voltages()+0x95: return with modified stack frame drivers/regulator/core.o: warning: objtool: regulator_count_voltages()+0x0: stack state mismatch: cfa1=7+32 cfa2=7+8 Instead it should be printing: drivers/regulator/core.o: warning: objtool: regulator_supply_is_couple() falls through to next function regulator_count_voltages() This used to work, but was broken by the following commit: 13810435b9a7 ("objtool: Support GCC 8's cold subfunctions") The padding nops at the end of a function aren't actually part of the function, as defined by the symbol table. So the 'func' variable in validate_branch() is getting cleared to NULL when a padding nop is encountered, breaking the fallthrough detection. If the current instruction doesn't have a function associated with it, just consider it to be part of the previously detected function by not overwriting the previous value of 'func'. Reported-by: kbuild test robot Signed-off-by: Josh Poimboeuf Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: Fixes: 13810435b9a7 ("objtool: Support GCC 8's cold subfunctions") Link: http://lkml.kernel.org/r/546d143820cd08a46624ae8440d093dd6c902cae.1557766718.git.jpoimboe@redhat.com Signed-off-by: Ingo Molnar --- tools/objtool/check.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 90226791df6b..7325d89ccad9 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -1959,7 +1959,8 @@ static int validate_branch(struct objtool_file *file, struct instruction *first, return 1; } - func = insn->func ? insn->func->pfunc : NULL; + if (insn->func) + func = insn->func->pfunc; if (func && insn->ignore) { WARN_FUNC("BUG: why am I validating an ignored function?", From 2decec48b0fd28ffdbf4cc684bd04e735f0839dd Mon Sep 17 00:00:00 2001 From: Raphael Gault Date: Tue, 14 May 2019 17:47:46 -0500 Subject: [PATCH 4/4] objtool: Fix whitelist documentation typo The directive specified in the documentation to add an exception for a single file in a Makefile was inverted. Signed-off-by: Raphael Gault Signed-off-by: Josh Poimboeuf Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/522362a1b934ee39d0af0abb231f68e160ecf1a8.1557874043.git.jpoimboe@redhat.com Signed-off-by: Ingo Molnar --- tools/objtool/Documentation/stack-validation.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/objtool/Documentation/stack-validation.txt b/tools/objtool/Documentation/stack-validation.txt index 3995735a878f..cd17ee022072 100644 --- a/tools/objtool/Documentation/stack-validation.txt +++ b/tools/objtool/Documentation/stack-validation.txt @@ -306,7 +306,7 @@ ignore it: - To skip validation of a file, add - OBJECT_FILES_NON_STANDARD_filename.o := n + OBJECT_FILES_NON_STANDARD_filename.o := y to the Makefile.