arm: the kernel backtrace follows a zero stack word to NULL and faults - #643
Open
cyclistmass wants to merge 1 commit into
Open
cyclistmass wants to merge 1 commit into
cyclistmass wants to merge 1 commit into
Conversation
walk_stack_frames follows a non-frame stack word as a pointer in two of its arms. Zero satisfies `(header & fixnummask) == 0', and a control stack is full of zero words, so next became NULL and lisp_frame_p(NULL) dereferenced address 0. The backtrace printer died inside the crash it was reporting. advance_or_stop() accepts a candidate only when start < candidate <= end, and otherwise ends the walk with a diagnostic naming the value it rejected. Also here: the "Bad frame!" line printed a pointer with %x, which truncates to 32 bits on a 64-bit target; it is now %p.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
walk_stack_framesfollows a non-frame stack word as a pointer in two arms:Zero satisfies
(header & fixnummask) == 0, and a control stack holds many zerowords.
nextbecomes NULL,start = nextstill passeswhile (start < end),and
lisp_frame_p(NULL)dereferences address 0.So the printer faults while it prints the backtrace for another fault, and it
loses the report that would identify the original defect. Any small fixnum does
the same at a different address, and a candidate below
startwalks backwards.The right test is not "does this word carry a fixnum tag" but "is this a
forward address inside the region under walk".
advance_or_stopaccepts a candidateonly when
start < candidate <= end. Anything else ends the walk with adiagnostic, because a truncated backtrace beats a SIGSEGV in the debugger.
A core dump shows it.
startenters as0xffff829fc1f0, and reaches the callas
0x0:The "Bad frame!" line also printed a pointer with
%x, which truncates to 32bits on a 64-bit target. It now uses
%p.albt.cbuilds for androidarm, darwinarm, darwinarm64, linuxarm and linuxarm64,and links into the shipped kernel, so the defect is live for ARM32 as well.
I verified this on linuxarm64, using the command
make -n albt.oprints ratherthan one I guessed. Both files compile clean,
albt.ogrows from 25896 to 29176bytes, and the patch adds no warning. I watched two positive controls fail.
I have not linked and booted a kernel with this change, and I did not reproduce
the fault on demand.