cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

objtool.txt (17804B)


      1Objtool
      2=======
      3
      4The kernel CONFIG_OBJTOOL option enables a host tool named 'objtool'
      5which runs at compile time.  It can do various validations and
      6transformations on .o files.
      7
      8Objtool has become an integral part of the x86-64 kernel toolchain.  The
      9kernel depends on it for a variety of security and performance features
     10(and other types of features as well).
     11
     12
     13Features
     14--------
     15
     16Objtool has the following features:
     17
     18- Stack unwinding metadata validation -- useful for helping to ensure
     19  stack traces are reliable for live patching
     20
     21- ORC unwinder metadata generation -- a faster and more precise
     22  alternative to frame pointer based unwinding
     23
     24- Retpoline validation -- ensures that all indirect calls go through
     25  retpoline thunks, for Spectre v2 mitigations
     26
     27- Retpoline call site annotation -- annotates all retpoline thunk call
     28  sites, enabling the kernel to patch them inline, to prevent "thunk
     29  funneling" for both security and performance reasons
     30
     31- Non-instrumentation validation -- validates non-instrumentable
     32  ("noinstr") code rules, preventing instrumentation in low-level C
     33  entry code
     34
     35- Static call annotation -- annotates static call sites, enabling the
     36  kernel to implement inline static calls, a faster alternative to some
     37  indirect branches
     38
     39- Uaccess validation -- validates uaccess rules for a proper
     40  implementation of Supervisor Mode Access Protection (SMAP)
     41
     42- Straight Line Speculation validation -- validates certain SLS
     43  mitigations
     44
     45- Indirect Branch Tracking validation -- validates Intel CET IBT rules
     46  to ensure that all functions referenced by function pointers have
     47  corresponding ENDBR instructions
     48
     49- Indirect Branch Tracking annotation -- annotates unused ENDBR
     50  instruction sites, enabling the kernel to "seal" them (replace them
     51  with NOPs) to further harden IBT
     52
     53- Function entry annotation -- annotates function entries, enabling
     54  kernel function tracing
     55
     56- Other toolchain hacks which will go unmentioned at this time...
     57
     58Each feature can be enabled individually or in combination using the
     59objtool cmdline.
     60
     61
     62Objects
     63-------
     64
     65Typically, objtool runs on every translation unit (TU, aka ".o file") in
     66the kernel.  If a TU is part of a kernel module, the '--module' option
     67is added.
     68
     69However:
     70
     71- If noinstr validation is enabled, it also runs on vmlinux.o, with all
     72  options removed and '--noinstr' added.
     73
     74- If IBT or LTO is enabled, it doesn't run on TUs at all.  Instead it
     75  runs on vmlinux.o and linked modules, with all options.
     76
     77In summary:
     78
     79  A) Legacy mode:
     80             TU: objtool [--module] <options>
     81        vmlinux: N/A
     82         module: N/A
     83
     84  B) CONFIG_NOINSTR_VALIDATION=y && !(CONFIG_X86_KERNEL_IBT=y || CONFIG_LTO=y):
     85             TU: objtool [--module] <options>	// no --noinstr
     86        vmlinux: objtool --noinstr		// other options removed
     87         module: N/A
     88
     89  C) CONFIG_X86_KERNEL_IBT=y || CONFIG_LTO=y:
     90             TU: N/A
     91        vmlinux: objtool --noinstr <options>
     92         module: objtool --module --noinstr <options>
     93
     94
     95Stack validation
     96----------------
     97
     98Objtool's stack validation feature analyzes every .o file and ensures
     99the validity of its stack metadata.  It enforces a set of rules on asm
    100code and C inline assembly code so that stack traces can be reliable.
    101
    102For each function, it recursively follows all possible code paths and
    103validates the correct frame pointer state at each instruction.
    104
    105It also follows code paths involving special sections, like
    106.altinstructions, __jump_table, and __ex_table, which can add
    107alternative execution paths to a given instruction (or set of
    108instructions).  Similarly, it knows how to follow switch statements, for
    109which gcc sometimes uses jump tables.
    110
    111Here are some of the benefits of validating stack metadata:
    112
    113a) More reliable stack traces for frame pointer enabled kernels
    114
    115   Frame pointers are used for debugging purposes.  They allow runtime
    116   code and debug tools to be able to walk the stack to determine the
    117   chain of function call sites that led to the currently executing
    118   code.
    119
    120   For some architectures, frame pointers are enabled by
    121   CONFIG_FRAME_POINTER.  For some other architectures they may be
    122   required by the ABI (sometimes referred to as "backchain pointers").
    123
    124   For C code, gcc automatically generates instructions for setting up
    125   frame pointers when the -fno-omit-frame-pointer option is used.
    126
    127   But for asm code, the frame setup instructions have to be written by
    128   hand, which most people don't do.  So the end result is that
    129   CONFIG_FRAME_POINTER is honored for C code but not for most asm code.
    130
    131   For stack traces based on frame pointers to be reliable, all
    132   functions which call other functions must first create a stack frame
    133   and update the frame pointer.  If a first function doesn't properly
    134   create a stack frame before calling a second function, the *caller*
    135   of the first function will be skipped on the stack trace.
    136
    137   For example, consider the following example backtrace with frame
    138   pointers enabled:
    139
    140     [<ffffffff81812584>] dump_stack+0x4b/0x63
    141     [<ffffffff812d6dc2>] cmdline_proc_show+0x12/0x30
    142     [<ffffffff8127f568>] seq_read+0x108/0x3e0
    143     [<ffffffff812cce62>] proc_reg_read+0x42/0x70
    144     [<ffffffff81256197>] __vfs_read+0x37/0x100
    145     [<ffffffff81256b16>] vfs_read+0x86/0x130
    146     [<ffffffff81257898>] SyS_read+0x58/0xd0
    147     [<ffffffff8181c1f2>] entry_SYSCALL_64_fastpath+0x12/0x76
    148
    149   It correctly shows that the caller of cmdline_proc_show() is
    150   seq_read().
    151
    152   If we remove the frame pointer logic from cmdline_proc_show() by
    153   replacing the frame pointer related instructions with nops, here's
    154   what it looks like instead:
    155
    156     [<ffffffff81812584>] dump_stack+0x4b/0x63
    157     [<ffffffff812d6dc2>] cmdline_proc_show+0x12/0x30
    158     [<ffffffff812cce62>] proc_reg_read+0x42/0x70
    159     [<ffffffff81256197>] __vfs_read+0x37/0x100
    160     [<ffffffff81256b16>] vfs_read+0x86/0x130
    161     [<ffffffff81257898>] SyS_read+0x58/0xd0
    162     [<ffffffff8181c1f2>] entry_SYSCALL_64_fastpath+0x12/0x76
    163
    164   Notice that cmdline_proc_show()'s caller, seq_read(), has been
    165   skipped.  Instead the stack trace seems to show that
    166   cmdline_proc_show() was called by proc_reg_read().
    167
    168   The benefit of objtool here is that because it ensures that *all*
    169   functions honor CONFIG_FRAME_POINTER, no functions will ever[*] be
    170   skipped on a stack trace.
    171
    172   [*] unless an interrupt or exception has occurred at the very
    173       beginning of a function before the stack frame has been created,
    174       or at the very end of the function after the stack frame has been
    175       destroyed.  This is an inherent limitation of frame pointers.
    176
    177b) ORC (Oops Rewind Capability) unwind table generation
    178
    179   An alternative to frame pointers and DWARF, ORC unwind data can be
    180   used to walk the stack.  Unlike frame pointers, ORC data is out of
    181   band.  So it doesn't affect runtime performance and it can be
    182   reliable even when interrupts or exceptions are involved.
    183
    184   For more details, see Documentation/x86/orc-unwinder.rst.
    185
    186c) Higher live patching compatibility rate
    187
    188   Livepatch has an optional "consistency model", which is needed for
    189   more complex patches.  In order for the consistency model to work,
    190   stack traces need to be reliable (or an unreliable condition needs to
    191   be detectable).  Objtool makes that possible.
    192
    193   For more details, see the livepatch documentation in the Linux kernel
    194   source tree at Documentation/livepatch/livepatch.rst.
    195
    196To achieve the validation, objtool enforces the following rules:
    197
    1981. Each callable function must be annotated as such with the ELF
    199   function type.  In asm code, this is typically done using the
    200   ENTRY/ENDPROC macros.  If objtool finds a return instruction
    201   outside of a function, it flags an error since that usually indicates
    202   callable code which should be annotated accordingly.
    203
    204   This rule is needed so that objtool can properly identify each
    205   callable function in order to analyze its stack metadata.
    206
    2072. Conversely, each section of code which is *not* callable should *not*
    208   be annotated as an ELF function.  The ENDPROC macro shouldn't be used
    209   in this case.
    210
    211   This rule is needed so that objtool can ignore non-callable code.
    212   Such code doesn't have to follow any of the other rules.
    213
    2143. Each callable function which calls another function must have the
    215   correct frame pointer logic, if required by CONFIG_FRAME_POINTER or
    216   the architecture's back chain rules.  This can by done in asm code
    217   with the FRAME_BEGIN/FRAME_END macros.
    218
    219   This rule ensures that frame pointer based stack traces will work as
    220   designed.  If function A doesn't create a stack frame before calling
    221   function B, the _caller_ of function A will be skipped on the stack
    222   trace.
    223
    2244. Dynamic jumps and jumps to undefined symbols are only allowed if:
    225
    226   a) the jump is part of a switch statement; or
    227
    228   b) the jump matches sibling call semantics and the frame pointer has
    229      the same value it had on function entry.
    230
    231   This rule is needed so that objtool can reliably analyze all of a
    232   function's code paths.  If a function jumps to code in another file,
    233   and it's not a sibling call, objtool has no way to follow the jump
    234   because it only analyzes a single file at a time.
    235
    2365. A callable function may not execute kernel entry/exit instructions.
    237   The only code which needs such instructions is kernel entry code,
    238   which shouldn't be be in callable functions anyway.
    239
    240   This rule is just a sanity check to ensure that callable functions
    241   return normally.
    242
    243
    244Objtool warnings
    245----------------
    246
    247For asm files, if you're getting an error which doesn't make sense,
    248first make sure that the affected code follows the above rules.
    249
    250For C files, the common culprits are inline asm statements and calls to
    251"noreturn" functions.  See below for more details.
    252
    253Another possible cause for errors in C code is if the Makefile removes
    254-fno-omit-frame-pointer or adds -fomit-frame-pointer to the gcc options.
    255
    256Here are some examples of common warnings reported by objtool, what
    257they mean, and suggestions for how to fix them.  When in doubt, ping
    258the objtool maintainers.
    259
    260
    2611. file.o: warning: objtool: func()+0x128: call without frame pointer save/setup
    262
    263   The func() function made a function call without first saving and/or
    264   updating the frame pointer, and CONFIG_FRAME_POINTER is enabled.
    265
    266   If the error is for an asm file, and func() is indeed a callable
    267   function, add proper frame pointer logic using the FRAME_BEGIN and
    268   FRAME_END macros.  Otherwise, if it's not a callable function, remove
    269   its ELF function annotation by changing ENDPROC to END, and instead
    270   use the manual unwind hint macros in asm/unwind_hints.h.
    271
    272   If it's a GCC-compiled .c file, the error may be because the function
    273   uses an inline asm() statement which has a "call" instruction.  An
    274   asm() statement with a call instruction must declare the use of the
    275   stack pointer in its output operand.  On x86_64, this means adding
    276   the ASM_CALL_CONSTRAINT as an output constraint:
    277
    278     asm volatile("call func" : ASM_CALL_CONSTRAINT);
    279
    280   Otherwise the stack frame may not get created before the call.
    281
    282
    2832. file.o: warning: objtool: .text+0x53: unreachable instruction
    284
    285   Objtool couldn't find a code path to reach the instruction.
    286
    287   If the error is for an asm file, and the instruction is inside (or
    288   reachable from) a callable function, the function should be annotated
    289   with the ENTRY/ENDPROC macros (ENDPROC is the important one).
    290   Otherwise, the code should probably be annotated with the unwind hint
    291   macros in asm/unwind_hints.h so objtool and the unwinder can know the
    292   stack state associated with the code.
    293
    294   If you're 100% sure the code won't affect stack traces, or if you're
    295   a just a bad person, you can tell objtool to ignore it.  See the
    296   "Adding exceptions" section below.
    297
    298   If it's not actually in a callable function (e.g. kernel entry code),
    299   change ENDPROC to END.
    300
    301
    3024. file.o: warning: objtool: func(): can't find starting instruction
    303   or
    304   file.o: warning: objtool: func()+0x11dd: can't decode instruction
    305
    306   Does the file have data in a text section?  If so, that can confuse
    307   objtool's instruction decoder.  Move the data to a more appropriate
    308   section like .data or .rodata.
    309
    310
    3115. file.o: warning: objtool: func()+0x6: unsupported instruction in callable function
    312
    313   This is a kernel entry/exit instruction like sysenter or iret.  Such
    314   instructions aren't allowed in a callable function, and are most
    315   likely part of the kernel entry code.  They should usually not have
    316   the callable function annotation (ENDPROC) and should always be
    317   annotated with the unwind hint macros in asm/unwind_hints.h.
    318
    319
    3206. file.o: warning: objtool: func()+0x26: sibling call from callable instruction with modified stack frame
    321
    322   This is a dynamic jump or a jump to an undefined symbol.  Objtool
    323   assumed it's a sibling call and detected that the frame pointer
    324   wasn't first restored to its original state.
    325
    326   If it's not really a sibling call, you may need to move the
    327   destination code to the local file.
    328
    329   If the instruction is not actually in a callable function (e.g.
    330   kernel entry code), change ENDPROC to END and annotate manually with
    331   the unwind hint macros in asm/unwind_hints.h.
    332
    333
    3347. file: warning: objtool: func()+0x5c: stack state mismatch
    335
    336   The instruction's frame pointer state is inconsistent, depending on
    337   which execution path was taken to reach the instruction.
    338
    339   Make sure that, when CONFIG_FRAME_POINTER is enabled, the function
    340   pushes and sets up the frame pointer (for x86_64, this means rbp) at
    341   the beginning of the function and pops it at the end of the function.
    342   Also make sure that no other code in the function touches the frame
    343   pointer.
    344
    345   Another possibility is that the code has some asm or inline asm which
    346   does some unusual things to the stack or the frame pointer.  In such
    347   cases it's probably appropriate to use the unwind hint macros in
    348   asm/unwind_hints.h.
    349
    350
    3518. file.o: warning: objtool: funcA() falls through to next function funcB()
    352
    353   This means that funcA() doesn't end with a return instruction or an
    354   unconditional jump, and that objtool has determined that the function
    355   can fall through into the next function.  There could be different
    356   reasons for this:
    357
    358   1) funcA()'s last instruction is a call to a "noreturn" function like
    359      panic().  In this case the noreturn function needs to be added to
    360      objtool's hard-coded global_noreturns array.  Feel free to bug the
    361      objtool maintainer, or you can submit a patch.
    362
    363   2) funcA() uses the unreachable() annotation in a section of code
    364      that is actually reachable.
    365
    366   3) If funcA() calls an inline function, the object code for funcA()
    367      might be corrupt due to a gcc bug.  For more details, see:
    368      https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70646
    369
    3709. file.o: warning: objtool: funcA() call to funcB() with UACCESS enabled
    371
    372   This means that an unexpected call to a non-whitelisted function exists
    373   outside of arch-specific guards.
    374   X86: SMAP (stac/clac): __uaccess_begin()/__uaccess_end()
    375   ARM: PAN: uaccess_enable()/uaccess_disable()
    376
    377   These functions should be called to denote a minimal critical section around
    378   access to __user variables. See also: https://lwn.net/Articles/517475/
    379
    380   The intention of the warning is to prevent calls to funcB() from eventually
    381   calling schedule(), potentially leaking the AC flags state, and not
    382   restoring them correctly.
    383
    384   It also helps verify that there are no unexpected calls to funcB() which may
    385   access user space pages with protections against doing so disabled.
    386
    387   To fix, either:
    388   1) remove explicit calls to funcB() from funcA().
    389   2) add the correct guards before and after calls to low level functions like
    390      __get_user_size()/__put_user_size().
    391   3) add funcB to uaccess_safe_builtin whitelist in tools/objtool/check.c, if
    392      funcB obviously does not call schedule(), and is marked notrace (since
    393      function tracing inserts additional calls, which is not obvious from the
    394      sources).
    395
    39610. file.o: warning: func()+0x5c: stack layout conflict in alternatives
    397
    398    This means that in the use of the alternative() or ALTERNATIVE()
    399    macro, the code paths have conflicting modifications to the stack.
    400    The problem is that there is only one ORC unwind table, which means
    401    that the ORC unwind entries must be consistent for all possible
    402    instruction boundaries regardless of which code has been patched.
    403    This limitation can be overcome by massaging the alternatives with
    404    NOPs to shift the stack changes around so they no longer conflict.
    405
    40611. file.o: warning: unannotated intra-function call
    407
    408   This warning means that a direct call is done to a destination which
    409   is not at the beginning of a function. If this is a legit call, you
    410   can remove this warning by putting the ANNOTATE_INTRA_FUNCTION_CALL
    411   directive right before the call.
    412
    413
    414If the error doesn't seem to make sense, it could be a bug in objtool.
    415Feel free to ask the objtool maintainer for help.
    416
    417
    418Adding exceptions
    419-----------------
    420
    421If you _really_ need objtool to ignore something, and are 100% sure
    422that it won't affect kernel stack traces, you can tell objtool to
    423ignore it:
    424
    425- To skip validation of a function, use the STACK_FRAME_NON_STANDARD
    426  macro.
    427
    428- To skip validation of a file, add
    429
    430    OBJECT_FILES_NON_STANDARD_filename.o := y
    431
    432  to the Makefile.
    433
    434- To skip validation of a directory, add
    435
    436    OBJECT_FILES_NON_STANDARD := y
    437
    438  to the Makefile.
    439
    440NOTE: OBJECT_FILES_NON_STANDARD doesn't work for link time validation of
    441vmlinux.o or a linked module.  So it should only be used for files which
    442aren't linked into vmlinux or a module.