01 May, 2020

2 commits

  • Change objtool to support intra-function calls. On x86, an intra-function
    call is represented in objtool as a push onto the stack (of the return
    address), and a jump to the destination address. That way the stack
    information is correctly updated and the call flow is still accurate.

    Signed-off-by: Alexandre Chartre
    Signed-off-by: Peter Zijlstra (Intel)
    Reviewed-by: Miroslav Benes
    Acked-by: Josh Poimboeuf
    Link: https://lkml.kernel.org/r/20200414103618.12657-4-alexandre.chartre@oracle.com

    Alexandre Chartre
     
  • Jann reported that (for instance) entry_64.o:general_protection has
    very odd ORC data:

    0000000000000f40 :
    #######sp:sp+8 bp:(und) type:iret end:0
    f40: 90 nop
    #######sp:(und) bp:(und) type:call end:0
    f41: 90 nop
    f42: 90 nop
    #######sp:sp+8 bp:(und) type:iret end:0
    f43: e8 a8 01 00 00 callq 10f0
    #######sp:sp+0 bp:(und) type:regs end:0
    f48: f6 84 24 88 00 00 00 testb $0x3,0x88(%rsp)
    f4f: 03
    f50: 74 00 je f52
    f52: 48 89 e7 mov %rsp,%rdi
    f55: 48 8b 74 24 78 mov 0x78(%rsp),%rsi
    f5a: 48 c7 44 24 78 ff ff movq $0xffffffffffffffff,0x78(%rsp)
    f61: ff ff
    f63: e8 00 00 00 00 callq f68
    f68: e9 73 02 00 00 jmpq 11e0
    #######sp:(und) bp:(und) type:call end:0
    f6d: 0f 1f 00 nopl (%rax)

    Note the entry at 0xf41. Josh found this was the result of commit:

    764eef4b109a ("objtool: Rewrite alt->skip_orig")

    Due to the early return in validate_branch() we no longer set
    insn->cfi of the original instruction stream (the NOPs at 0xf41 and
    0xf42) and we'll end up with the above weirdness.

    In other discussions we realized alternatives should be ORC invariant;
    that is, due to there being only a single ORC table, it must be valid
    for all alternatives. The easiest way to ensure this is to not allow
    any stack modifications in alternatives.

    When we enforce this latter observation, we get the property that the
    whole alternative must have the same CFI, which we can employ to fix
    the former report.

    Fixes: 764eef4b109a ("objtool: Rewrite alt->skip_orig")
    Reported-by: Jann Horn
    Signed-off-by: Peter Zijlstra (Intel)
    Reviewed-by: Miroslav Benes
    Acked-by: Josh Poimboeuf
    Link: https://lkml.kernel.org/r/20200428191659.499074346@infradead.org

    Peter Zijlstra
     

22 Apr, 2020

1 commit

  • Compiling with Clang and CONFIG_KASAN=y was exposing a few warnings:

    call to memset() with UACCESS enabled

    Document how to fix these for future travelers.

    Link: https://github.com/ClangBuiltLinux/linux/issues/876
    Suggested-by: Kamalesh Babulal
    Suggested-by: Matt Helsley
    Suggested-by: Peter Zijlstra
    Suggested-by: Randy Dunlap
    Signed-off-by: Nick Desaulniers
    Signed-off-by: Josh Poimboeuf
    Signed-off-by: Ingo Molnar

    Nick Desaulniers
     

09 Jun, 2019

1 commit

  • Mostly due to x86 and acpi conversion, several documentation
    links are still pointing to the old file. Fix them.

    Signed-off-by: Mauro Carvalho Chehab
    Reviewed-by: Wolfram Sang
    Reviewed-by: Sven Van Asbroeck
    Reviewed-by: Bhupesh Sharma
    Acked-by: Mark Brown
    Signed-off-by: Jonathan Corbet

    Mauro Carvalho Chehab
     

17 May, 2019

1 commit


15 May, 2019

1 commit

  • 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

    Raphael Gault
     

08 May, 2019

