When building with CONFIG_STACK_VALIDATION on a ppc64le host with an x86
cross-compiler, Stephen Rothwell saw the following objtool build errors:
DESCEND objtool
CC /home/sfr/next/x86_64_allmodconfig/tools/objtool/builtin-check.o
CC /home/sfr/next/x86_64_allmodconfig/tools/objtool/special.o
CC /home/sfr/next/x86_64_allmodconfig/tools/objtool/elf.o
CC /home/sfr/next/x86_64_allmodconfig/tools/objtool/objtool.o
MKDIR /home/sfr/next/x86_64_allmodconfig/tools/objtool/arch/x86/insn/
CC /home/sfr/next/x86_64_allmodconfig/tools/objtool/libstring.o
elf.c:22:23: fatal error: sys/types.h: No such file or directory
compilation terminated.
CC /home/sfr/next/x86_64_allmodconfig/tools/objtool/exec-cmd.o
CC /home/sfr/next/x86_64_allmodconfig/tools/objtool/help.o
builtin-check.c:28:20: fatal error: string.h: No such file or directory
compilation terminated.
objtool.c:28:19: fatal error: stdio.h: No such file or directory
compilation terminated.
It fails to build because it tries to compile objtool with the
cross-compiler instead of the host compiler.
Ensure that it always uses the host compiler by ignoring CROSS_COMPILE.
In order to do that properly, the libsubcmd.a library needs to be built
in tools/objtool/ rather than tools/lib/subcmd/. The latter directory
contains the cross-compiled version which is needed for perf and
possibly other tools.
Note that cross-compiling for x86 on a _big_ endian system would result
in a bunch of false positive objtool warnings during the kernel build
because it isn't endian-aware. But that's generally a rare edge case
and there haven't been any reports of anybody needing that.
Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/55b63eefc347f1bb28573f972d8d1adbf1f1c31d.1456962210.git.jpoimboe@redhat.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
When running objtool on a ppc64le host to analyze x86 binaries, it
reports a lot of false warnings like:
ipc/compat_mq.o: warning: objtool: compat_SyS_mq_open()+0x91: can't find jump dest instruction at .text+0x3a5
The warnings are caused by the x86 instruction decoder setting the wrong
value for the jump instruction's immediate field because it assumes that
"char == signed char", which isn't true for all architectures. When
converting char to int, gcc sign-extends on x86 but doesn't sign-extend
on ppc64le.
According to the gcc man page, that's a feature, not a bug:
> Each kind of machine has a default for what "char" should be. It is
> either like "unsigned char" by default or like "signed char" by
> default.
>
> Ideally, a portable program should always use "signed char" or
> "unsigned char" when it depends on the signedness of an object.
Conform to the "standards" by changing the "char" casts to "signed
char". This results in no actual changes to the object code on x86.
Note: the x86 decoder now lives in three different locations in the
kernel tree, which are all kept in sync via makefile checks and
warnings: in-kernel, perf, and objtool. This fixes all three locations.
Eventually we should probably try to at least converge the two separate
"tools" locations into a single shared location.
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/9dd4161719b20e6def9564646d68bfbe498c549f.1456962210.git.jpoimboe@redhat.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
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:
[<ffffffff81812584>] dump_stack+0x4b/0x63
[<ffffffff812d6dc2>] cmdline_proc_show+0x12/0x30
[<ffffffff8127f568>] seq_read+0x108/0x3e0
[<ffffffff812cce62>] proc_reg_read+0x42/0x70
[<ffffffff81256197>] __vfs_read+0x37/0x100
[<ffffffff81256b16>] vfs_read+0x86/0x130
[<ffffffff81257898>] SyS_read+0x58/0xd0
[<ffffffff8181c1f2>] 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:
[<ffffffff81812584>] dump_stack+0x4b/0x63
[<ffffffff812d6dc2>] cmdline_proc_show+0x12/0x30
[<ffffffff812cce62>] proc_reg_read+0x42/0x70
[<ffffffff81256197>] __vfs_read+0x37/0x100
[<ffffffff81256b16>] vfs_read+0x86/0x130
[<ffffffff81257898>] SyS_read+0x58/0xd0
[<ffffffff8181c1f2>] 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 <jpoimboe@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Bernd Petrovitsch <bernd@petrovitsch.priv.at>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Chris J Arges <chris.j.arges@canonical.com>
Cc: Jiri Slaby <jslaby@suse.cz>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Michal Marek <mmarek@suse.cz>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Pedro Alves <palves@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: live-patching@vger.kernel.org
Link: http://lkml.kernel.org/r/f3efb173de43bd067b060de73f856567c0fa1174.1456719558.git.jpoimboe@redhat.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
objtool reports the following warnings for __schedule():
kernel/sched/core.o: warning: objtool:__schedule()+0x3c0: duplicate frame pointer save
kernel/sched/core.o: warning: objtool:__schedule()+0x3fd: sibling call from callable instruction with changed frame pointer
kernel/sched/core.o: warning: objtool:__schedule()+0x40a: call without frame pointer save/setup
kernel/sched/core.o: warning: objtool:__schedule()+0x7fd: frame pointer state mismatch
kernel/sched/core.o: warning: objtool:__schedule()+0x421: frame pointer state mismatch
Basically it's confused by two unusual attributes of the switch_to()
macro:
1. It saves prev's frame pointer to the old stack and restores next's
frame pointer from the new stack.
2. For new tasks it jumps directly to ret_from_fork.
Eventually it would probably be a good idea to clean up the
ret_from_fork hack so that new tasks are created with a valid initial
stack, as suggested by Andy:
https://lkml.kernel.org/r/CALCETrWsqCw4L1qKO9j9L5F+4ED4viuLQTFc=n1pKBZfFPQUFg@mail.gmail.com
Then __schedule() could return normally into the new code and objtool
hopefully wouldn't have a problem anymore.
In the meantime, mark its stack frame as non-standard so we can have a
baseline with no objtool warnings. The marker also serves as a reminder
that this code could be improved a bit.
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Bernd Petrovitsch <bernd@petrovitsch.priv.at>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Chris J Arges <chris.j.arges@canonical.com>
Cc: Jiri Slaby <jslaby@suse.cz>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Michal Marek <mmarek@suse.cz>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Pedro Alves <palves@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: live-patching@vger.kernel.org
Link: http://lkml.kernel.org/r/91190e324ebd7fcd01748d508d0dfd4693e84d91.1456719558.git.jpoimboe@redhat.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Code which runs outside the kernel's normal mode of operation often does
unusual things which can cause a static analysis tool like objtool to
emit false positive warnings:
- boot image
- vdso image
- relocation
- realmode
- efi
- head
- purgatory
- modpost
Set OBJECT_FILES_NON_STANDARD for their related files and directories,
which will tell objtool to skip checking them. It's ok to skip them
because they don't affect runtime stack traces.
Also skip the following code which does the right thing with respect to
frame pointers, but is too "special" to be validated by a tool:
- entry
- mcount
Also skip the test_nx module because it modifies its exception handling
table at runtime, which objtool can't understand. Fortunately it's
just a test module so it doesn't matter much.
Currently objtool is the only user of OBJECT_FILES_NON_STANDARD, but it
might eventually be useful for other tools.
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Bernd Petrovitsch <bernd@petrovitsch.priv.at>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Chris J Arges <chris.j.arges@canonical.com>
Cc: Jiri Slaby <jslaby@suse.cz>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Michal Marek <mmarek@suse.cz>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Pedro Alves <palves@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: live-patching@vger.kernel.org
Link: http://lkml.kernel.org/r/366c080e3844e8a5b6a0327dc7e8c2b90ca3baeb.1456719558.git.jpoimboe@redhat.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Pull ARC fixes from Vineet Gupta:
- Fix for csd deadlock due to missing self IPI
- Accompanying IPI cleanups / optimization
- Brown paper bag bug in one of the cleanups above
- Boot reporting updates for new hardware features
- Don't force DEVTMPFS if INITRAMFS
* tag 'arc-4.5-rc6-fixes-upd' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc:
arc: SMP: CONFIG_ARC_IPI_DBG cleanup
ARC: SMP: No need for CONFIG_ARC_IPI_DBG
ARCv2: Elide sending new cross core intr if receiver didn't ack prev
ARCv2: SMP: Push IPI_IRQ into IPI provider
ARC: [intc-compact] Remove IPI setup from ARCompact port
ARCv2: SMP: Emulate IPI to self using software triggered interrupt
arc: get rid of DEVTMPFS dependency on INITRAMFS_SOURCE
ARCv2: boot report CCMs (Closely Coupled Memories)
ARCv2: boot print Low Latency Memory
ARC: Assume multiplier is always present
Pull vfs fixes from Al Viro:
"Assorted fixes - xattr one from this cycle, the rest - stable fodder"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
fs/pnode.c: treat zero mnt_group_id-s as unequal
affs_do_readpage_ofs(): just use kmap_atomic() around memcpy()
xattr handlers: plug a lock leak in simple_xattr_list
fs: allow no_seek_end_llseek to actually seek
Previous Commit ("ARC: SMP: No need for CONFIG_ARC_IPI_DBG") removed
the Kconfig option ARC_IPI_DBG. Remove the last reference on this
option.
Signed-off-by: Valentin Rothberg <valentinrothberg@gmail.com>
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
If __preempt_schedule() or __preempt_schedule_notrace() is referenced at
the beginning of a function, gcc can insert the asm inline "call
___preempt_schedule[_notrace]" instruction before setting up a stack
frame, which breaks frame pointer convention if CONFIG_FRAME_POINTER is
enabled and can result in bad stack traces.
Force a stack frame to be created if CONFIG_FRAME_POINTER is enabled by
listing the stack pointer as an output operand for the inline asm
statements.
Specifically this fixes the following stacktool warnings:
stacktool: drivers/scsi/hpsa.o: hpsa_scsi_do_simple_cmd.constprop.106()+0x79: call without frame pointer save/setup
stacktool: fs/mbcache.o: mb_cache_entry_find_first()+0x70: call without frame pointer save/setup
stacktool: fs/mbcache.o: mb_cache_entry_find_first()+0x92: call without frame pointer save/setup
stacktool: fs/mbcache.o: mb_cache_entry_free()+0xff: call without frame pointer save/setup
stacktool: fs/mbcache.o: mb_cache_entry_free()+0xf5: call without frame pointer save/setup
stacktool: fs/mbcache.o: mb_cache_entry_free()+0x11a: call without frame pointer save/setup
stacktool: fs/mbcache.o: mb_cache_entry_get()+0x225: call without frame pointer save/setup
stacktool: kernel/locking/percpu-rwsem.o: percpu_up_read()+0x27: call without frame pointer save/setup
stacktool: kernel/profile.o: do_profile_hits.isra.5()+0x139: call without frame pointer save/setup
stacktool: lib/nmi_backtrace.o: nmi_trigger_all_cpu_backtrace()+0x2b6: call without frame pointer save/setup
stacktool: net/rds/ib_cm.o: rds_ib_cq_comp_handler_recv()+0x58: call without frame pointer save/setup
stacktool: net/rds/ib_cm.o: rds_ib_cq_comp_handler_send()+0x58: call without frame pointer save/setup
stacktool: net/rds/ib_recv.o: rds_ib_attempt_ack()+0xc1: call without frame pointer save/setup
stacktool: net/rds/iw_recv.o: rds_iw_attempt_ack()+0xc1: call without frame pointer save/setup
stacktool: net/rds/iw_recv.o: rds_iw_recv_cq_comp_handler()+0x55: call without frame pointer save/setup
So it only adds a stack frame to 15 call sites out of ~5000 calls to
___preempt_schedule[_notrace](). All the others already had stack frames.
Oddly, this change actually seems to make things faster in a lot of
cases. For many smaller functions it causes the stack frame creation to
get moved out of the common path and into the unlikely path.
For example, here's the original cyc2ns_read_end():
ffffffff8101f8c0 <cyc2ns_read_end>:
ffffffff8101f8c0: 55 push %rbp
ffffffff8101f8c1: 48 89 e5 mov %rsp,%rbp
ffffffff8101f8c4: 83 6f 10 01 subl $0x1,0x10(%rdi)
ffffffff8101f8c8: 75 08 jne ffffffff8101f8d2 <cyc2ns_read_end+0x12>
ffffffff8101f8ca: 65 48 89 3d e6 5a ff mov %rdi,%gs:0x7eff5ae6(%rip) # 153b8 <cyc2ns+0x38>
ffffffff8101f8d1: 7e
ffffffff8101f8d2: 65 ff 0d 77 c4 fe 7e decl %gs:0x7efec477(%rip) # bd50 <__preempt_count>
ffffffff8101f8d9: 74 02 je ffffffff8101f8dd <cyc2ns_read_end+0x1d>
ffffffff8101f8db: 5d pop %rbp
ffffffff8101f8dc: c3 retq
ffffffff8101f8dd: e8 1e 37 fe ff callq ffffffff81003000 <___preempt_schedule>
ffffffff8101f8e2: 5d pop %rbp
ffffffff8101f8e3: c3 retq
ffffffff8101f8e4: 66 66 66 2e 0f 1f 84 data16 data16 nopw %cs:0x0(%rax,%rax,1)
ffffffff8101f8eb: 00 00 00 00 00
And here's the same function with the patch:
ffffffff8101f8c0 <cyc2ns_read_end>:
ffffffff8101f8c0: 83 6f 10 01 subl $0x1,0x10(%rdi)
ffffffff8101f8c4: 75 08 jne ffffffff8101f8ce <cyc2ns_read_end+0xe>
ffffffff8101f8c6: 65 48 89 3d ea 5a ff mov %rdi,%gs:0x7eff5aea(%rip) # 153b8 <cyc2ns+0x38>
ffffffff8101f8cd: 7e
ffffffff8101f8ce: 65 ff 0d 7b c4 fe 7e decl %gs:0x7efec47b(%rip) # bd50 <__preempt_count>
ffffffff8101f8d5: 74 01 je ffffffff8101f8d8 <cyc2ns_read_end+0x18>
ffffffff8101f8d7: c3 retq
ffffffff8101f8d8: 55 push %rbp
ffffffff8101f8d9: 48 89 e5 mov %rsp,%rbp
ffffffff8101f8dc: e8 1f 37 fe ff callq ffffffff81003000 <___preempt_schedule>
ffffffff8101f8e1: 5d pop %rbp
ffffffff8101f8e2: c3 retq
ffffffff8101f8e3: 66 66 66 66 2e 0f 1f data16 data16 data16 nopw %cs:0x0(%rax,%rax,1)
ffffffff8101f8ea: 84 00 00 00 00 00
Notice that it moved the frame pointer setup code to the unlikely
___preempt_schedule() call path. Going through a sampling of the
differences in the asm, that's the most common change I see.
Otherwise it has no real effect on callers which already have stack
frames (though it does result in the reordering of some 'mov's).
Reported-by: Jiri Slaby <jslaby@suse.cz>
Tested-by: Jiri Slaby <jslaby@suse.cz>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: live-patching@vger.kernel.org
Link: http://lkml.kernel.org/r/20160218174158.GA28230@treble.redhat.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>