Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1695264 > unrolled thread
| Started by | Josh Poimboeuf <jpoimboe@redhat.com> |
|---|---|
| First post | 2017-07-25 01:40 +0200 |
| Last post | 2017-07-29 06:00 +0200 |
| Articles | 11 — 4 participants |
Back to article view | Back to linux.kernel
[PATCH v4 0/2] ORC unwinder Josh Poimboeuf <jpoimboe@redhat.com> - 2017-07-25 01:40 +0200
[PATCH v4 2/2] x86/kconfig: make it easier to switch to the new ORC unwinder Josh Poimboeuf <jpoimboe@redhat.com> - 2017-07-25 01:40 +0200
Re: [PATCH v4 2/2] x86/kconfig: make it easier to switch to the new ORC unwinder Ingo Molnar <mingo@kernel.org> - 2017-07-25 11:20 +0200
Re: [PATCH v4 2/2] x86/kconfig: make it easier to switch to the new ORC unwinder Josh Poimboeuf <jpoimboe@redhat.com> - 2017-07-25 16:00 +0200
[tip:x86/asm] x86/kconfig: Consolidate unwinders into multiple choice selection tip-bot for Josh Poimboeuf <tipbot@zytor.com> - 2017-07-26 14:20 +0200
[tip:x86/asm] x86/kconfig: Make it easier to switch to the new ORC unwinder tip-bot for Josh Poimboeuf <tipbot@zytor.com> - 2017-07-26 14:20 +0200
Re: [PATCH v4 1/2] x86/unwind: add ORC unwinder "Levin, Alexander (Sasha Levin)" <alexander.levin@verizon.com> - 2017-07-28 18:50 +0200
Re: [PATCH v4 1/2] x86/unwind: add ORC unwinder Josh Poimboeuf <jpoimboe@redhat.com> - 2017-07-28 20:00 +0200
Re: [PATCH v4 1/2] x86/unwind: add ORC unwinder "Levin, Alexander (Sasha Levin)" <alexander.levin@verizon.com> - 2017-07-28 20:40 +0200
Re: [PATCH v4 1/2] x86/unwind: add ORC unwinder Josh Poimboeuf <jpoimboe@redhat.com> - 2017-07-28 21:00 +0200
Re: [PATCH v4 1/2] x86/unwind: add ORC unwinder Josh Poimboeuf <jpoimboe@redhat.com> - 2017-07-29 06:00 +0200
| From | Josh Poimboeuf <jpoimboe@redhat.com> |
|---|---|
| Date | 2017-07-25 01:40 +0200 |
| Subject | [PATCH v4 0/2] ORC unwinder |
| Message-ID | <u6V7b-3vi-7@gated-at.bofh.it> |
All the prerequisite patches have been merged into -tip since I posted
v3. These last two patches are:
1) the ORC unwinder itself; and
2) a kconfig tweak to make it easier to switch from
CONFIG_FRAME_POINTER to CONFIG_ORC_UNWINDER.
v4 changes:
- slightly tweak documentation wording re: RAM usage (Ingo M)
- use READ_ONCE_NOCHECK in __unwind_start() (Jiri S)
- in orc_find(), use printk_deferred_once() instead of WARN_ON_ONCE()
because printk doesn't work in all error scenarios
-----
Create a new "ORC" unwinder, enabled by CONFIG_ORC_UNWINDER, and plug it
into the x86 unwinder framework. Objtool is used to generate the ORC
debuginfo. The ORC debuginfo format is basically a simplified version
of DWARF CFI. More details below.
The unwinder works well in my testing. It unwinds through interrupts,
exceptions, and preemption, with and without frame pointers, across
aligned stacks and dynamically allocated stacks. If something goes
wrong during an oops, it successfully falls back to printing the '?'
entries just like the frame pointer unwinder.
Some potential future improvements:
- properly annotate or fix whitelisted functions and files
- add reliability checks for livepatch
- runtime NMI stack reliability checker
- generated code integration
This code can also be found at:
https://git.kernel.org/pub/scm/linux/kernel/git/jpoimboe/linux.git orc-v4
Here's the contents of the orc-unwinder.txt file which explains the
'why' in more detail:
ORC unwinder
============
Overview
--------
The kernel CONFIG_ORC_UNWINDER option enables the ORC unwinder, which is
similar in concept to a DWARF unwinder. The difference is that the
format of the ORC data is much simpler than DWARF, which in turn allows
the ORC unwinder to be much simpler and faster.
The ORC data consists of unwind tables which are generated by objtool.
They contain out-of-band data which is used by the in-kernel ORC
unwinder. Objtool generates the ORC data by first doing compile-time
stack metadata validation (CONFIG_STACK_VALIDATION). After analyzing
all the code paths of a .o file, it determines information about the
stack state at each instruction address in the file and outputs that
information to the .orc_unwind and .orc_unwind_ip sections.
The per-object ORC sections are combined at link time and are sorted and
post-processed at boot time. The unwinder uses the resulting data to
correlate instruction addresses with their stack states at run time.
ORC vs frame pointers
---------------------
With frame pointers enabled, GCC adds instrumentation code to every
function in the kernel. The kernel's .text size increases by about
3.2%, resulting in a broad kernel-wide slowdown. Measurements by Mel
Gorman [1] have shown a slowdown of 5-10% for some workloads.
In contrast, the ORC unwinder has no effect on text size or runtime
performance, because the debuginfo is out of band. So if you disable
frame pointers and enable the ORC unwinder, you get a nice performance
improvement across the board, and still have reliable stack traces.
Ingo Molnar says:
"Note that it's not just a performance improvement, but also an
instruction cache locality improvement: 3.2% .text savings almost
directly transform into a similarly sized reduction in cache
footprint. That can transform to even higher speedups for workloads
whose cache locality is borderline."
Another benefit of ORC compared to frame pointers is that it can
reliably unwind across interrupts and exceptions. Frame pointer based
unwinds can sometimes skip the caller of the interrupted function, if it
was a leaf function or if the interrupt hit before the frame pointer was
saved.
The main disadvantage of the ORC unwinder compared to frame pointers is
that it needs more memory to store the ORC unwind tables: roughly 2-4MB
depending on the kernel config.
ORC vs DWARF
------------
ORC debuginfo's advantage over DWARF itself is that it's much simpler.
It gets rid of the complex DWARF CFI state machine and also gets rid of
the tracking of unnecessary registers. This allows the unwinder to be
much simpler, meaning fewer bugs, which is especially important for
mission critical oops code.
The simpler debuginfo format also enables the unwinder to be much faster
than DWARF, which is important for perf and lockdep. In a basic
performance test by Jiri Slaby [2], the ORC unwinder was about 20x
faster than an out-of-tree DWARF unwinder. (Note: That measurement was
taken before some performance tweaks were added, which doubled
performance, so the speedup over DWARF may be closer to 40x.)
The ORC data format does have a few downsides compared to DWARF. ORC
unwind tables take up ~50% more RAM (+1.3MB on an x86 defconfig kernel)
than DWARF-based eh_frame tables.
Another potential downside is that, as GCC evolves, it's conceivable
that the ORC data may end up being *too* simple to describe the state of
the stack for certain optimizations. But IMO this is unlikely because
GCC saves the frame pointer for any unusual stack adjustments it does,
so I suspect we'll really only ever need to keep track of the stack
pointer and the frame pointer between call frames. But even if we do
end up having to track all the registers DWARF tracks, at least we will
still be able to control the format, e.g. no complex state machines.
ORC unwind table generation
---------------------------
The ORC data is generated by objtool. With the existing compile-time
stack metadata validation feature, objtool already follows all code
paths, and so it already has all the information it needs to be able to
generate ORC data from scratch. So it's an easy step to go from stack
validation to ORC data generation.
It should be possible to instead generate the ORC data with a simple
tool which converts DWARF to ORC data. However, such a solution would
be incomplete due to the kernel's extensive use of asm, inline asm, and
special sections like exception tables.
That could be rectified by manually annotating those special code paths
using GNU assembler .cfi annotations in .S files, and homegrown
annotations for inline asm in .c files. But asm annotations were tried
in the past and were found to be unmaintainable. They were often
incorrect/incomplete and made the code harder to read and keep updated.
And based on looking at glibc code, annotating inline asm in .c files
might be even worse.
Objtool still needs a few annotations, but only in code which does
unusual things to the stack like entry code. And even then, far fewer
annotations are needed than what DWARF would need, so they're much more
maintainable than DWARF CFI annotations.
So the advantages of using objtool to generate ORC data are that it
gives more accurate debuginfo, with very few annotations. It also
insulates the kernel from toolchain bugs which can be very painful to
deal with in the kernel since we often have to workaround issues in
older versions of the toolchain for years.
The downside is that the unwinder now becomes dependent on objtool's
ability to reverse engineer GCC code flow. If GCC optimizations become
too complicated for objtool to follow, the ORC data generation might
stop working or become incomplete. (It's worth noting that livepatch
already has such a dependency on objtool's ability to follow GCC code
flow.)
If newer versions of GCC come up with some optimizations which break
objtool, we may need to revisit the current implementation. Some
possible solutions would be asking GCC to make the optimizations more
palatable, or having objtool use DWARF as an additional input, or
creating a GCC plugin to assist objtool with its analysis. But for now,
objtool follows GCC code quite well.
Unwinder implementation details
-------------------------------
Objtool generates the ORC data by integrating with the compile-time
stack metadata validation feature, which is described in detail in
tools/objtool/Documentation/stack-validation.txt. After analyzing all
the code paths of a .o file, it creates an array of orc_entry structs,
and a parallel array of instruction addresses associated with those
structs, and writes them to the .orc_unwind and .orc_unwind_ip sections
respectively.
The ORC data is split into the two arrays for performance reasons, to
make the searchable part of the data (.orc_unwind_ip) more compact. The
arrays are sorted in parallel at boot time.
Performance is further improved by the use of a fast lookup table which
is created at runtime. The fast lookup table associates a given address
with a range of indices for the .orc_unwind table, so that only a small
subset of the table needs to be searched.
Etymology
---------
Orcs, fearsome creatures of medieval folklore, are the Dwarves' natural
enemies. Similarly, the ORC unwinder was created in opposition to the
complexity and slowness of DWARF.
"Although Orcs rarely consider multiple solutions to a problem, they do
excel at getting things done because they are creatures of action, not
thought." [3] Similarly, unlike the esoteric DWARF unwinder, the
veracious ORC unwinder wastes no time or siloconic effort decoding
variable-length zero-extended unsigned-integer byte-coded
state-machine-based debug information entries.
Similar to how Orcs frequently unravel the well-intentioned plans of
their adversaries, the ORC unwinder frequently unravels stacks with
brutal, unyielding efficiency.
ORC stands for Oops Rewind Capability.
[1] https://lkml.kernel.org/r/20170602104048.jkkzssljsompjdwy@suse.de
[2] https://lkml.kernel.org/r/d2ca5435-6386-29b8-db87-7f227c2b713a@suse.cz
[3] http://dustin.wikidot.com/half-orcs-and-orcs
Josh Poimboeuf (2):
x86/unwind: add ORC unwinder
x86/kconfig: make it easier to switch to the new ORC unwinder
Documentation/x86/orc-unwinder.txt | 179 ++++++++++++
arch/um/include/asm/unwind.h | 8 +
arch/x86/Kconfig | 1 +
arch/x86/Kconfig.debug | 24 ++
arch/x86/include/asm/module.h | 9 +
arch/x86/include/asm/orc_lookup.h | 46 +++
arch/x86/include/asm/orc_types.h | 2 +-
arch/x86/include/asm/unwind.h | 76 +++--
arch/x86/kernel/Makefile | 8 +-
arch/x86/kernel/module.c | 11 +-
arch/x86/kernel/setup.c | 3 +
arch/x86/kernel/unwind_frame.c | 39 +--
arch/x86/kernel/unwind_guess.c | 5 +
arch/x86/kernel/unwind_orc.c | 582 +++++++++++++++++++++++++++++++++++++
arch/x86/kernel/vmlinux.lds.S | 3 +
include/asm-generic/vmlinux.lds.h | 27 +-
lib/Kconfig.debug | 9 +-
scripts/Makefile.build | 14 +-
18 files changed, 979 insertions(+), 67 deletions(-)
create mode 100644 Documentation/x86/orc-unwinder.txt
create mode 100644 arch/um/include/asm/unwind.h
create mode 100644 arch/x86/include/asm/orc_lookup.h
create mode 100644 arch/x86/kernel/unwind_orc.c
--
2.13.3
[toc] | [next] | [standalone]
| From | Josh Poimboeuf <jpoimboe@redhat.com> |
|---|---|
| Date | 2017-07-25 01:40 +0200 |
| Subject | [PATCH v4 2/2] x86/kconfig: make it easier to switch to the new ORC unwinder |
| Message-ID | <u6V7b-3vi-17@gated-at.bofh.it> |
| In reply to | #1695264 |
A couple of Kconfig changes which make it much easier to switch to the new CONFIG_ORC_UNWINDER: 1) Remove x86 dependencies on CONFIG_FRAME_POINTER for lockdep, latencytop, and fault injection. x86 has a 'guess' unwinder which just scans the stack for kernel text addresses. It's not 100% accurate but in many cases it's good enough. This allows those users who don't want the text overhead of the frame pointer or ORC unwinders to still use these features. More importantly, this also makes it much more straightforward to disable frame pointers. 2) Make CONFIG_ORC_UNWINDER depend on !CONFIG_FRAME_POINTER. While it would be possible to have both enabled, it doesn't really make sense to do so. So enforce a sane configuration to prevent the user from making a dumb mistake. With these changes, when you disable CONFIG_FRAME_POINTER, "make oldconfig" will ask if you want to enable CONFIG_ORC_UNWINDER. Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com> --- arch/x86/Kconfig.debug | 7 +++---- lib/Kconfig.debug | 6 +++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index d5bca2ec8a74..e6176007b838 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -358,7 +358,7 @@ config PUNIT_ATOM_DEBUG config ORC_UNWINDER bool "ORC unwinder" - depends on X86_64 + depends on X86_64 && !FRAME_POINTER select STACK_VALIDATION ---help--- This option enables the ORC (Oops Rewind Capability) unwinder for @@ -366,9 +366,8 @@ config ORC_UNWINDER a simplified version of the DWARF Call Frame Information standard. This unwinder is more accurate across interrupt entry frames than the - frame pointer unwinder. It can also enable a 5-10% performance - improvement across the entire kernel if CONFIG_FRAME_POINTER is - disabled. + frame pointer unwinder. It also enables a 5-10% performance + improvement across the entire kernel compared to frame pointers. Enabling this option will increase the kernel's runtime memory usage by roughly 2-4MB, depending on your kernel config. diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 0f0d019ffb99..32a48e739e26 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -1124,7 +1124,7 @@ config LOCKDEP bool depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT select STACKTRACE - select FRAME_POINTER if !MIPS && !PPC && !ARM_UNWIND && !S390 && !MICROBLAZE && !ARC && !SCORE + select FRAME_POINTER if !MIPS && !PPC && !ARM_UNWIND && !S390 && !MICROBLAZE && !ARC && !SCORE && !X86 select KALLSYMS select KALLSYMS_ALL @@ -1543,7 +1543,7 @@ config FAULT_INJECTION_STACKTRACE_FILTER depends on FAULT_INJECTION_DEBUG_FS && STACKTRACE_SUPPORT depends on !X86_64 select STACKTRACE - select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND && !ARC && !SCORE + select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND && !ARC && !SCORE && !X86 help Provide stacktrace filter for fault-injection capabilities @@ -1552,7 +1552,7 @@ config LATENCYTOP depends on DEBUG_KERNEL depends on STACKTRACE_SUPPORT depends on PROC_FS - select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND && !ARC + select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND && !ARC && !X86 select KALLSYMS select KALLSYMS_ALL select STACKTRACE -- 2.13.3
[toc] | [prev] | [next] | [standalone]
| From | Ingo Molnar <mingo@kernel.org> |
|---|---|
| Date | 2017-07-25 11:20 +0200 |
| Subject | Re: [PATCH v4 2/2] x86/kconfig: make it easier to switch to the new ORC unwinder |
| Message-ID | <u74av-VK-37@gated-at.bofh.it> |
| In reply to | #1695268 |
* Josh Poimboeuf <jpoimboe@redhat.com> wrote: > A couple of Kconfig changes which make it much easier to switch to the > new CONFIG_ORC_UNWINDER: > > 1) Remove x86 dependencies on CONFIG_FRAME_POINTER for lockdep, > latencytop, and fault injection. x86 has a 'guess' unwinder which > just scans the stack for kernel text addresses. It's not 100% > accurate but in many cases it's good enough. This allows those users > who don't want the text overhead of the frame pointer or ORC > unwinders to still use these features. More importantly, this also > makes it much more straightforward to disable frame pointers. > > 2) Make CONFIG_ORC_UNWINDER depend on !CONFIG_FRAME_POINTER. While it > would be possible to have both enabled, it doesn't really make sense > to do so. So enforce a sane configuration to prevent the user from > making a dumb mistake. > > With these changes, when you disable CONFIG_FRAME_POINTER, "make > oldconfig" will ask if you want to enable CONFIG_ORC_UNWINDER. Yeah, so I think this is still suboptimal: the frame pointer and the Orc unwinders are configured in different places, and the user won't know about the various unwinder options unless stumbling across them by accidentally disabling frame pointers ... Also, the Kconfig help text for frame pointers is now actively misleading: CONFIG_FRAME_POINTER: If you say Y here the resulting kernel image will be slightly larger and slower, but it gives very useful debugging information in case of kernel bugs. (precise oopses/stacktraces/warnings) Please, as I suggested it before, make it a multiple choice option: frame, Orc, or the guess unwinder. I'd only offer the 'guess' unwinder if EXPERT is selected, because it's a really sub-optimal selection all things considered. Once things are tested and it's all rosy we can change the default x86 unwinder to Orc and organize the naming of the config variables to: CONFIG_UNWINDER_ORC CONFIG_UNWINDER_FRAME_POINTER CONFIG_UNWINDER_GUESS Thanks, Ingo
[toc] | [prev] | [next] | [standalone]
| From | Josh Poimboeuf <jpoimboe@redhat.com> |
|---|---|
| Date | 2017-07-25 16:00 +0200 |
| Subject | Re: [PATCH v4 2/2] x86/kconfig: make it easier to switch to the new ORC unwinder |
| Message-ID | <u78xs-3uy-35@gated-at.bofh.it> |
| In reply to | #1695531 |
On Tue, Jul 25, 2017 at 11:10:59AM +0200, Ingo Molnar wrote:
>
> * Josh Poimboeuf <jpoimboe@redhat.com> wrote:
>
> > A couple of Kconfig changes which make it much easier to switch to the
> > new CONFIG_ORC_UNWINDER:
> >
> > 1) Remove x86 dependencies on CONFIG_FRAME_POINTER for lockdep,
> > latencytop, and fault injection. x86 has a 'guess' unwinder which
> > just scans the stack for kernel text addresses. It's not 100%
> > accurate but in many cases it's good enough. This allows those users
> > who don't want the text overhead of the frame pointer or ORC
> > unwinders to still use these features. More importantly, this also
> > makes it much more straightforward to disable frame pointers.
> >
> > 2) Make CONFIG_ORC_UNWINDER depend on !CONFIG_FRAME_POINTER. While it
> > would be possible to have both enabled, it doesn't really make sense
> > to do so. So enforce a sane configuration to prevent the user from
> > making a dumb mistake.
> >
> > With these changes, when you disable CONFIG_FRAME_POINTER, "make
> > oldconfig" will ask if you want to enable CONFIG_ORC_UNWINDER.
>
> Yeah, so I think this is still suboptimal: the frame pointer and the Orc unwinders
> are configured in different places, and the user won't know about the various
> unwinder options unless stumbling across them by accidentally disabling frame
> pointers ...
>
> Also, the Kconfig help text for frame pointers is now actively misleading:
>
> CONFIG_FRAME_POINTER:
>
> If you say Y here the resulting kernel image will be slightly
> larger and slower, but it gives very useful debugging information
> in case of kernel bugs. (precise oopses/stacktraces/warnings)
>
> Please, as I suggested it before, make it a multiple choice option: frame, Orc, or
> the guess unwinder.
>
> I'd only offer the 'guess' unwinder if EXPERT is selected, because it's a really
> sub-optimal selection all things considered.
>
> Once things are tested and it's all rosy we can change the default x86 unwinder to
> Orc and organize the naming of the config variables to:
>
> CONFIG_UNWINDER_ORC
> CONFIG_UNWINDER_FRAME_POINTER
> CONFIG_UNWINDER_GUESS
How about the below patch? It goes on top of the other two.
----
From: Josh Poimboeuf <jpoimboe@redhat.com>
Subject: [PATCH] x86/kconfig: consolidate unwinders into multiple choice selection
There are three mutually exclusive unwinders. Make that more obvious by
combining them into a multiple-choice selection:
CONFIG_FRAME_POINTER_UNWINDER
CONFIG_ORC_UNWINDER
CONFIG_GUESS_UNWINDER (if CONFIG_EXPERT=y)
Frame pointers are still the default (for now).
The old CONFIG_FRAME_POINTER option is still used in some
arch-independent places, so keep it around, but make it invisible to the
user on x86. It's now selected by CONFIG_FRAME_POINTER_UNWINDER.
Suggested-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
---
arch/x86/Kconfig | 3 +--
arch/x86/Kconfig.debug | 47 ++++++++++++++++++++++++++++++++++++-------
arch/x86/configs/tiny.config | 2 ++
arch/x86/include/asm/unwind.h | 4 ++--
4 files changed, 45 insertions(+), 11 deletions(-)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 21c75a652bb9..1e789ecefc02 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -73,7 +73,6 @@ config X86
select ARCH_USE_QUEUED_RWLOCKS
select ARCH_USE_QUEUED_SPINLOCKS
select ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH
- select ARCH_WANT_FRAME_POINTERS
select ARCH_WANTS_DYNAMIC_TASK_STRUCT
select ARCH_WANTS_THP_SWAP if X86_64
select BUILDTIME_EXTABLE_SORT
@@ -168,7 +167,7 @@ config X86
select HAVE_PERF_REGS
select HAVE_PERF_USER_STACK_DUMP
select HAVE_REGS_AND_STACK_ACCESS_API
- select HAVE_RELIABLE_STACKTRACE if X86_64 && FRAME_POINTER && STACK_VALIDATION
+ select HAVE_RELIABLE_STACKTRACE if X86_64 && FRAME_POINTER_UNWINDER && STACK_VALIDATION
select HAVE_STACK_VALIDATION if X86_64
select HAVE_SYSCALL_TRACEPOINTS
select HAVE_UNSTABLE_SCHED_CLOCK
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
index e6176007b838..71a48a30fc84 100644
--- a/arch/x86/Kconfig.debug
+++ b/arch/x86/Kconfig.debug
@@ -356,9 +356,32 @@ config PUNIT_ATOM_DEBUG
The current power state can be read from
/sys/kernel/debug/punit_atom/dev_power_state
+choice
+ prompt "Choose kernel unwinder"
+ default FRAME_POINTER_UNWINDER
+ ---help---
+ This determines which method will be used for unwinding kernel stack
+ traces for panics, oopses, bugs, warnings, perf, /proc/<pid>/stack,
+ livepatch, lockdep, and more.
+
+config FRAME_POINTER_UNWINDER
+ bool "Frame pointer unwinder"
+ select FRAME_POINTER
+ ---help---
+ This option enables the frame pointer unwinder for unwinding kernel
+ stack traces.
+
+ The unwinder itself is fast and it uses less RAM than the ORC
+ unwinder, but the kernel text size will grow by ~3% and the kernel's
+ overall performance will degrade by roughly 5-10%.
+
+ This option is recommended if you want to use the livepatch
+ consistency model, as this is currently the only way to get a
+ reliable stack trace (CONFIG_HAVE_RELIABLE_STACKTRACE).
+
config ORC_UNWINDER
bool "ORC unwinder"
- depends on X86_64 && !FRAME_POINTER
+ depends on X86_64
select STACK_VALIDATION
---help---
This option enables the ORC (Oops Rewind Capability) unwinder for
@@ -372,12 +395,22 @@ config ORC_UNWINDER
Enabling this option will increase the kernel's runtime memory usage
by roughly 2-4MB, depending on your kernel config.
-config FRAME_POINTER_UNWINDER
- def_bool y
- depends on !ORC_UNWINDER && FRAME_POINTER
-
config GUESS_UNWINDER
- def_bool y
- depends on !ORC_UNWINDER && !FRAME_POINTER
+ bool "Guess unwinder"
+ depends on EXPERT
+ ---help---
+ This option enables the "guess" unwinder for unwinding kernel stack
+ traces. It scans the stack and reports every kernel text address it
+ finds. Some of the addresses it reports may be incorrect.
+
+ While this option often produces false positives, it can still be
+ useful in many cases. Unlike the other unwinders, it has no runtime
+ overhead.
+
+endchoice
+
+config FRAME_POINTER
+ depends on !ORC_UNWINDER && !GUESS_UNWINDER
+ bool
endmenu
diff --git a/arch/x86/configs/tiny.config b/arch/x86/configs/tiny.config
index 4b429df40d7a..550cd5012b73 100644
--- a/arch/x86/configs/tiny.config
+++ b/arch/x86/configs/tiny.config
@@ -1,3 +1,5 @@
CONFIG_NOHIGHMEM=y
# CONFIG_HIGHMEM4G is not set
# CONFIG_HIGHMEM64G is not set
+CONFIG_GUESS_UNWINDER=y
+# CONFIG_FRAME_POINTER_UNWINDER is not set
diff --git a/arch/x86/include/asm/unwind.h b/arch/x86/include/asm/unwind.h
index 25b8d31a007d..e9f793e2df7a 100644
--- a/arch/x86/include/asm/unwind.h
+++ b/arch/x86/include/asm/unwind.h
@@ -16,7 +16,7 @@ struct unwind_state {
bool signal, full_regs;
unsigned long sp, bp, ip;
struct pt_regs *regs;
-#elif defined(CONFIG_FRAME_POINTER)
+#elif defined(CONFIG_FRAME_POINTER_UNWINDER)
bool got_irq;
unsigned long *bp, *orig_sp, ip;
struct pt_regs *regs;
@@ -50,7 +50,7 @@ void unwind_start(struct unwind_state *state, struct task_struct *task,
__unwind_start(state, task, regs, first_frame);
}
-#if defined(CONFIG_ORC_UNWINDER) || defined(CONFIG_FRAME_POINTER)
+#if defined(CONFIG_ORC_UNWINDER) || defined(CONFIG_FRAME_POINTER_UNWINDER)
static inline struct pt_regs *unwind_get_entry_regs(struct unwind_state *state)
{
if (unwind_done(state))
--
2.13.3
[toc] | [prev] | [next] | [standalone]
| From | tip-bot for Josh Poimboeuf <tipbot@zytor.com> |
|---|---|
| Date | 2017-07-26 14:20 +0200 |
| Subject | [tip:x86/asm] x86/kconfig: Consolidate unwinders into multiple choice selection |
| Message-ID | <u7tsf-aO-23@gated-at.bofh.it> |
| In reply to | #1695755 |
Commit-ID: 81d387190039c14edac8de2b3ec789beb899afd9
Gitweb: http://git.kernel.org/tip/81d387190039c14edac8de2b3ec789beb899afd9
Author: Josh Poimboeuf <jpoimboe@redhat.com>
AuthorDate: Tue, 25 Jul 2017 08:54:24 -0500
Committer: Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 26 Jul 2017 14:05:36 +0200
x86/kconfig: Consolidate unwinders into multiple choice selection
There are three mutually exclusive unwinders. Make that more obvious by
combining them into a multiple-choice selection:
CONFIG_FRAME_POINTER_UNWINDER
CONFIG_ORC_UNWINDER
CONFIG_GUESS_UNWINDER (if CONFIG_EXPERT=y)
Frame pointers are still the default (for now).
The old CONFIG_FRAME_POINTER option is still used in some
arch-independent places, so keep it around, but make it
invisible to the user on x86 - it's now selected by
CONFIG_FRAME_POINTER_UNWINDER=y.
Suggested-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Jiri Slaby <jslaby@suse.cz>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: live-patching@vger.kernel.org
Link: http://lkml.kernel.org/r/20170725135424.zukjmgpz3plf5pmt@treble
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
arch/x86/Kconfig | 3 +--
arch/x86/Kconfig.debug | 47 ++++++++++++++++++++++++++++++++++++-------
arch/x86/configs/tiny.config | 2 ++
arch/x86/include/asm/unwind.h | 4 ++--
4 files changed, 45 insertions(+), 11 deletions(-)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 7ccf26a..9b30212 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -73,7 +73,6 @@ config X86
select ARCH_USE_QUEUED_RWLOCKS
select ARCH_USE_QUEUED_SPINLOCKS
select ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH
- select ARCH_WANT_FRAME_POINTERS
select ARCH_WANTS_DYNAMIC_TASK_STRUCT
select ARCH_WANTS_THP_SWAP if X86_64
select BUILDTIME_EXTABLE_SORT
@@ -168,7 +167,7 @@ config X86
select HAVE_PERF_REGS
select HAVE_PERF_USER_STACK_DUMP
select HAVE_REGS_AND_STACK_ACCESS_API
- select HAVE_RELIABLE_STACKTRACE if X86_64 && FRAME_POINTER && STACK_VALIDATION
+ select HAVE_RELIABLE_STACKTRACE if X86_64 && FRAME_POINTER_UNWINDER && STACK_VALIDATION
select HAVE_STACK_VALIDATION if X86_64
select HAVE_SYSCALL_TRACEPOINTS
select HAVE_UNSTABLE_SCHED_CLOCK
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
index 268a318..93bbb31 100644
--- a/arch/x86/Kconfig.debug
+++ b/arch/x86/Kconfig.debug
@@ -355,9 +355,32 @@ config PUNIT_ATOM_DEBUG
The current power state can be read from
/sys/kernel/debug/punit_atom/dev_power_state
+choice
+ prompt "Choose kernel unwinder"
+ default FRAME_POINTER_UNWINDER
+ ---help---
+ This determines which method will be used for unwinding kernel stack
+ traces for panics, oopses, bugs, warnings, perf, /proc/<pid>/stack,
+ livepatch, lockdep, and more.
+
+config FRAME_POINTER_UNWINDER
+ bool "Frame pointer unwinder"
+ select FRAME_POINTER
+ ---help---
+ This option enables the frame pointer unwinder for unwinding kernel
+ stack traces.
+
+ The unwinder itself is fast and it uses less RAM than the ORC
+ unwinder, but the kernel text size will grow by ~3% and the kernel's
+ overall performance will degrade by roughly 5-10%.
+
+ This option is recommended if you want to use the livepatch
+ consistency model, as this is currently the only way to get a
+ reliable stack trace (CONFIG_HAVE_RELIABLE_STACKTRACE).
+
config ORC_UNWINDER
bool "ORC unwinder"
- depends on X86_64 && !FRAME_POINTER
+ depends on X86_64
select STACK_VALIDATION
---help---
This option enables the ORC (Oops Rewind Capability) unwinder for
@@ -371,12 +394,22 @@ config ORC_UNWINDER
Enabling this option will increase the kernel's runtime memory usage
by roughly 2-4MB, depending on your kernel config.
-config FRAME_POINTER_UNWINDER
- def_bool y
- depends on !ORC_UNWINDER && FRAME_POINTER
-
config GUESS_UNWINDER
- def_bool y
- depends on !ORC_UNWINDER && !FRAME_POINTER
+ bool "Guess unwinder"
+ depends on EXPERT
+ ---help---
+ This option enables the "guess" unwinder for unwinding kernel stack
+ traces. It scans the stack and reports every kernel text address it
+ finds. Some of the addresses it reports may be incorrect.
+
+ While this option often produces false positives, it can still be
+ useful in many cases. Unlike the other unwinders, it has no runtime
+ overhead.
+
+endchoice
+
+config FRAME_POINTER
+ depends on !ORC_UNWINDER && !GUESS_UNWINDER
+ bool
endmenu
diff --git a/arch/x86/configs/tiny.config b/arch/x86/configs/tiny.config
index 4b429df..550cd50 100644
--- a/arch/x86/configs/tiny.config
+++ b/arch/x86/configs/tiny.config
@@ -1,3 +1,5 @@
CONFIG_NOHIGHMEM=y
# CONFIG_HIGHMEM4G is not set
# CONFIG_HIGHMEM64G is not set
+CONFIG_GUESS_UNWINDER=y
+# CONFIG_FRAME_POINTER_UNWINDER is not set
diff --git a/arch/x86/include/asm/unwind.h b/arch/x86/include/asm/unwind.h
index 25b8d31a..e9f793e 100644
--- a/arch/x86/include/asm/unwind.h
+++ b/arch/x86/include/asm/unwind.h
@@ -16,7 +16,7 @@ struct unwind_state {
bool signal, full_regs;
unsigned long sp, bp, ip;
struct pt_regs *regs;
-#elif defined(CONFIG_FRAME_POINTER)
+#elif defined(CONFIG_FRAME_POINTER_UNWINDER)
bool got_irq;
unsigned long *bp, *orig_sp, ip;
struct pt_regs *regs;
@@ -50,7 +50,7 @@ void unwind_start(struct unwind_state *state, struct task_struct *task,
__unwind_start(state, task, regs, first_frame);
}
-#if defined(CONFIG_ORC_UNWINDER) || defined(CONFIG_FRAME_POINTER)
+#if defined(CONFIG_ORC_UNWINDER) || defined(CONFIG_FRAME_POINTER_UNWINDER)
static inline struct pt_regs *unwind_get_entry_regs(struct unwind_state *state)
{
if (unwind_done(state))
[toc] | [prev] | [next] | [standalone]
| From | tip-bot for Josh Poimboeuf <tipbot@zytor.com> |
|---|---|
| Date | 2017-07-26 14:20 +0200 |
| Subject | [tip:x86/asm] x86/kconfig: Make it easier to switch to the new ORC unwinder |
| Message-ID | <u7tse-aO-5@gated-at.bofh.it> |
| In reply to | #1695268 |
Commit-ID: a34a766ff96d9e88572e35a45066279e40a85d84 Gitweb: http://git.kernel.org/tip/a34a766ff96d9e88572e35a45066279e40a85d84 Author: Josh Poimboeuf <jpoimboe@redhat.com> AuthorDate: Mon, 24 Jul 2017 18:36:58 -0500 Committer: Ingo Molnar <mingo@kernel.org> CommitDate: Wed, 26 Jul 2017 13:18:20 +0200 x86/kconfig: Make it easier to switch to the new ORC unwinder A couple of Kconfig changes which make it much easier to switch to the new CONFIG_ORC_UNWINDER: 1) Remove x86 dependencies on CONFIG_FRAME_POINTER for lockdep, latencytop, and fault injection. x86 has a 'guess' unwinder which just scans the stack for kernel text addresses. It's not 100% accurate but in many cases it's good enough. This allows those users who don't want the text overhead of the frame pointer or ORC unwinders to still use these features. More importantly, this also makes it much more straightforward to disable frame pointers. 2) Make CONFIG_ORC_UNWINDER depend on !CONFIG_FRAME_POINTER. While it would be possible to have both enabled, it doesn't really make sense to do so. So enforce a sane configuration to prevent the user from making a dumb mistake. With these changes, when you disable CONFIG_FRAME_POINTER, "make oldconfig" will ask if you want to enable CONFIG_ORC_UNWINDER. Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com> Cc: Andy Lutomirski <luto@kernel.org> Cc: Borislav Petkov <bp@alien8.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: Denys Vlasenko <dvlasenk@redhat.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Jiri Slaby <jslaby@suse.cz> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Mike Galbraith <efault@gmx.de> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: live-patching@vger.kernel.org Link: http://lkml.kernel.org/r/9985fb91ce5005fe33ea5cc2a20f14bd33c61d03.1500938583.git.jpoimboe@redhat.com Signed-off-by: Ingo Molnar <mingo@kernel.org> --- arch/x86/Kconfig.debug | 7 +++---- lib/Kconfig.debug | 6 +++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index dc10ec6..268a318 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -357,7 +357,7 @@ config PUNIT_ATOM_DEBUG config ORC_UNWINDER bool "ORC unwinder" - depends on X86_64 + depends on X86_64 && !FRAME_POINTER select STACK_VALIDATION ---help--- This option enables the ORC (Oops Rewind Capability) unwinder for @@ -365,9 +365,8 @@ config ORC_UNWINDER a simplified version of the DWARF Call Frame Information standard. This unwinder is more accurate across interrupt entry frames than the - frame pointer unwinder. It can also enable a 5-10% performance - improvement across the entire kernel if CONFIG_FRAME_POINTER is - disabled. + frame pointer unwinder. It also enables a 5-10% performance + improvement across the entire kernel compared to frame pointers. Enabling this option will increase the kernel's runtime memory usage by roughly 2-4MB, depending on your kernel config. diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 0f0d019..32a48e7 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -1124,7 +1124,7 @@ config LOCKDEP bool depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT select STACKTRACE - select FRAME_POINTER if !MIPS && !PPC && !ARM_UNWIND && !S390 && !MICROBLAZE && !ARC && !SCORE + select FRAME_POINTER if !MIPS && !PPC && !ARM_UNWIND && !S390 && !MICROBLAZE && !ARC && !SCORE && !X86 select KALLSYMS select KALLSYMS_ALL @@ -1543,7 +1543,7 @@ config FAULT_INJECTION_STACKTRACE_FILTER depends on FAULT_INJECTION_DEBUG_FS && STACKTRACE_SUPPORT depends on !X86_64 select STACKTRACE - select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND && !ARC && !SCORE + select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND && !ARC && !SCORE && !X86 help Provide stacktrace filter for fault-injection capabilities @@ -1552,7 +1552,7 @@ config LATENCYTOP depends on DEBUG_KERNEL depends on STACKTRACE_SUPPORT depends on PROC_FS - select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND && !ARC + select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND && !ARC && !X86 select KALLSYMS select KALLSYMS_ALL select STACKTRACE
[toc] | [prev] | [next] | [standalone]
| From | "Levin, Alexander (Sasha Levin)" <alexander.levin@verizon.com> |
|---|---|
| Date | 2017-07-28 18:50 +0200 |
| Subject | Re: [PATCH v4 1/2] x86/unwind: add ORC unwinder |
| Message-ID | <u8gCC-6cX-15@gated-at.bofh.it> |
| In reply to | #1695264 |
On Mon, Jul 24, 2017 at 06:36:57PM -0500, Josh Poimboeuf wrote:
>Add a new ORC unwinder which is enabled by CONFIG_ORC_UNWINDER. It
>plugs into the existing x86 unwinder framework.
>
>It relies on objtool to generate the needed .orc_unwind and
>.orc_unwind_ip sections.
>
>For more details on why ORC is used instead of DWARF, see
>Documentation/x86/orc-unwinder.txt.
>
>Thanks to Andy Lutomirski for the performance improvement ideas:
>splitting the ORC unwind table into two parallel arrays and creating a
>fast lookup table to search a subset of the unwind table.
>
>Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Hey Josh,
Syzkaller seems to trigger the following:
==================================================================
BUG: KASAN: stack-out-of-bounds in __read_once_size include/linux/compiler.h:253 [inline]
BUG: KASAN: stack-out-of-bounds in deref_stack_reg+0x123/0x140 arch/x86/kernel/unwind_orc.c:282
Read of size 8 at addr ffff8800374a7b28 by task syz-executor4/6474
CPU: 2 PID: 6474 Comm: syz-executor4 Not tainted 4.13.0-rc2-next-20170727 #232
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.1-1ubuntu1 04/01/2014
Call Trace:
<IRQ>
__dump_stack lib/dump_stack.c:16 [inline]
dump_stack+0xab/0x105 lib/dump_stack.c:52
print_address_description+0xc2/0x250 mm/kasan/report.c:252
kasan_report_error mm/kasan/report.c:351 [inline]
kasan_report+0x24f/0x360 mm/kasan/report.c:408
__read_once_size include/linux/compiler.h:253 [inline]
deref_stack_reg+0x123/0x140 arch/x86/kernel/unwind_orc.c:282
unwind_next_frame+0xd9b/0x1b80 arch/x86/kernel/unwind_orc.c:426
__save_stack_trace+0x7d/0xf0 arch/x86/kernel/stacktrace.c:44
save_stack+0x33/0xa0 mm/kasan/kasan.c:447
set_track mm/kasan/kasan.c:459 [inline]
kasan_slab_free+0x72/0xc0 mm/kasan/kasan.c:524
slab_free_hook mm/slub.c:1357 [inline]
slab_free_freelist_hook mm/slub.c:1379 [inline]
slab_free mm/slub.c:2955 [inline]
kmem_cache_free+0xae/0x310 mm/slub.c:2977
put_pid+0xe2/0x120 kernel/pid.c:246
__rcu_reclaim kernel/rcu/rcu.h:195 [inline]
rcu_do_batch kernel/rcu/tree.c:2666 [inline]
invoke_rcu_callbacks kernel/rcu/tree.c:2920 [inline]
__rcu_process_callbacks kernel/rcu/tree.c:2887 [inline]
rcu_process_callbacks+0x599/0x12b0 kernel/rcu/tree.c:2904
__do_softirq+0x234/0x934 kernel/softirq.c:284
invoke_softirq kernel/softirq.c:364 [inline]
irq_exit+0x164/0x190 kernel/softirq.c:405
exiting_irq arch/x86/include/asm/apic.h:638 [inline]
smp_apic_timer_interrupt+0x71/0x90 arch/x86/kernel/apic/apic.c:1044
apic_timer_interrupt+0xb9/0xc0 arch/x86/entry/entry_64.S:793
</IRQ>
RIP: 0010:arch_local_irq_enable arch/x86/include/asm/paravirt.h:824 [inline]
RIP: 0010:preempt_schedule_irq+0x71/0xd0 kernel/sched/core.c:3579
RSP: 0018:ffff8800374a7958 EFLAGS: 00000246 ORIG_RAX: ffffffffffffff10
RAX: 0000000000000007 RBX: ffffed0006d95808 RCX: 1ffffffff534d022
RDX: 0000000000000000 RSI: ffffffffa7065fe0 RDI: ffff880036cac9a4
RBP: 0000000000000000 R08: ffff88007ffd709c R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000000 R12: ffff880036cac040
R13: 00000000000002eb R14: ffff880036cac040 R15: ffff88005fdc2728
retint_kernel+0x1b/0x2d
RIP: 0010:arch_local_save_flags arch/x86/include/asm/paravirt.h:809 [inline]
RIP: 0010:___might_sleep+0x159/0x480 kernel/sched/core.c:5968
RSP: 0018:ffff8800374a7a28 EFLAGS: 00000246 ORIG_RAX: ffffffffffffff02
RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000001
RDX: 1ffff10006d95882 RSI: 00000000ffffffff RDI: ffff880036cac410
RBP: 0000000000000000 R08: ffffffffa3b1546e R09: dffffc0000000000
R10: ffff8800374a7c08 R11: 0000000000000001 R12: ffffffffa7065320
R13: 00000000000002eb R14: ffff880036cac040 R15: ffff88005fdc2728
ext4_orphan_add+0x34e/0xd70 fs/ext4/namei.c:2801
The buggy address belongs to the page:
page:ffffea0000dd29c0 count:0 mapcount:0 mapping: (null) index:0x0
flags: 0xfffe0000000000()
raw: 00fffe0000000000 0000000000000000 0000000000000000 00000000ffffffff
raw: 0000000000000000 dead000000000200 0000000000000000 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff8800374a7a00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
ffff8800374a7a80: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 f4 f4 f4
>ffff8800374a7b00: f2 f2 f2 f2 00 f4 f4 f4 f2 f2 f2 f2 00 00 00 00
^
ffff8800374a7b80: 00 f4 f4 f4 00 00 00 00 00 00 00 00 00 00 00 00
ffff8800374a7c00: 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00 00
==================================================================
--
Thanks,
Sasha
[toc] | [prev] | [next] | [standalone]
| From | Josh Poimboeuf <jpoimboe@redhat.com> |
|---|---|
| Date | 2017-07-28 20:00 +0200 |
| Subject | Re: [PATCH v4 1/2] x86/unwind: add ORC unwinder |
| Message-ID | <u8hIm-6Ub-19@gated-at.bofh.it> |
| In reply to | #1698944 |
On Fri, Jul 28, 2017 at 04:48:47PM +0000, Levin, Alexander (Sasha Levin) wrote: > Hey Josh, > > Syzkaller seems to trigger the following: > > ================================================================== > BUG: KASAN: stack-out-of-bounds in __read_once_size include/linux/compiler.h:253 [inline] > BUG: KASAN: stack-out-of-bounds in deref_stack_reg+0x123/0x140 arch/x86/kernel/unwind_orc.c:282 > Read of size 8 at addr ffff8800374a7b28 by task syz-executor4/6474 > > CPU: 2 PID: 6474 Comm: syz-executor4 Not tainted 4.13.0-rc2-next-20170727 #232 > Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.1-1ubuntu1 04/01/2014 > Call Trace: > <IRQ> > __dump_stack lib/dump_stack.c:16 [inline] > dump_stack+0xab/0x105 lib/dump_stack.c:52 > print_address_description+0xc2/0x250 mm/kasan/report.c:252 > kasan_report_error mm/kasan/report.c:351 [inline] > kasan_report+0x24f/0x360 mm/kasan/report.c:408 > __read_once_size include/linux/compiler.h:253 [inline] > deref_stack_reg+0x123/0x140 arch/x86/kernel/unwind_orc.c:282 > unwind_next_frame+0xd9b/0x1b80 arch/x86/kernel/unwind_orc.c:426 > __save_stack_trace+0x7d/0xf0 arch/x86/kernel/stacktrace.c:44 > save_stack+0x33/0xa0 mm/kasan/kasan.c:447 > set_track mm/kasan/kasan.c:459 [inline] > kasan_slab_free+0x72/0xc0 mm/kasan/kasan.c:524 > slab_free_hook mm/slub.c:1357 [inline] > slab_free_freelist_hook mm/slub.c:1379 [inline] > slab_free mm/slub.c:2955 [inline] > kmem_cache_free+0xae/0x310 mm/slub.c:2977 > put_pid+0xe2/0x120 kernel/pid.c:246 > __rcu_reclaim kernel/rcu/rcu.h:195 [inline] > rcu_do_batch kernel/rcu/tree.c:2666 [inline] > invoke_rcu_callbacks kernel/rcu/tree.c:2920 [inline] > __rcu_process_callbacks kernel/rcu/tree.c:2887 [inline] > rcu_process_callbacks+0x599/0x12b0 kernel/rcu/tree.c:2904 > __do_softirq+0x234/0x934 kernel/softirq.c:284 > invoke_softirq kernel/softirq.c:364 [inline] > irq_exit+0x164/0x190 kernel/softirq.c:405 > exiting_irq arch/x86/include/asm/apic.h:638 [inline] > smp_apic_timer_interrupt+0x71/0x90 arch/x86/kernel/apic/apic.c:1044 > apic_timer_interrupt+0xb9/0xc0 arch/x86/entry/entry_64.S:793 > </IRQ> > RIP: 0010:arch_local_irq_enable arch/x86/include/asm/paravirt.h:824 [inline] > RIP: 0010:preempt_schedule_irq+0x71/0xd0 kernel/sched/core.c:3579 > RSP: 0018:ffff8800374a7958 EFLAGS: 00000246 ORIG_RAX: ffffffffffffff10 > RAX: 0000000000000007 RBX: ffffed0006d95808 RCX: 1ffffffff534d022 > RDX: 0000000000000000 RSI: ffffffffa7065fe0 RDI: ffff880036cac9a4 > RBP: 0000000000000000 R08: ffff88007ffd709c R09: 0000000000000000 > R10: 0000000000000000 R11: 0000000000000000 R12: ffff880036cac040 > R13: 00000000000002eb R14: ffff880036cac040 R15: ffff88005fdc2728 > retint_kernel+0x1b/0x2d > RIP: 0010:arch_local_save_flags arch/x86/include/asm/paravirt.h:809 [inline] > RIP: 0010:___might_sleep+0x159/0x480 kernel/sched/core.c:5968 > RSP: 0018:ffff8800374a7a28 EFLAGS: 00000246 ORIG_RAX: ffffffffffffff02 > RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000001 > RDX: 1ffff10006d95882 RSI: 00000000ffffffff RDI: ffff880036cac410 > RBP: 0000000000000000 R08: ffffffffa3b1546e R09: dffffc0000000000 > R10: ffff8800374a7c08 R11: 0000000000000001 R12: ffffffffa7065320 > R13: 00000000000002eb R14: ffff880036cac040 R15: ffff88005fdc2728 > ext4_orphan_add+0x34e/0xd70 fs/ext4/namei.c:2801 Thanks for reporting this. I'm confused by the stack trace. It seems to end at ext4_orphan_add, which would normally make sense because the unwinder would have stopped when it read the bad address on the stack. But there aren't any of the '?' entries, which should still be there. Any chance your post-processing script removes those? Can you share the raw dmesg before it was post-processed? -- Josh
[toc] | [prev] | [next] | [standalone]
| From | "Levin, Alexander (Sasha Levin)" <alexander.levin@verizon.com> |
|---|---|
| Date | 2017-07-28 20:40 +0200 |
| Subject | Re: [PATCH v4 1/2] x86/unwind: add ORC unwinder |
| Message-ID | <u8il4-7oj-29@gated-at.bofh.it> |
| In reply to | #1698984 |
On Fri, Jul 28, 2017 at 12:52:34PM -0500, Josh Poimboeuf wrote: >On Fri, Jul 28, 2017 at 04:48:47PM +0000, Levin, Alexander (Sasha Levin) wrote: >> Hey Josh, >> >> Syzkaller seems to trigger the following: >> >> ================================================================== >> BUG: KASAN: stack-out-of-bounds in __read_once_size include/linux/compiler.h:253 [inline] >> BUG: KASAN: stack-out-of-bounds in deref_stack_reg+0x123/0x140 arch/x86/kernel/unwind_orc.c:282 >> Read of size 8 at addr ffff8800374a7b28 by task syz-executor4/6474 >> >> CPU: 2 PID: 6474 Comm: syz-executor4 Not tainted 4.13.0-rc2-next-20170727 #232 >> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.1-1ubuntu1 04/01/2014 >> Call Trace: >> <IRQ> >> __dump_stack lib/dump_stack.c:16 [inline] >> dump_stack+0xab/0x105 lib/dump_stack.c:52 >> print_address_description+0xc2/0x250 mm/kasan/report.c:252 >> kasan_report_error mm/kasan/report.c:351 [inline] >> kasan_report+0x24f/0x360 mm/kasan/report.c:408 >> __read_once_size include/linux/compiler.h:253 [inline] >> deref_stack_reg+0x123/0x140 arch/x86/kernel/unwind_orc.c:282 >> unwind_next_frame+0xd9b/0x1b80 arch/x86/kernel/unwind_orc.c:426 >> __save_stack_trace+0x7d/0xf0 arch/x86/kernel/stacktrace.c:44 >> save_stack+0x33/0xa0 mm/kasan/kasan.c:447 >> set_track mm/kasan/kasan.c:459 [inline] >> kasan_slab_free+0x72/0xc0 mm/kasan/kasan.c:524 >> slab_free_hook mm/slub.c:1357 [inline] >> slab_free_freelist_hook mm/slub.c:1379 [inline] >> slab_free mm/slub.c:2955 [inline] >> kmem_cache_free+0xae/0x310 mm/slub.c:2977 >> put_pid+0xe2/0x120 kernel/pid.c:246 >> __rcu_reclaim kernel/rcu/rcu.h:195 [inline] >> rcu_do_batch kernel/rcu/tree.c:2666 [inline] >> invoke_rcu_callbacks kernel/rcu/tree.c:2920 [inline] >> __rcu_process_callbacks kernel/rcu/tree.c:2887 [inline] >> rcu_process_callbacks+0x599/0x12b0 kernel/rcu/tree.c:2904 >> __do_softirq+0x234/0x934 kernel/softirq.c:284 >> invoke_softirq kernel/softirq.c:364 [inline] >> irq_exit+0x164/0x190 kernel/softirq.c:405 >> exiting_irq arch/x86/include/asm/apic.h:638 [inline] >> smp_apic_timer_interrupt+0x71/0x90 arch/x86/kernel/apic/apic.c:1044 >> apic_timer_interrupt+0xb9/0xc0 arch/x86/entry/entry_64.S:793 >> </IRQ> >> RIP: 0010:arch_local_irq_enable arch/x86/include/asm/paravirt.h:824 [inline] >> RIP: 0010:preempt_schedule_irq+0x71/0xd0 kernel/sched/core.c:3579 >> RSP: 0018:ffff8800374a7958 EFLAGS: 00000246 ORIG_RAX: ffffffffffffff10 >> RAX: 0000000000000007 RBX: ffffed0006d95808 RCX: 1ffffffff534d022 >> RDX: 0000000000000000 RSI: ffffffffa7065fe0 RDI: ffff880036cac9a4 >> RBP: 0000000000000000 R08: ffff88007ffd709c R09: 0000000000000000 >> R10: 0000000000000000 R11: 0000000000000000 R12: ffff880036cac040 >> R13: 00000000000002eb R14: ffff880036cac040 R15: ffff88005fdc2728 >> retint_kernel+0x1b/0x2d >> RIP: 0010:arch_local_save_flags arch/x86/include/asm/paravirt.h:809 [inline] >> RIP: 0010:___might_sleep+0x159/0x480 kernel/sched/core.c:5968 >> RSP: 0018:ffff8800374a7a28 EFLAGS: 00000246 ORIG_RAX: ffffffffffffff02 >> RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000001 >> RDX: 1ffff10006d95882 RSI: 00000000ffffffff RDI: ffff880036cac410 >> RBP: 0000000000000000 R08: ffffffffa3b1546e R09: dffffc0000000000 >> R10: ffff8800374a7c08 R11: 0000000000000001 R12: ffffffffa7065320 >> R13: 00000000000002eb R14: ffff880036cac040 R15: ffff88005fdc2728 >> ext4_orphan_add+0x34e/0xd70 fs/ext4/namei.c:2801 > >Thanks for reporting this. I'm confused by the stack trace. It seems >to end at ext4_orphan_add, which would normally make sense because the >unwinder would have stopped when it read the bad address on the stack. > >But there aren't any of the '?' entries, which should still be there. >Any chance your post-processing script removes those? Can you share the >raw dmesg before it was post-processed? Hey Josh, Sure, here it is: [ 391.851860] ================================================================== [ 391.856663] BUG: KASAN: stack-out-of-bounds in deref_stack_reg+0x123/0x140 [ 391.861469] Read of size 8 at addr ffff8800374a7b28 by task syz-executor4/6474 [ 391.864387] [ 391.864651] CPU: 2 PID: 6474 Comm: syz-executor4 Not tainted 4.13.0-rc2-next-20170727 #232 [ 391.865919] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.1-1ubuntu1 04/01/2014 [ 391.867424] Call Trace: [ 391.867875] <IRQ> [ 391.868269] dump_stack+0xab/0x105 [ 391.868923] print_address_description+0xc2/0x250 [ 391.869843] kasan_report+0x24f/0x360 [ 391.870534] ? deref_stack_reg+0x123/0x140 [ 391.871490] deref_stack_reg+0x123/0x140 [ 391.872239] ? __read_once_size_nocheck.constprop.7+0x10/0x10 [ 391.873289] ? get_stack_info+0x32/0x150 [ 391.874016] ? stack_access_ok+0xd6/0x150 [ 391.874701] ? sched_clock+0x5/0x10 [ 391.875516] ? sched_clock_cpu+0x18/0x1d0 [ 391.877449] unwind_next_frame+0xd9b/0x1b80 [ 391.878149] ? ext4_orphan_add+0x34e/0xd70 [ 391.878798] ? deref_stack_reg+0x140/0x140 [ 391.882077] ? check_preemption_disabled+0x34/0x1f0 [ 391.884084] __save_stack_trace+0x7d/0xf0 [ 391.885471] ? ext4_orphan_add+0x34e/0xd70 [ 391.886123] ? put_pid+0xe2/0x120 [ 391.889839] save_stack+0x33/0xa0 [ 391.890367] ? save_stack+0x33/0xa0 [ 391.890902] ? kasan_slab_free+0x72/0xc0 [ 391.891508] ? kmem_cache_free+0xae/0x310 [ 391.892134] ? put_pid+0xe2/0x120 [ 391.892659] ? rcu_process_callbacks+0x599/0x12b0 [ 391.893791] ? __do_softirq+0x234/0x934 [ 391.894418] ? irq_exit+0x164/0x190 [ 391.894973] ? smp_apic_timer_interrupt+0x71/0x90 [ 391.895705] ? apic_timer_interrupt+0xb9/0xc0 [ 391.896379] ? preempt_schedule_irq+0x71/0xd0 [ 391.897062] ? retint_kernel+0x1b/0x2d [ 391.901512] ? ___might_sleep+0x159/0x480 [ 391.902143] ? ext4_orphan_add+0x34e/0xd70 [ 391.902794] ? mark_held_locks+0xc7/0x110 [ 391.903422] ? check_preemption_disabled+0x34/0x1f0 [ 391.911223] ? trace_hardirqs_on_caller+0x284/0x590 [ 391.911987] ? _raw_spin_unlock_irqrestore+0x41/0x70 [ 391.912771] ? free_object+0xce/0x160 [ 391.913376] ? __debug_check_no_obj_freed+0x400/0x900 [ 391.919901] ? check_preemption_disabled+0x34/0x1f0 [ 391.920664] ? debug_object_free+0x10/0x10 [ 391.921324] ? mark_held_locks+0xc7/0x110 [ 391.921952] ? check_preemption_disabled+0x34/0x1f0 [ 391.922718] kasan_slab_free+0x72/0xc0 [ 391.923314] kmem_cache_free+0xae/0x310 [ 391.923927] put_pid+0xe2/0x120 [ 391.924633] rcu_process_callbacks+0x599/0x12b0 [ 391.928396] ? rcu_exp_wait_wake+0x1100/0x1100 [ 391.929078] ? check_preemption_disabled+0x34/0x1f0 [ 391.929967] __do_softirq+0x234/0x934 [ 391.930867] irq_exit+0x164/0x190 [ 391.931482] smp_apic_timer_interrupt+0x71/0x90 [ 391.934785] apic_timer_interrupt+0xb9/0xc0 [ 391.935393] </IRQ> [ 391.935720] RIP: 0010:preempt_schedule_irq+0x71/0xd0 [ 391.936799] RSP: 0018:ffff8800374a7958 EFLAGS: 00000246 ORIG_RAX: ffffffffffffff10 [ 391.940748] RAX: 0000000000000007 RBX: ffffed0006d95808 RCX: 1ffffffff534d022 [ 391.942554] RDX: 0000000000000000 RSI: ffffffffa7065fe0 RDI: ffff880036cac9a4 [ 391.943536] RBP: 0000000000000000 R08: ffff88007ffd709c R09: 0000000000000000 [ 391.950270] R10: 0000000000000000 R11: 0000000000000000 R12: ffff880036cac040 [ 391.952836] R13: 00000000000002eb R14: ffff880036cac040 R15: ffff88005fdc2728 [ 391.957222] ? preempt_schedule_irq+0x6d/0xd0 [ 391.957915] retint_kernel+0x1b/0x2d [ 391.958483] RIP: 0010:___might_sleep+0x159/0x480 [ 391.959904] RSP: 0018:ffff8800374a7a28 EFLAGS: 00000246 ORIG_RAX: ffffffffffffff02 [ 391.969771] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000001 [ 391.971302] RDX: 1ffff10006d95882 RSI: 00000000ffffffff RDI: ffff880036cac410 [ 391.972390] RBP: 0000000000000000 R08: ffffffffa3b1546e R09: dffffc0000000000 [ 391.973523] R10: ffff8800374a7c08 R11: 0000000000000001 R12: ffffffffa7065320 [ 391.974947] R13: 00000000000002eb R14: ffff880036cac040 R15: ffff88005fdc2728 [ 391.976216] ? ext4_orphan_add+0x34e/0xd70 [ 391.977434] ext4_orphan_add+0x34e/0xd70 [ 391.979303] ? __mutex_lock+0xc7/0x14b0 [ 391.980692] ? ext4_orphan_add+0x34e/0xd70 [ 391.981547] ? mutex_lock_io_nested+0x1350/0x1350 [ 391.982276] ? lock_acquire+0x3a0/0x3a0 [ 391.982884] ? check_preemption_disabled+0x34/0x1f0 [ 391.983655] ? jbd2_write_access_granted.part.7+0x1b9/0x2b0 [ 391.984534] ? jbd2_journal_get_write_access+0x77/0x90 [ 391.990212] ? __ext4_journal_get_write_access+0x117/0x1d0 [ 391.994173] ? ext4_orphan_add+0x34e/0xd70 [ 391.994820] ? ext4_orphan_add+0x34e/0xd70 [ 391.995467] ? ext4_delete_entry+0x25c/0x420 [ 391.996137] ? jbd2__journal_start+0xef/0x8c0 [ 391.996799] ? ext4_empty_dir+0x750/0x750 [ 391.998128] ? __ext4_journal_start_sb+0x100/0x440 [ 391.998873] ? ext4_rmdir+0x432/0xc30 [ 391.999484] ? ext4_rmdir+0x703/0xc30 [ 392.000071] ? ext4_rename2+0x130/0x130 [ 392.000692] ? vfs_rmdir+0x1cd/0x3a0 [ 392.001273] ? do_rmdir+0x39f/0x400 [ 392.001833] ? user_path_create+0x40/0x40 [ 392.002458] ? syscall_trace_enter+0x324/0xe30 [ 392.008656] ? lock_acquire+0x3a0/0x3a0 [ 392.009278] ? exit_to_usermode_loop+0x160/0x160 [ 392.009997] ? check_preemption_disabled+0x34/0x1f0 [ 392.010765] ? check_preemption_disabled+0x34/0x1f0 [ 392.011527] ? SyS_mkdir+0x230/0x230 [ 392.012094] ? do_syscall_64+0x1b0/0x600 [ 392.012718] ? entry_SYSCALL64_slow_path+0x25/0x25 [ 392.013484] [ 392.013734] The buggy address belongs to the page: [ 392.014750] page:ffffea0000dd29c0 count:0 mapcount:0 mapping: (null) index:0x0 [ 392.016276] flags: 0xfffe0000000000() [ 392.016939] raw: 00fffe0000000000 0000000000000000 0000000000000000 00000000ffffffff [ 392.018679] raw: 0000000000000000 dead000000000200 0000000000000000 0000000000000000 [ 392.019881] page dumped because: kasan: bad access detected [ 392.020729] [ 392.020979] Memory state around the buggy address: [ 392.021738] ffff8800374a7a00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 392.022836] ffff8800374a7a80: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 f4 f4 f4 [ 392.023950] >ffff8800374a7b00: f2 f2 f2 f2 00 f4 f4 f4 f2 f2 f2 f2 00 00 00 00 [ 392.025193] ^ [ 392.025890] ffff8800374a7b80: 00 f4 f4 f4 00 00 00 00 00 00 00 00 00 00 00 00 [ 392.026961] ffff8800374a7c00: 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00 00 [ 392.028049] ================================================================== [ 392.029713] Disabling lock debugging due to kernel taint [ 392.030551] Kernel panic - not syncing: panic_on_warn set ... [ 392.030551] [ 392.031651] CPU: 2 PID: 6474 Comm: syz-executor4 Tainted: G B 4.13.0-rc2-next-20170727 #232 [ 392.033060] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.1-1ubuntu1 04/01/2014 [ 392.034399] Call Trace: [ 392.034785] <IRQ> [ 392.035115] dump_stack+0xab/0x105 [ 392.035649] panic+0x1bc/0x3ba [ 392.036306] ? __warn+0x1d6/0x1d6 [ 392.036836] kasan_end_report+0x4a/0x50 [ 392.037438] kasan_report+0x168/0x360 [ 392.038004] ? deref_stack_reg+0x123/0x140 [ 392.038581] deref_stack_reg+0x123/0x140 [ 392.039161] ? __read_once_size_nocheck.constprop.7+0x10/0x10 [ 392.040072] ? get_stack_info+0x32/0x150 [ 392.040895] ? stack_access_ok+0xd6/0x150 [ 392.041764] ? sched_clock+0x5/0x10 [ 392.042346] ? sched_clock_cpu+0x18/0x1d0 [ 392.043076] unwind_next_frame+0xd9b/0x1b80 [ 392.043776] ? ext4_orphan_add+0x34e/0xd70 [ 392.044425] ? deref_stack_reg+0x140/0x140 [ 392.045073] ? check_preemption_disabled+0x34/0x1f0 [ 392.045833] __save_stack_trace+0x7d/0xf0 [ 392.047297] ? ext4_orphan_add+0x34e/0xd70 [ 392.047932] ? put_pid+0xe2/0x120 [ 392.048447] save_stack+0x33/0xa0 [ 392.048986] ? save_stack+0x33/0xa0 [ 392.049564] ? kasan_slab_free+0x72/0xc0 [ 392.050171] ? kmem_cache_free+0xae/0x310 [ 392.050792] ? put_pid+0xe2/0x120 [ 392.051650] ? rcu_process_callbacks+0x599/0x12b0 [ 392.052357] ? __do_softirq+0x234/0x934 [ 392.052948] ? irq_exit+0x164/0x190 [ 392.053523] ? smp_apic_timer_interrupt+0x71/0x90 [ 392.054273] ? apic_timer_interrupt+0xb9/0xc0 [ 392.054951] ? preempt_schedule_irq+0x71/0xd0 [ 392.055594] ? retint_kernel+0x1b/0x2d [ 392.056168] ? ___might_sleep+0x159/0x480 [ 392.056784] ? ext4_orphan_add+0x34e/0xd70 [ 392.057442] ? mark_held_locks+0xc7/0x110 [ 392.058235] ? check_preemption_disabled+0x34/0x1f0 [ 392.058979] ? trace_hardirqs_on_caller+0x284/0x590 [ 392.059730] ? _raw_spin_unlock_irqrestore+0x41/0x70 [ 392.060486] ? free_object+0xce/0x160 [ 392.060997] ? __debug_check_no_obj_freed+0x400/0x900 [ 392.061905] ? check_preemption_disabled+0x34/0x1f0 [ 392.062763] ? debug_object_free+0x10/0x10 [ 392.063334] ? mark_held_locks+0xc7/0x110 [ 392.063914] ? check_preemption_disabled+0x34/0x1f0 [ 392.064764] kasan_slab_free+0x72/0xc0 [ 392.065451] kmem_cache_free+0xae/0x310 [ 392.066139] put_pid+0xe2/0x120 [ 392.066723] rcu_process_callbacks+0x599/0x12b0 [ 392.067532] ? rcu_exp_wait_wake+0x1100/0x1100 [ 392.068293] ? check_preemption_disabled+0x34/0x1f0 [ 392.069231] __do_softirq+0x234/0x934 [ 392.069760] irq_exit+0x164/0x190 [ 392.070270] smp_apic_timer_interrupt+0x71/0x90 [ 392.070978] apic_timer_interrupt+0xb9/0xc0 [ 392.071614] </IRQ> [ 392.072152] RIP: 0010:preempt_schedule_irq+0x71/0xd0 [ 392.072903] RSP: 0018:ffff8800374a7958 EFLAGS: 00000246 ORIG_RAX: ffffffffffffff10 [ 392.074336] RAX: 0000000000000007 RBX: ffffed0006d95808 RCX: 1ffffffff534d022 [ 392.075285] RDX: 0000000000000000 RSI: ffffffffa7065fe0 RDI: ffff880036cac9a4 [ 392.076235] RBP: 0000000000000000 R08: ffff88007ffd709c R09: 0000000000000000 [ 392.077204] R10: 0000000000000000 R11: 0000000000000000 R12: ffff880036cac040 [ 392.078271] R13: 00000000000002eb R14: ffff880036cac040 R15: ffff88005fdc2728 [ 392.080105] ? preempt_schedule_irq+0x6d/0xd0 [ 392.080882] retint_kernel+0x1b/0x2d [ 392.081563] RIP: 0010:___might_sleep+0x159/0x480 [ 392.082364] RSP: 0018:ffff8800374a7a28 EFLAGS: 00000246 ORIG_RAX: ffffffffffffff02 [ 392.083604] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000001 [ 392.084879] RDX: 1ffff10006d95882 RSI: 00000000ffffffff RDI: ffff880036cac410 [ 392.085967] RBP: 0000000000000000 R08: ffffffffa3b1546e R09: dffffc0000000000 [ 392.087029] R10: ffff8800374a7c08 R11: 0000000000000001 R12: ffffffffa7065320 [ 392.088090] R13: 00000000000002eb R14: ffff880036cac040 R15: ffff88005fdc2728 [ 392.089199] ? ext4_orphan_add+0x34e/0xd70 [ 392.089833] ext4_orphan_add+0x34e/0xd70 [ 392.090441] ? __mutex_lock+0xc7/0x14b0 [ 392.091197] ? ext4_orphan_add+0x34e/0xd70 [ 392.091833] ? mutex_lock_io_nested+0x1350/0x1350 [ 392.092550] ? lock_acquire+0x3a0/0x3a0 [ 392.093153] ? check_preemption_disabled+0x34/0x1f0 [ 392.093917] ? jbd2_write_access_granted.part.7+0x1b9/0x2b0 [ 392.094774] ? jbd2_journal_get_write_access+0x77/0x90 [ 392.095946] ? __ext4_journal_get_write_access+0x117/0x1d0 [ 392.096785] ? ext4_orphan_add+0x34e/0xd70 [ 392.097431] ? ext4_orphan_add+0x34e/0xd70 [ 392.098063] ? ext4_delete_entry+0x25c/0x420 [ 392.098934] ? jbd2__journal_start+0xef/0x8c0 [ 392.099602] ? ext4_empty_dir+0x750/0x750 [ 392.100233] ? __ext4_journal_start_sb+0x100/0x440 [ 392.100964] ? ext4_rmdir+0x432/0xc30 [ 392.101561] ? ext4_rmdir+0x703/0xc30 [ 392.102303] ? ext4_rename2+0x130/0x130 [ 392.102906] ? vfs_rmdir+0x1cd/0x3a0 [ 392.103460] ? do_rmdir+0x39f/0x400 [ 392.104097] ? user_path_create+0x40/0x40 [ 392.104806] ? syscall_trace_enter+0x324/0xe30 [ 392.105812] ? lock_acquire+0x3a0/0x3a0 [ 392.106684] ? exit_to_usermode_loop+0x160/0x160 [ 392.107501] ? check_preemption_disabled+0x34/0x1f0 [ 392.108299] ? check_preemption_disabled+0x34/0x1f0 [ 392.110963] ? SyS_mkdir+0x230/0x230 [ 392.111521] ? do_syscall_64+0x1b0/0x600 [ 392.112154] ? entry_SYSCALL64_slow_path+0x25/0x25 [ 392.113310] Dumping ftrace buffer: [ 392.113849] (ftrace buffer empty) [ 392.114400] Kernel Offset: 0x22200000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff) [ 392.116033] Rebooting in 86400 seconds.. -- Thanks, Sasha
[toc] | [prev] | [next] | [standalone]
| From | Josh Poimboeuf <jpoimboe@redhat.com> |
|---|---|
| Date | 2017-07-28 21:00 +0200 |
| Subject | Re: [PATCH v4 1/2] x86/unwind: add ORC unwinder |
| Message-ID | <u8iEq-7vB-23@gated-at.bofh.it> |
| In reply to | #1699014 |
On Fri, Jul 28, 2017 at 06:29:57PM +0000, Levin, Alexander (Sasha Levin) wrote: > On Fri, Jul 28, 2017 at 12:52:34PM -0500, Josh Poimboeuf wrote: > >On Fri, Jul 28, 2017 at 04:48:47PM +0000, Levin, Alexander (Sasha Levin) wrote: > >> Hey Josh, > >> > >> Syzkaller seems to trigger the following: > >> > >> ================================================================== > >> BUG: KASAN: stack-out-of-bounds in __read_once_size include/linux/compiler.h:253 [inline] > >> BUG: KASAN: stack-out-of-bounds in deref_stack_reg+0x123/0x140 arch/x86/kernel/unwind_orc.c:282 > >> Read of size 8 at addr ffff8800374a7b28 by task syz-executor4/6474 > >> > >> CPU: 2 PID: 6474 Comm: syz-executor4 Not tainted 4.13.0-rc2-next-20170727 #232 > >> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.1-1ubuntu1 04/01/2014 > >> Call Trace: > >> <IRQ> > >> __dump_stack lib/dump_stack.c:16 [inline] > >> dump_stack+0xab/0x105 lib/dump_stack.c:52 > >> print_address_description+0xc2/0x250 mm/kasan/report.c:252 > >> kasan_report_error mm/kasan/report.c:351 [inline] > >> kasan_report+0x24f/0x360 mm/kasan/report.c:408 > >> __read_once_size include/linux/compiler.h:253 [inline] > >> deref_stack_reg+0x123/0x140 arch/x86/kernel/unwind_orc.c:282 > >> unwind_next_frame+0xd9b/0x1b80 arch/x86/kernel/unwind_orc.c:426 > >> __save_stack_trace+0x7d/0xf0 arch/x86/kernel/stacktrace.c:44 > >> save_stack+0x33/0xa0 mm/kasan/kasan.c:447 > >> set_track mm/kasan/kasan.c:459 [inline] > >> kasan_slab_free+0x72/0xc0 mm/kasan/kasan.c:524 > >> slab_free_hook mm/slub.c:1357 [inline] > >> slab_free_freelist_hook mm/slub.c:1379 [inline] > >> slab_free mm/slub.c:2955 [inline] > >> kmem_cache_free+0xae/0x310 mm/slub.c:2977 > >> put_pid+0xe2/0x120 kernel/pid.c:246 > >> __rcu_reclaim kernel/rcu/rcu.h:195 [inline] > >> rcu_do_batch kernel/rcu/tree.c:2666 [inline] > >> invoke_rcu_callbacks kernel/rcu/tree.c:2920 [inline] > >> __rcu_process_callbacks kernel/rcu/tree.c:2887 [inline] > >> rcu_process_callbacks+0x599/0x12b0 kernel/rcu/tree.c:2904 > >> __do_softirq+0x234/0x934 kernel/softirq.c:284 > >> invoke_softirq kernel/softirq.c:364 [inline] > >> irq_exit+0x164/0x190 kernel/softirq.c:405 > >> exiting_irq arch/x86/include/asm/apic.h:638 [inline] > >> smp_apic_timer_interrupt+0x71/0x90 arch/x86/kernel/apic/apic.c:1044 > >> apic_timer_interrupt+0xb9/0xc0 arch/x86/entry/entry_64.S:793 > >> </IRQ> > >> RIP: 0010:arch_local_irq_enable arch/x86/include/asm/paravirt.h:824 [inline] > >> RIP: 0010:preempt_schedule_irq+0x71/0xd0 kernel/sched/core.c:3579 > >> RSP: 0018:ffff8800374a7958 EFLAGS: 00000246 ORIG_RAX: ffffffffffffff10 > >> RAX: 0000000000000007 RBX: ffffed0006d95808 RCX: 1ffffffff534d022 > >> RDX: 0000000000000000 RSI: ffffffffa7065fe0 RDI: ffff880036cac9a4 > >> RBP: 0000000000000000 R08: ffff88007ffd709c R09: 0000000000000000 > >> R10: 0000000000000000 R11: 0000000000000000 R12: ffff880036cac040 > >> R13: 00000000000002eb R14: ffff880036cac040 R15: ffff88005fdc2728 > >> retint_kernel+0x1b/0x2d > >> RIP: 0010:arch_local_save_flags arch/x86/include/asm/paravirt.h:809 [inline] > >> RIP: 0010:___might_sleep+0x159/0x480 kernel/sched/core.c:5968 > >> RSP: 0018:ffff8800374a7a28 EFLAGS: 00000246 ORIG_RAX: ffffffffffffff02 > >> RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000001 > >> RDX: 1ffff10006d95882 RSI: 00000000ffffffff RDI: ffff880036cac410 > >> RBP: 0000000000000000 R08: ffffffffa3b1546e R09: dffffc0000000000 > >> R10: ffff8800374a7c08 R11: 0000000000000001 R12: ffffffffa7065320 > >> R13: 00000000000002eb R14: ffff880036cac040 R15: ffff88005fdc2728 > >> ext4_orphan_add+0x34e/0xd70 fs/ext4/namei.c:2801 > > > >Thanks for reporting this. I'm confused by the stack trace. It seems > >to end at ext4_orphan_add, which would normally make sense because the > >unwinder would have stopped when it read the bad address on the stack. > > > >But there aren't any of the '?' entries, which should still be there. > >Any chance your post-processing script removes those? Can you share the > >raw dmesg before it was post-processed? > > Hey Josh, > > Sure, here it is: Thanks, that's much better. I'm relieved the unwinder didn't screw that up, at least. This looks like a tricky one. Is it easily recreatable? Any chance you'd be able to share the vmlinux file somehow? If not, at least the .config file, GCC version, and code level would be useful so I can try to build a similar image. -- Josh
[toc] | [prev] | [next] | [standalone]
| From | Josh Poimboeuf <jpoimboe@redhat.com> |
|---|---|
| Date | 2017-07-29 06:00 +0200 |
| Subject | Re: [PATCH v4 1/2] x86/unwind: add ORC unwinder |
| Message-ID | <u8r50-4Yt-7@gated-at.bofh.it> |
| In reply to | #1699028 |
On Fri, Jul 28, 2017 at 07:59:12PM +0000, Levin, Alexander (Sasha Levin) wrote:
> On Fri, Jul 28, 2017 at 01:57:20PM -0500, Josh Poimboeuf wrote:
> >Thanks, that's much better. I'm relieved the unwinder didn't screw that
> >up, at least.
> >
> >This looks like a tricky one. Is it easily recreatable?
>
> Yeah, I just hit it again with slightly different initial calls:
Sasha sent me some data privately. As I suspected, the cause is some
bad ORC data. Objtool incorrectly assumes that once the frame pointer
is set up, it no longer gets touched.
For example:
ffffffff81820680 <pipe_wait>:
ffffffff81820680: 41 56 push %r14
ffffffff81820682: 41 55 push %r13
ffffffff81820684: 41 54 push %r12
ffffffff81820686: 49 89 fc mov %rdi,%r12
ffffffff81820689: 55 push %rbp
ffffffff8182068a: 53 push %rbx
ffffffff8182068b: 48 bb 00 00 00 00 00 movabs $0xdffffc0000000000,%rbx
ffffffff81820692: fc ff df
ffffffff81820695: 48 83 c4 80 add $0xffffffffffffff80,%rsp
ffffffff81820699: 48 89 e5 mov %rsp,%rbp
ffffffff8182069c: 48 c7 04 24 b3 8a b5 movq $0x41b58ab3,(%rsp)
ffffffff818206a3: 41
ffffffff818206a4: 48 c7 44 24 08 07 a5 movq $0xffffffff8621a507,0x8(%rsp)
ffffffff818206ab: 21 86
ffffffff818206a9: R_X86_64_32S .rodata+0xa1a507
ffffffff818206ad: 48 c1 ed 03 shr $0x3,%rbp
In this case, rbp was pushed ("push %rbp") and then replaced with rsp
("mov %rsp, %rbp"), which is the normal frame pointer setup. But then
rbp was modified ("shr 0x3, %rbp"), which objtool didn't expect.
Objtool will need to be made smarter here somehow. I'll be on vacation
next week so it might be a week or so before I can come up with the fix.
Despite the scary KASAN warning, this is only a minor bug. The ORC data
isn't perfect yet, so these types of issues will happen until we get the
kinks worked out. The good news is the unwinder recovered from the bad
ORC data gracefully, and the oops dump still showed the rest of the
addresses (with question marks).
--
Josh
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web