1 commit

  • Convert livepatch documentation to ReST format. The changes
    are mostly trivial, as the documents are already on a good
    shape. Just a few markup changes are needed for Sphinx to
    properly parse the docs.

    The conversion is actually:
    - add blank lines and identation in order to identify paragraphs;
    - fix tables markups;
    - add some lists markups;
    - mark literal blocks;
    - The in-file TOC becomes a comment, in order to skip it from the
    output, as Sphinx already generates an index there.
    - adjust title markups.

    At its new index.rst, let's add a :orphan: while this is not linked to
    the main index.rst file, in order to avoid build warnings.

    Signed-off-by: Mauro Carvalho Chehab
    Signed-off-by: Petr Mladek
    Acked-by: Miroslav Benes
    Acked-by: Josh Poimboeuf
    Acked-by: Joe Lawrence
    Reviewed-by: Kamalesh Babulal
    Signed-off-by: Jonathan Corbet

    Mauro Carvalho Chehab
     

23 Sep, 2017

1 commit

  • For inline asm statements which have a CALL instruction, we list the
    stack pointer as a constraint to convince GCC to ensure the frame
    pointer is set up first:

    static inline void foo()
    {
    register void *__sp asm(_ASM_SP);
    asm("call bar" : "+r" (__sp))
    }

    Unfortunately, that pattern causes Clang to corrupt the stack pointer.

    The fix is easy: convert the stack pointer register variable to a global
    variable.

    It should be noted that the end result is different based on the GCC
    version. With GCC 6.4, this patch has exactly the same result as
    before:

    defconfig defconfig-nofp distro distro-nofp
    before 9820389 9491555 8816046 8516940
    after 9820389 9491555 8816046 8516940

    With GCC 7.2, however, GCC's behavior has changed. It now changes its
    behavior based on the conversion of the register variable to a global.
    That somehow convinces it to *always* set up the frame pointer before
    inserting *any* inline asm. (Therefore, listing the variable as an
    output constraint is a no-op and is no longer necessary.) It's a bit
    overkill, but the performance impact should be negligible. And in fact,
    there's a nice improvement with frame pointers disabled:

    defconfig defconfig-nofp distro distro-nofp
    before 9796316 9468236 9076191 8790305
    after 9796957 9464267 9076381 8785949

    So in summary, while listing the stack pointer as an output constraint
    is no longer necessary for newer versions of GCC, it's still needed for
    older versions.

    Suggested-by: Andrey Ryabinin
    Reported-by: Matthias Kaehlcke
    Signed-off-by: Josh Poimboeuf
    Cc: Alexander Potapenko
    Cc: Andy Lutomirski
    Cc: Arnd Bergmann
    Cc: Dmitriy Vyukov
    Cc: Linus Torvalds
    Cc: Miguel Bernal Marin
    Cc: Peter Zijlstra
    Cc: Thomas Gleixner
    Link: http://lkml.kernel.org/r/3db862e970c432ae823cf515c52b54fec8270e0e.1505942196.git.jpoimboe@redhat.com
    Signed-off-by: Ingo Molnar

    Josh Poimboeuf
     

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
     

16 Apr, 2016

1 commit

  • There are several cases in compiled C code where a function may not
    return at the end, and may instead fall through to the next function.

    That may indicate a bug in the code, or a gcc bug, or even an objtool
    bug. But in each case, objtool reports an unhelpful warning, something
    like:

    drivers/scsi/qla2xxx/qla_attr.o: warning: objtool: qla2x00_get_fc_host_stats()+0x0: duplicate frame pointer save
    drivers/scsi/qla2xxx/qla_attr.o: warning: objtool: qla2x00_get_fc_host_stats()+0x0: frame pointer state mismatch

    Detect this situation and print a more useful error message:

    drivers/scsi/qla2xxx/qla_attr.o: warning: objtool: qla2x00_get_host_fabric_name() falls through to next function qla2x00_get_starget_node_name()

    Also add some information about this warning and its potential causes to
    the documentation.

    Reported-by: kbuild test robot
    Signed-off-by: Josh Poimboeuf
    Cc: Alexander Shishkin
    Cc: Andy Lutomirski
    Cc: Arnaldo Carvalho de Melo
    Cc: Borislav Petkov
    Cc: Brian Gerst
    Cc: Denys Vlasenko
    Cc: H. Peter Anvin
    Cc: Jiri Olsa
    Cc: Linus Torvalds
    Cc: Peter Zijlstra
    Cc: Thomas Gleixner
    Link: http://lkml.kernel.org/r/caa4ec6c687931db805e692d4e4bf06cd87d33e6.1460729697.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