17 Dec, 2018

2 commits

  • [ Upstream commit 22566c1603030f0a036ad564634b064ad1a55db2 ]

    Because find_symbol_by_name() traverses the same lists as
    read_symbols(), changing sym->name in place without copying it affects
    the result of find_symbol_by_name(). In the case where a ".cold"
    function precedes its parent in sec->symbol_list, it can result in a
    function being considered a parent of itself. This leads to function
    length being set to 0 and other consequent side-effects including a
    segfault in add_switch_table(). The effects of this bug are only
    visible when building with -ffunction-sections in KCFLAGS.

    Fix by copying the search string instead of modifying it in place.

    Signed-off-by: Artem Savkov
    Signed-off-by: Josh Poimboeuf
    Cc: Linus Torvalds
    Cc: Peter Zijlstra
    Cc: Thomas Gleixner
    Fixes: 13810435b9a7 ("objtool: Support GCC 8's cold subfunctions")
    Link: http://lkml.kernel.org/r/910abd6b5a4945130fd44f787c24e07b9e07c8da.1542736240.git.jpoimboe@redhat.com
    Signed-off-by: Ingo Molnar
    Signed-off-by: Sasha Levin

    Artem Savkov
     
  • [ Upstream commit 0b9301fb632f7111a3293a30cc5b20f1b82ed08d ]

    If read_symbols() fails during second list traversal (the one dealing
    with ".cold" subfunctions) it frees the symbol, but never deletes it
    from the list/hash_table resulting in symbol being freed again in
    elf_close(). Fix it by just returning an error, leaving cleanup to
    elf_close().

    Signed-off-by: Artem Savkov
    Signed-off-by: Josh Poimboeuf
    Cc: Linus Torvalds
    Cc: Peter Zijlstra
    Cc: Thomas Gleixner
    Fixes: 13810435b9a7 ("objtool: Support GCC 8's cold subfunctions")
    Link: http://lkml.kernel.org/r/beac5a9b7da9e8be90223459dcbe07766ae437dd.1542736240.git.jpoimboe@redhat.com
    Signed-off-by: Ingo Molnar
    Signed-off-by: Sasha Levin

    Artem Savkov
     

24 Aug, 2018

1 commit

  • [ Upstream commit 08b393d01c88aff27347ed2b1b354eb4db2f1532 ]

    Since the following commit:

    cd77849a69cf ("objtool: Fix GCC 8 cold subfunction detection for aliased functions")

    ... if the kernel is built with EXTRA_CFLAGS='-fno-reorder-functions',
    objtool can get stuck in an infinite loop.

    That flag causes the new GCC 8 cold subfunctions to be placed in .text
    instead of .text.unlikely. But it also has an unfortunate quirk: in the
    symbol table, the subfunction (e.g., nmi_panic.cold.7) is nested inside
    the parent (nmi_panic).

    That function overlap confuses objtool, and causes it to get into an
    infinite loop in next_insn_same_func(). Here's Allan's description of
    the loop:

    "Objtool iterates through the instructions in nmi_panic using
    next_insn_same_func. Once it reaches the end of nmi_panic at 0x534 it
    jumps to 0x528 as that's the start of nmi_panic.cold.7. However, since
    the instructions starting at 0x528 are still associated with nmi_panic
    objtool will get stuck in a loop, continually jumping back to 0x528
    after reaching 0x534."

    Fix it by shortening the length of the parent function so that the
    functions no longer overlap.

    Reported-and-analyzed-by: Allan Xavier
    Signed-off-by: Josh Poimboeuf
    Cc: Allan Xavier
    Cc: Andy Lutomirski
    Cc: Borislav Petkov
    Cc: Brian Gerst
    Cc: Denys Vlasenko
    Cc: H. Peter Anvin
    Cc: Linus Torvalds
    Cc: Peter Zijlstra
    Cc: Thomas Gleixner
    Link: http://lkml.kernel.org/r/9e704c52bee651129b036be14feda317ae5606ae.1530136978.git.jpoimboe@redhat.com
    Signed-off-by: Ingo Molnar
    Signed-off-by: Sasha Levin
    Signed-off-by: Greg Kroah-Hartman

    Josh Poimboeuf
     

05 Jun, 2018

