scripts/decodecode: add the capability to supply the program counter

So that comparing with objdump output from vmlinux can ease pinpointing
where the trapping instruction actually is.  An example is better than a
thousand words:

  $ PC=0xffffffff8329a927 ./scripts/decodecode < ~/tmp/syz/gfs2.splat
  [ 477.379104][T23917] Code: 48 83 ec 28 48 89 3c 24 48 89 54 24 08 e8 c1 b4 4a fe 48 8d bb 00 01 00 00 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 <80> 3c 02 00 0f 85 97 05 00 00 48 8b 9b 00 01 00 00 48 85 db 0f 84
  All code
  ========
  ffffffff8329a8fd:       48 83 ec 28             sub    $0x28,%rsp
  ffffffff8329a901:       48 89 3c 24             mov    %rdi,(%rsp)
  ffffffff8329a905:       48 89 54 24 08          mov    %rdx,0x8(%rsp)
  ffffffff8329a90a:       e8 c1 b4 4a fe          callq  0xffffffff81745dd0
  ffffffff8329a90f:       48 8d bb 00 01 00 00    lea    0x100(%rbx),%rdi
  ffffffff8329a916:       48 b8 00 00 00 00 00    movabs $0xdffffc0000000000,%rax
  ffffffff8329a91d:       fc ff df
  ffffffff8329a920:       48 89 fa                mov    %rdi,%rdx
  ffffffff8329a923:       48 c1 ea 03             shr    $0x3,%rdx
  ffffffff8329a927:*      80 3c 02 00             cmpb   $0x0,(%rdx,%rax,1)               <-- trapping instruction
  ffffffff8329a92b:       0f 85 97 05 00 00       jne    0xffffffff8329aec8
  ffffffff8329a931:       48 8b 9b 00 01 00 00    mov    0x100(%rbx),%rbx
  ffffffff8329a938:       48 85 db                test   %rbx,%rbx
  ffffffff8329a93b:       0f                      .byte 0xf
  ffffffff8329a93c:       84                      .byte 0x84

Signed-off-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Cc: Marc Zyngier <maz@misterjones.org>
Cc: Will Deacon <will@kernel.org>
Cc: Rabin Vincent <rabin@rab.in>
Link: https://lkml.kernel.org/r/20200930111416.GF6810@zn.tnic
Link: https://lkml.kernel.org/r/20200929113238.GC21110@zn.tnic
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Borislav Petkov 2020-10-13 16:48:14 -07:00 committed by Linus Torvalds
parent 33c5bb375e
commit d72e720a19

View File

@ -6,6 +6,7 @@
# options: set env. variable AFLAGS=options to pass options to "as"; # options: set env. variable AFLAGS=options to pass options to "as";
# e.g., to decode an i386 oops on an x86_64 system, use: # e.g., to decode an i386 oops on an x86_64 system, use:
# AFLAGS=--32 decodecode < 386.oops # AFLAGS=--32 decodecode < 386.oops
# PC=hex - the PC (program counter) the oops points to
cleanup() { cleanup() {
rm -f $T $T.s $T.o $T.oo $T.aa $T.dis rm -f $T $T.s $T.o $T.oo $T.aa $T.dis
@ -67,15 +68,19 @@ if [ -z "$ARCH" ]; then
esac esac
fi fi
# Params: (tmp_file, pc_sub)
disas() { disas() {
${CROSS_COMPILE}as $AFLAGS -o $1.o $1.s > /dev/null 2>&1 t=$1
pc_sub=$2
${CROSS_COMPILE}as $AFLAGS -o $t.o $t.s > /dev/null 2>&1
if [ "$ARCH" = "arm" ]; then if [ "$ARCH" = "arm" ]; then
if [ $width -eq 2 ]; then if [ $width -eq 2 ]; then
OBJDUMPFLAGS="-M force-thumb" OBJDUMPFLAGS="-M force-thumb"
fi fi
${CROSS_COMPILE}strip $1.o ${CROSS_COMPILE}strip $t.o
fi fi
if [ "$ARCH" = "arm64" ]; then if [ "$ARCH" = "arm64" ]; then
@ -83,11 +88,18 @@ disas() {
type=inst type=inst
fi fi
${CROSS_COMPILE}strip $1.o ${CROSS_COMPILE}strip $t.o
fi fi
${CROSS_COMPILE}objdump $OBJDUMPFLAGS -S $1.o | \ if [ $pc_sub -ne 0 ]; then
grep -v "/tmp\|Disassembly\|\.text\|^$" > $1.dis 2>&1 if [ $PC ]; then
adj_vma=$(( $PC - $pc_sub ))
OBJDUMPFLAGS="$OBJDUMPFLAGS --adjust-vma=$adj_vma"
fi
fi
${CROSS_COMPILE}objdump $OBJDUMPFLAGS -S $t.o | \
grep -v "/tmp\|Disassembly\|\.text\|^$" > $t.dis 2>&1
} }
marker=`expr index "$code" "\<"` marker=`expr index "$code" "\<"`
@ -95,14 +107,17 @@ if [ $marker -eq 0 ]; then
marker=`expr index "$code" "\("` marker=`expr index "$code" "\("`
fi fi
touch $T.oo touch $T.oo
if [ $marker -ne 0 ]; then if [ $marker -ne 0 ]; then
# 2 opcode bytes and a single space
pc_sub=$(( $marker / 3 ))
echo All code >> $T.oo echo All code >> $T.oo
echo ======== >> $T.oo echo ======== >> $T.oo
beforemark=`echo "$code"` beforemark=`echo "$code"`
echo -n " .$type 0x" > $T.s echo -n " .$type 0x" > $T.s
echo $beforemark | sed -e 's/ /,0x/g; s/[<>()]//g' >> $T.s echo $beforemark | sed -e 's/ /,0x/g; s/[<>()]//g' >> $T.s
disas $T disas $T $pc_sub
cat $T.dis >> $T.oo cat $T.dis >> $T.oo
rm -f $T.o $T.s $T.dis rm -f $T.o $T.s $T.dis
@ -114,7 +129,7 @@ echo =========================================== >> $T.aa
code=`echo $code | sed -e 's/ [<(]/ /;s/[>)] / /;s/ /,0x/g; s/[>)]$//'` code=`echo $code | sed -e 's/ [<(]/ /;s/[>)] / /;s/ /,0x/g; s/[>)]$//'`
echo -n " .$type 0x" > $T.s echo -n " .$type 0x" > $T.s
echo $code >> $T.s echo $code >> $T.s
disas $T disas $T 0
cat $T.dis >> $T.aa cat $T.dis >> $T.aa
# (lines of whole $T.oo) - (lines of $T.aa, i.e. "Code starting") + 3, # (lines of whole $T.oo) - (lines of $T.aa, i.e. "Code starting") + 3,