diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-06-28 10:16:15 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-06-28 10:16:15 -0700 |
commit | 7ecb59a56666506ebb1197f89ca7d587bd83309e (patch) | |
tree | 81ad7f30114cd4f2ada4a5631636581f9ff7544e /tools/objtool/check.c | |
parent | a358505d8af3ab43763e1b49549619528783d2bf (diff) | |
parent | 0f1441b44e823a74f3f3780902a113e07c73fbf6 (diff) | |
download | linux-stable-7ecb59a56666506ebb1197f89ca7d587bd83309e.tar.gz linux-stable-7ecb59a56666506ebb1197f89ca7d587bd83309e.tar.bz2 linux-stable-7ecb59a56666506ebb1197f89ca7d587bd83309e.zip |
Merge tag 'objtool_urgent_for_5.8_rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull objtool fixes from Borislav Petkov:
"Three fixes from Peter Zijlstra suppressing KCOV instrumentation in
noinstr sections.
Peter Zijlstra says:
"Address KCOV vs noinstr. There is no function attribute to
selectively suppress KCOV instrumentation, instead teach objtool
to NOP out the calls in noinstr functions"
This cures a bunch of KCOV crashes (as used by syzcaller)"
* tag 'objtool_urgent_for_5.8_rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
objtool: Fix noinstr vs KCOV
objtool: Provide elf_write_{insn,reloc}()
objtool: Clean up elf_write() condition
Diffstat (limited to 'tools/objtool/check.c')
-rw-r--r-- | tools/objtool/check.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/tools/objtool/check.c b/tools/objtool/check.c index d8eaa7dc53d5..5e0d70a89fb8 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -12,6 +12,7 @@ #include "check.h" #include "special.h" #include "warn.h" +#include "arch_elf.h" #include <linux/hashtable.h> #include <linux/kernel.h> @@ -766,6 +767,24 @@ static int add_call_destinations(struct objtool_file *file) insn->call_dest = rela->sym; /* + * Many compilers cannot disable KCOV with a function attribute + * so they need a little help, NOP out any KCOV calls from noinstr + * text. + */ + if (insn->sec->noinstr && + !strncmp(insn->call_dest->name, "__sanitizer_cov_", 16)) { + if (rela) { + rela->type = R_NONE; + elf_write_rela(file->elf, rela); + } + + elf_write_insn(file->elf, insn->sec, + insn->offset, insn->len, + arch_nop_insn(insn->len)); + insn->type = INSN_NOP; + } + + /* * Whatever stack impact regular CALLs have, should be undone * by the RETURN of the called function. * @@ -2766,7 +2785,7 @@ int check(const char *_objname, bool orc) objname = _objname; - file.elf = elf_open_read(objname, orc ? O_RDWR : O_RDONLY); + file.elf = elf_open_read(objname, O_RDWR); if (!file.elf) return 1; @@ -2827,7 +2846,9 @@ int check(const char *_objname, bool orc) ret = create_orc_sections(&file); if (ret < 0) goto out; + } + if (file.elf->changed) { ret = elf_write(file.elf); if (ret < 0) goto out; |