1 commit

  • commit 13810435b9a7014fb92eb715f77da488f3b65b99 upstream.

    GCC 8 moves a lot of unlikely code out of line to "cold" subfunctions in
    .text.unlikely. Properly detect the new subfunctions and treat them as
    extensions of the original functions.

    This fixes a bunch of warnings like:

    kernel/cgroup/cgroup.o: warning: objtool: parse_cgroup_root_flags()+0x33: sibling call from callable instruction with modified stack frame
    kernel/cgroup/cgroup.o: warning: objtool: cgroup_addrm_files()+0x290: sibling call from callable instruction with modified stack frame
    kernel/cgroup/cgroup.o: warning: objtool: cgroup_apply_control_enable()+0x25b: sibling call from callable instruction with modified stack frame
    kernel/cgroup/cgroup.o: warning: objtool: rebind_subsystems()+0x325: sibling call from callable instruction with modified stack frame

    Reported-and-tested-by: damian
    Reported-by: Arnd Bergmann
    Signed-off-by: Josh Poimboeuf
    Acked-by: Peter Zijlstra (Intel)
    Cc: David Laight
    Cc: Greg KH
    Cc: Linus Torvalds
    Cc: Peter Zijlstra
    Cc: Randy Dunlap
    Cc: Thomas Gleixner
    Link: http://lkml.kernel.org/r/0965e7fcfc5f31a276f0c7f298ff770c19b68706.1525923412.git.jpoimboe@redhat.com
    Signed-off-by: Ingo Molnar
    Signed-off-by: Greg Kroah-Hartman

    Josh Poimboeuf
     

24 Jan, 2018

1 commit

  • commit 385d11b152c4eb638eeb769edcb3249533bb9a00 upstream.

    If a nonexistent file is supplied to objtool, it complains with a
    non-helpful error:

    open: No such file or directory

    Improve it to:

    objtool: Can't open 'foo': No such file or directory

    Reported-by: Markus
    Signed-off-by: Josh Poimboeuf
    Cc: Linus Torvalds
    Cc: Peter Zijlstra
    Cc: Thomas Gleixner
    Link: http://lkml.kernel.org/r/406a3d00a21225eee2819844048e17f68523ccf6.1516025651.git.jpoimboe@redhat.com
    Signed-off-by: Ingo Molnar
    Signed-off-by: Greg Kroah-Hartman

    Josh Poimboeuf
     

15 Sep, 2017

3 commits

  • Arnd Bergmann reported that a randconfig build was failing with the
    following link error:

    built-in.o: member arch/x86/kernel/time.o in archive is not an object

    It turns out the link failed because the time.o file had been corrupted
    by objtool:

    nm: arch/x86/kernel/time.o: File format not recognized

    In certain rare cases, when a .o file's ORC table is very small, the
    .data section size doesn't change because it's page aligned. Because
    all the existing sections haven't changed size, libelf doesn't detect
    any section header changes, and so it doesn't update the section header
    table properly. Instead it writes junk in the section header entries
    for the new ORC sections.

    Make sure libelf properly updates the section header table by setting
    the ELF_F_DIRTY flag in the top level elf struct.

    Reported-by: Arnd Bergmann
    Signed-off-by: Josh Poimboeuf
    Cc: Linus Torvalds
    Cc: Peter Zijlstra
    Cc: Thomas Gleixner
    Fixes: 627fce14809b ("objtool: Add ORC unwind table generation")
    Link: http://lkml.kernel.org/r/e650fd0f2d8a209d1409a9785deb101fdaed55fb.1505459813.git.jpoimboe@redhat.com
    Signed-off-by: Ingo Molnar

    Josh Poimboeuf
     
  • Binutils 2.29-9 in Debian return an error when elf_getdata is invoked
    on empty section (.note.GNU-stack in all kernel files), causing
    immediate failure of kernel build with:

    elf_getdata: can't manipulate null section

    As nothing is done with sections that have zero size, just do not
    retrieve their data at all.

    Signed-off-by: Petr Vandrovec
    Signed-off-by: Josh Poimboeuf
    Cc: Linus Torvalds
    Cc: Peter Zijlstra
    Cc: Thomas Gleixner
    Link: http://lkml.kernel.org/r/2ce30a44349065b70d0f00e71e286dc0cbe745e6.1505459652.git.jpoimboe@redhat.com
    Signed-off-by: Ingo Molnar

    Petr Vandrovec
     
  • Let's free the allocated char array 'relaname' before returning,
    in order to avoid leaking memory.

    Signed-off-by: Martin Kepplinger
    Acked-by: Josh Poimboeuf
    Cc: Linus Torvalds
    Cc: Peter Zijlstra
    Cc: Thomas Gleixner
    Cc: mingo.kernel.org@gmail.com
    Link: http://lkml.kernel.org/r/20170914060138.26472-1-martink@posteo.de
    Signed-off-by: Ingo Molnar

    Martin Kepplinger
     

18 Jul, 2017

1 commit

  • Now that objtool knows the states of all registers on the stack for each
    instruction, it's straightforward to generate debuginfo for an unwinder
    to use.

    Instead of generating DWARF, generate a new format called ORC, which is
    more suitable for an in-kernel unwinder. See
    Documentation/x86/orc-unwinder.txt for a more detailed description of
    this new debuginfo format and why it's preferable to DWARF.

    Signed-off-by: Josh Poimboeuf
    Cc: Andy Lutomirski
    Cc: Borislav Petkov
    Cc: Brian Gerst
    Cc: Denys Vlasenko
    Cc: H. Peter Anvin
    Cc: Jiri Slaby
    Cc: Linus Torvalds
    Cc: Mike Galbraith
    Cc: Peter Zijlstra
    Cc: Thomas Gleixner
    Cc: live-patching@vger.kernel.org
    Link: http://lkml.kernel.org/r/c9b9f01ba6c5ed2bdc9bb0957b78167fdbf9632e.1499786555.git.jpoimboe@redhat.com
    Signed-off-by: Ingo Molnar

    Josh Poimboeuf
     

30 Jun, 2017

1 commit

  • This is a major rewrite of objtool. Instead of only tracking frame
    pointer changes, it now tracks all stack-related operations, including
    all register saves/restores.

    In addition to making stack validation more robust, this also paves the
    way for undwarf generation.

    Signed-off-by: Josh Poimboeuf
    Cc: Andy Lutomirski
    Cc: Jiri Slaby
    Cc: Linus Torvalds
    Cc: Peter Zijlstra
    Cc: Thomas Gleixner
    Cc: live-patching@vger.kernel.org
    Link: http://lkml.kernel.org/r/678bd94c0566c6129bcc376cddb259c4c5633004.1498659915.git.jpoimboe@redhat.com
    Signed-off-by: Ingo Molnar

    Josh Poimboeuf
     

07 Mar, 2017

1 commit

  • Arnd Bergmann reported a (false positive) objtool warning:

    drivers/infiniband/sw/rxe/rxe_resp.o: warning: objtool: rxe_responder()+0xfe: sibling call from callable instruction with changed frame pointer

    The issue is in find_switch_table(). It tries to find a switch
    statement's jump table by walking backwards from an indirect jump
    instruction, looking for a relocation to the .rodata section. In this
    case it stopped walking prematurely: the first .rodata relocation it
    encountered was for a variable (resp_state_name) instead of a jump
    table, so it just assumed there wasn't a jump table.

    The fix is to ignore any .rodata relocation which refers to an ELF
    object symbol. This works because the jump tables are anonymous and
    have no symbols associated with them.

    Reported-by: Arnd Bergmann
    Tested-by: Arnd Bergmann
    Signed-off-by: Josh Poimboeuf
    Cc: Denys Vlasenko
    Cc: Linus Torvalds
    Cc: Peter Zijlstra
    Cc: Thomas Gleixner
    Fixes: 3732710ff6f2 ("objtool: Improve rare switch jump table pattern detection")
    Link: http://lkml.kernel.org/r/20170302225723.3ndbsnl4hkqbne7a@treble
    Signed-off-by: Ingo Molnar

    Josh Poimboeuf
     

14 Jul, 2016

1 commit

  • Not all libelf implementations have this "Please, ELF_C_READ, but use
    mmap if possible" elf_begin() cmd, so provide a fallback to plain old
    ELF_C_READ.

    Case in point: Alpine Linux 3.4.

    Cc: Adrian Hunter
    Cc: David Ahern
    Cc: Jiri Olsa
    Cc: Josh Poimboeuf
    Cc: Namhyung Kim
    Cc: Wang Nan
    Link: http://lkml.kernel.org/n/tip-1fctuknrawgoi5xqon4mu9dv@git.kernel.org
    Signed-off-by: Arnaldo Carvalho de Melo

    Arnaldo Carvalho de Melo
     

09 Mar, 2016

2 commits

  • Use hash tables for instruction and rela lookups (and keep the linked
    lists around for sequential access).

    Also cache the section struct for the "__func_stack_frame_non_standard"
    section.

    With this change, "objtool check net/wireless/nl80211.o" goes from:

    real 0m1.168s
    user 0m1.163s
    sys 0m0.005s

    to:

    real 0m0.059s
    user 0m0.042s
    sys 0m0.017s

    for a 20x speedup.

    With the same object, it should be noted that the memory heap usage grew
    from 8MB to 62MB. Reducing the memory usage is on the TODO list.

    Reported-by: Ingo Molnar
    Signed-off-by: Josh Poimboeuf
    Cc: Andrew Morton
    Cc: Andy Lutomirski
    Cc: Arnaldo Carvalho de Melo
    Cc: Arnaldo Carvalho de Melo
    Cc: Bernd Petrovitsch
    Cc: Borislav Petkov
    Cc: Chris J Arges
    Cc: Jiri Slaby
    Cc: Linus Torvalds
    Cc: Michal Marek
    Cc: Namhyung Kim
    Cc: Pedro Alves
    Cc: Peter Zijlstra
    Cc: Thomas Gleixner
    Cc: live-patching@vger.kernel.org
    Link: http://lkml.kernel.org/r/dd0d8e1449506cfa7701b4e7ba73577077c44253.1457502970.git.jpoimboe@redhat.com
    Signed-off-by: Ingo Molnar

    Josh Poimboeuf
     
  • Rename some list heads to distinguish them from hash node heads, which
    are added later in the patch series.

    Also rename the get_*() functions to add_*(), which is more descriptive:
    they "add" data to the objtool_file struct.

    Also rename rodata_rela and text_rela to be clearer:
    - text_rela refers to a rela entry in .rela.text.
    - rodata_rela refers to a rela entry in .rela.rodata.

    Signed-off-by: Josh Poimboeuf
    Cc: Andrew Morton
    Cc: Andy Lutomirski
    Cc: Arnaldo Carvalho de Melo
    Cc: Arnaldo Carvalho de Melo
    Cc: Bernd Petrovitsch
    Cc: Borislav Petkov
    Cc: Chris J Arges
    Cc: Jiri Slaby
    Cc: Linus Torvalds
    Cc: Michal Marek
    Cc: Namhyung Kim
    Cc: Pedro Alves
    Cc: Peter Zijlstra
    Cc: Thomas Gleixner
    Cc: live-patching@vger.kernel.org
    Link: http://lkml.kernel.org/r/ee0eca2bba8482aa45758958c5586c00a7b71e62.1457502970.git.jpoimboe@redhat.com
    Signed-off-by: Ingo Molnar

    Josh Poimboeuf
     

29 Feb, 2016

1 commit

  • This adds a host tool named objtool which has a "check" subcommand which
    analyzes .o files to ensure the validity of stack metadata. It enforces
    a set of rules on asm code and C inline assembly code so that stack
    traces can be reliable.

    For each function, it recursively follows all possible code paths and
    validates the correct frame pointer state at each instruction.

    It also follows code paths involving kernel special sections, like
    .altinstructions, __jump_table, and __ex_table, which can add
    alternative execution paths to a given instruction (or set of
    instructions). Similarly, it knows how to follow switch statements, for
    which gcc sometimes uses jump tables.

    Here are some of the benefits of validating stack metadata:

    a) More reliable stack traces for frame pointer enabled kernels

    Frame pointers are used for debugging purposes. They allow runtime
    code and debug tools to be able to walk the stack to determine the
    chain of function call sites that led to the currently executing
    code.

    For some architectures, frame pointers are enabled by
    CONFIG_FRAME_POINTER. For some other architectures they may be
    required by the ABI (sometimes referred to as "backchain pointers").

    For C code, gcc automatically generates instructions for setting up
    frame pointers when the -fno-omit-frame-pointer option is used.

    But for asm code, the frame setup instructions have to be written by
    hand, which most people don't do. So the end result is that
    CONFIG_FRAME_POINTER is honored for C code but not for most asm code.

    For stack traces based on frame pointers to be reliable, all
    functions which call other functions must first create a stack frame
    and update the frame pointer. If a first function doesn't properly
    create a stack frame before calling a second function, the *caller*
    of the first function will be skipped on the stack trace.

    For example, consider the following example backtrace with frame
    pointers enabled:

    [] dump_stack+0x4b/0x63
    [] cmdline_proc_show+0x12/0x30
    [] seq_read+0x108/0x3e0
    [] proc_reg_read+0x42/0x70
    [] __vfs_read+0x37/0x100
    [] vfs_read+0x86/0x130
    [] SyS_read+0x58/0xd0
    [] entry_SYSCALL_64_fastpath+0x12/0x76

    It correctly shows that the caller of cmdline_proc_show() is
    seq_read().

    If we remove the frame pointer logic from cmdline_proc_show() by
    replacing the frame pointer related instructions with nops, here's
    what it looks like instead:

    [] dump_stack+0x4b/0x63
    [] cmdline_proc_show+0x12/0x30
    [] proc_reg_read+0x42/0x70
    [] __vfs_read+0x37/0x100
    [] vfs_read+0x86/0x130
    [] SyS_read+0x58/0xd0
    [] entry_SYSCALL_64_fastpath+0x12/0x76

    Notice that cmdline_proc_show()'s caller, seq_read(), has been
    skipped. Instead the stack trace seems to show that
    cmdline_proc_show() was called by proc_reg_read().

    The benefit of "objtool check" here is that because it ensures that
    *all* functions honor CONFIG_FRAME_POINTER, no functions will ever[*]
    be skipped on a stack trace.

    [*] unless an interrupt or exception has occurred at the very
    beginning of a function before the stack frame has been created,
    or at the very end of the function after the stack frame has been
    destroyed. This is an inherent limitation of frame pointers.

    b) 100% reliable stack traces for DWARF enabled kernels

    This is not yet implemented. For more details about what is planned,
    see tools/objtool/Documentation/stack-validation.txt.

    c) Higher live patching compatibility rate

    This is not yet implemented. For more details about what is planned,
    see tools/objtool/Documentation/stack-validation.txt.

    To achieve the validation, "objtool check" enforces the following rules:

    1. Each callable function must be annotated as such with the ELF
    function type. In asm code, this is typically done using the
    ENTRY/ENDPROC macros. If objtool finds a return instruction
    outside of a function, it flags an error since that usually indicates
    callable code which should be annotated accordingly.

    This rule is needed so that objtool can properly identify each
    callable function in order to analyze its stack metadata.

    2. Conversely, each section of code which is *not* callable should *not*
    be annotated as an ELF function. The ENDPROC macro shouldn't be used
    in this case.

    This rule is needed so that objtool can ignore non-callable code.
    Such code doesn't have to follow any of the other rules.

    3. Each callable function which calls another function must have the
    correct frame pointer logic, if required by CONFIG_FRAME_POINTER or
    the architecture's back chain rules. This can by done in asm code
    with the FRAME_BEGIN/FRAME_END macros.

    This rule ensures that frame pointer based stack traces will work as
    designed. If function A doesn't create a stack frame before calling
    function B, the _caller_ of function A will be skipped on the stack
    trace.

    4. Dynamic jumps and jumps to undefined symbols are only allowed if:

    a) the jump is part of a switch statement; or

    b) the jump matches sibling call semantics and the frame pointer has
    the same value it had on function entry.

    This rule is needed so that objtool can reliably analyze all of a
    function's code paths. If a function jumps to code in another file,
    and it's not a sibling call, objtool has no way to follow the jump
    because it only analyzes a single file at a time.

    5. A callable function may not execute kernel entry/exit instructions.
    The only code which needs such instructions is kernel entry code,
    which shouldn't be be in callable functions anyway.

    This rule is just a sanity check to ensure that callable functions
    return normally.

    It currently only supports x86_64. I tried to make the code generic so
    that support for other architectures can hopefully be plugged in
    relatively easily.

    On my Lenovo laptop with a i7-4810MQ 4-core/8-thread CPU, building the
    kernel with objtool checking every .o file adds about three seconds of
    total build time. It hasn't been optimized for performance yet, so
    there are probably some opportunities for better build performance.

    Signed-off-by: Josh Poimboeuf
    Cc: Andrew Morton
    Cc: Andy Lutomirski
    Cc: Arnaldo Carvalho de Melo
    Cc: Bernd Petrovitsch
    Cc: Borislav Petkov
    Cc: Chris J Arges
    Cc: Jiri Slaby
    Cc: Linus Torvalds
    Cc: Michal Marek
    Cc: Namhyung Kim
    Cc: Pedro Alves
    Cc: Peter Zijlstra
    Cc: Thomas Gleixner
    Cc: live-patching@vger.kernel.org
    Link: http://lkml.kernel.org/r/f3efb173de43bd067b060de73f856567c0fa1174.1456719558.git.jpoimboe@redhat.com
    Signed-off-by: Ingo Molnar

    Josh Poimboeuf