--- Begin Message ---
libdwfl/
2014-01-03 Jan Kratochvil <[email protected]>
Detect infinite backtraces.
* dwfl_frame.c (state_alloc): Initialize CFA.
* frame_unwind.c (expr_eval): Remove parameter frame, add parameter
elfclass. Move elfclass to handle_cfi. Replace recursive call by
state->unwound->CFA.
(new_unwound): Initialize CFA.
(handle_cfi): Move elfclass here. Compute CFA. Update expr_eval
caller parameters.
* libdwflP.h (DWFL_ERRORS): Add UNWIND_BAD_CFA.
(struct Dwfl_Frame): Add field cfa.
tests/
2014-01-03 Jan Kratochvil <[email protected]>
* Makefile.am (TESTS): Add run-cfaloop.sh.
(EXTRA_DIST): Add run-cfaloop.sh, testfilecfaloop.S,
testfilecfaloop.bz2, testfilecfaloop.c and testfilecfaloop.core.bz2.
* run-cfaloop.sh: New file.
* testfilecfaloop.S: New file.
* testfilecfaloop.bz2: New file.
* testfilecfaloop.c: New file.
* testfilecfaloop.core.bz2: New file.
Signed-off-by: Jan Kratochvil <[email protected]>
---
libdwfl/dwfl_frame.c | 3 +-
libdwfl/frame_unwind.c | 46 ++++++++++++++-------
libdwfl/libdwflP.h | 7 +++-
tests/Makefile.am | 8 ++--
tests/run-cfaloop.sh | 22 ++++++++++
tests/testfilecfaloop.S | 90 +++++++++++++++++++++++++++++++++++++++++
tests/testfilecfaloop.bz2 | Bin 0 -> 640 bytes
tests/testfilecfaloop.c | 22 ++++++++++
tests/testfilecfaloop.core.bz2 | Bin 0 -> 5765 bytes
9 files changed, 177 insertions(+), 21 deletions(-)
create mode 100755 tests/run-cfaloop.sh
create mode 100644 tests/testfilecfaloop.S
create mode 100644 tests/testfilecfaloop.bz2
create mode 100644 tests/testfilecfaloop.c
create mode 100644 tests/testfilecfaloop.core.bz2
diff --git a/libdwfl/dwfl_frame.c b/libdwfl/dwfl_frame.c
index 28008e9..89fd920 100644
--- a/libdwfl/dwfl_frame.c
+++ b/libdwfl/dwfl_frame.c
@@ -1,5 +1,5 @@
/* Get Dwarf Frame state for target PID or core file.
- Copyright (C) 2013 Red Hat, Inc.
+ Copyright (C) 2013-2014 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -98,6 +98,7 @@ state_alloc (Dwfl_Thread *thread)
state->thread = thread;
state->signal_frame = false;
state->initial_frame = true;
+ state->cfa = 0;
state->pc_state = DWFL_FRAME_STATE_ERROR;
memset (state->regs_set, 0, sizeof (state->regs_set));
thread->unwound = state;
diff --git a/libdwfl/frame_unwind.c b/libdwfl/frame_unwind.c
index 3ce4547..d434c46 100644
--- a/libdwfl/frame_unwind.c
+++ b/libdwfl/frame_unwind.c
@@ -1,5 +1,5 @@
/* Get previous frame state for an existing frame state.
- Copyright (C) 2013 Red Hat, Inc.
+ Copyright (C) 2013-2014 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -105,8 +105,8 @@ bra_compar (const void *key_voidp, const void *elem_voidp)
DW_OP_call_frame_cfa is no longer permitted. */
static bool
-expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
- size_t nops, Dwarf_Addr *result, Dwarf_Addr bias)
+expr_eval (Dwfl_Frame *state, const Dwarf_Op *ops, size_t nops,
+ Dwarf_Addr *result, Dwarf_Addr bias, const int elfclass)
{
Dwfl_Process *process = state->thread->process;
if (nops == 0)
@@ -310,7 +310,6 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const
Dwarf_Op *ops,
}
if (op->atom == DW_OP_deref_size)
{
- const int elfclass = frame->cache->e_ident[EI_CLASS];
const unsigned addr_bytes = elfclass == ELFCLASS32 ? 4 : 8;
if (op->number > addr_bytes)
{
@@ -450,16 +449,15 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const
Dwarf_Op *ops,
break;
/* DW_OP_* not listed in libgcc/unwind-dw2.c execute_stack_op: */
case DW_OP_call_frame_cfa:;
- // Not used by CFI itself but it is synthetized by elfutils
internation.
- Dwarf_Op *cfa_ops;
- size_t cfa_nops;
- Dwarf_Addr cfa;
- if (frame == NULL
- || dwarf_frame_cfa (frame, &cfa_ops, &cfa_nops) != 0
- || ! expr_eval (state, NULL, cfa_ops, cfa_nops, &cfa, bias)
- || ! push (cfa))
- {
- __libdwfl_seterrno (DWFL_E_LIBDW);
+ if (state->unwound->cfa == 0)
+ {
+ /* DW_OP_call_frame_cfa is needed to compute CFA itself. */
+ free (stack);
+ __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
+ return false;
+ }
+ if (! push (state->unwound->cfa))
+ {
free (stack);
return false;
}
@@ -510,6 +508,7 @@ new_unwound (Dwfl_Frame *state)
unwound->unwound = NULL;
unwound->signal_frame = false;
unwound->initial_frame = false;
+ unwound->cfa = 0;
unwound->pc_state = DWFL_FRAME_STATE_ERROR;
memset (unwound->regs_set, 0, sizeof (unwound->regs_set));
}
@@ -536,12 +535,29 @@ handle_cfi (Dwfl_Frame *state, Dwarf_Addr pc, Dwarf_CFI
*cfi, Dwarf_Addr bias)
Ebl *ebl = process->ebl;
size_t nregs = ebl_frame_nregs (ebl);
assert (nregs > 0);
+ const int elfclass = frame->cache->e_ident[EI_CLASS];
/* The return register is special for setting the unwound->pc_state. */
unsigned ra = frame->fde->cie->return_address_register;
bool ra_set = false;
ebl_dwarf_to_regno (ebl, &ra);
+ // Set unwound->CFA.
+ Dwarf_Op *cfa_ops;
+ size_t cfa_nops;
+ if (dwarf_frame_cfa (frame, &cfa_ops, &cfa_nops) != 0
+ || ! expr_eval (state, cfa_ops, cfa_nops, &unwound->cfa, bias, elfclass))
+ {
+ __libdwfl_seterrno (DWFL_E_LIBDW);
+ return;
+ }
+ if (unwound->cfa == 0
+ || (! state->initial_frame && unwound->cfa <= state->cfa))
+ {
+ __libdwfl_seterrno (DWFL_E_UNWIND_BAD_CFA);
+ return;
+ }
+
for (unsigned regno = 0; regno < nregs; regno++)
{
Dwarf_Op reg_ops_mem[3], *reg_ops;
@@ -574,7 +590,7 @@ handle_cfi (Dwfl_Frame *state, Dwarf_Addr pc, Dwarf_CFI
*cfi, Dwarf_Addr bias)
continue;
}
}
- else if (! expr_eval (state, frame, reg_ops, reg_nops, ®val, bias))
+ else if (! expr_eval (state, reg_ops, reg_nops, ®val, bias, elfclass))
{
/* PPC32 vDSO has various invalid operations, ignore them. The
register will look as unset causing an error later, if used.
diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h
index 63615a8..5f6bbcd 100644
--- a/libdwfl/libdwflP.h
+++ b/libdwfl/libdwflP.h
@@ -1,5 +1,5 @@
/* Internal definitions for libdwfl.
- Copyright (C) 2005-2013 Red Hat, Inc.
+ Copyright (C) 2005-2014 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -89,7 +89,8 @@ typedef struct Dwfl_Process Dwfl_Process;
DWFL_ERROR (ATTACH_STATE_CONFLICT, N_("Dwfl already has attached state")) \
DWFL_ERROR (NO_ATTACH_STATE, N_("Dwfl has no attached state")) \
DWFL_ERROR (NO_UNWIND, N_("Unwinding not supported for this architecture")) \
- DWFL_ERROR (INVALID_ARGUMENT, N_("Invalid argument"))
+ DWFL_ERROR (INVALID_ARGUMENT, N_("Invalid argument"))
\
+ DWFL_ERROR (UNWIND_BAD_CFA, N_("Unwind not monotonous (corrupt stack?)"))
#define DWFL_ERROR(name, text) DWFL_E_##name,
typedef enum { DWFL_ERRORS DWFL_E_NUM } Dwfl_Error;
@@ -241,6 +242,8 @@ struct Dwfl_Frame
Dwfl_Frame *unwound;
bool signal_frame : 1;
bool initial_frame : 1;
+ /* Used to catch infinite unwinding. */
+ Dwarf_Addr cfa;
enum
{
/* This structure is still being initialized or there was an error
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 52eb50a..ac83d9c 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,6 +1,6 @@
## Process this file with automake to create Makefile.in
##
-## Copyright (C) 1996-2013 Red Hat, Inc.
+## Copyright (C) 1996-2014 Red Hat, Inc.
## This file is part of elfutils.
##
## This file is free software; you can redistribute it and/or modify
@@ -107,7 +107,7 @@ TESTS = run-arextract.sh run-arsymtest.sh newfile
test-nlist \
run-backtrace-native-biarch.sh run-backtrace-native-core.sh \
run-backtrace-native-core-biarch.sh run-backtrace-core-x86_64.sh \
run-backtrace-core-i386.sh run-backtrace-core-ppc.sh \
- run-backtrace-core-s390x.sh run-backtrace-core-s390.sh
+ run-backtrace-core-s390x.sh run-backtrace-core-s390.sh run-cfaloop.sh
if !BIARCH
export ELFUTILS_DISABLE_BIARCH = 1
@@ -256,7 +256,9 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \
run-backtrace-core-ppc.sh testfile66.bz2 testfile66.core.bz2 \
backtrace.s390x.core.bz2 backtrace.s390x.exec.bz2 \
backtrace.s390.core.bz2 backtrace.s390.exec.bz2 \
- run-backtrace-core-s390x.sh run-backtrace-core-s390.sh
+ run-backtrace-core-s390x.sh run-backtrace-core-s390.sh \
+ run-cfaloop.sh testfilecfaloop.S testfilecfaloop.bz2 \
+ testfilecfaloop.c testfilecfaloop.core.bz2
if USE_VALGRIND
valgrind_cmd='valgrind -q --error-exitcode=1 --run-libc-freeres=no'
diff --git a/tests/run-cfaloop.sh b/tests/run-cfaloop.sh
new file mode 100755
index 0000000..afad5db
--- /dev/null
+++ b/tests/run-cfaloop.sh
@@ -0,0 +1,22 @@
+#! /bin/bash
+# Copyright (C) 2014 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfilecfaloop testfilecfaloop.core
+testrun ${abs_top_builddir}/src/stack -e testfilecfaloop
--core=testfilecfaloop.core 2>&1 \
+ | grep -q 'Unwind not monotonous'
diff --git a/tests/testfilecfaloop.S b/tests/testfilecfaloop.S
new file mode 100644
index 0000000..f4108a2
--- /dev/null
+++ b/tests/testfilecfaloop.S
@@ -0,0 +1,90 @@
+/* Test program for run-cfaloop.sh.
+ Copyright (C) 2014 Red Hat, Inc.
+ This file is part of elfutils.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+ .file "testfilecfaloop.c"
+ .text
+ .p2align 4,,15
+ .globl _start
+ .type _start, @function
+_start:
+.LFB0:
+# BLOCK 2 freq:10000 seq:0
+# PRED: ENTRY [100.0%] (FALLTHRU)
+ movq $0, -8(%rsp)
+ movq -8(%rsp), %rax
+ movl $0, (%rax)
+# SUCC: EXIT [100.0%]
+ ret
+.LFE0:
+ .size _start, .-_start
+#APP
+ .section .eh_frame,"a",@progbits
+.Lframe1:
+ .long .LECIE1-.LSCIE1 # Length of Common Information Entry
+.LSCIE1:
+ .long 0 # CIE Identifier Tag
+ .byte 0x3 # CIE Version
+ .ascii "zR\0" # CIE Augmentation
+ .uleb128 0x1 # CIE Code Alignment Factor
+ .sleb128 -8 # CIE Data Alignment Factor
+ .uleb128 0x10 # CIE RA Column
+ .uleb128 0x1 # Augmentation size
+ .byte 0x3 # FDE Encoding (udata4)
+ .byte 0xc # DW_CFA_def_cfa
+ .uleb128 0x7
+ .uleb128 0x8
+ .byte 0x90 # DW_CFA_offset, column 0x10
+ .uleb128 0x1
+ .align 8
+.LECIE1:
+.LSFDE1:
+ .long .LEFDE1-.LASFDE1 # FDE Length
+.LASFDE1:
+ .long .LASFDE1-.Lframe1 # FDE CIE offset
+ .long .LFB0 # FDE initial location
+ .long .LFE0-.LFB0 # FDE address range
+ .uleb128 0 # Augmentation size
+// BEGIN inserted data { DW_CFA_same_value + ULEB128 register }
+#define REG(n) \
+ .byte 0x8; \
+ .uleb128 n;
+REG(0)
+REG(1)
+REG(2)
+REG(3)
+REG(4)
+REG(5)
+REG(6)
+REG(7)
+REG(8)
+REG(9)
+REG(10)
+REG(11)
+REG(12)
+REG(13)
+REG(14)
+REG(15)
+REG(16)
+ .byte 0xc # DW_CFA_def_cfa
+ .uleb128 0x7
+ .uleb128 0x0
+// END inserted data
+ .align 8
+.LEFDE1:
+#NO_APP
+ .ident "GCC: (GNU) 4.8.2 20131212 (Red Hat 4.8.2-7)"
+ .section .note.GNU-stack,"",@progbits
diff --git a/tests/testfilecfaloop.bz2 b/tests/testfilecfaloop.bz2
new file mode 100644
index
0000000000000000000000000000000000000000..ab30fcd07f4d76bbdf6a1b3f5ec49a7dacf6d921
GIT binary patch
literal 640
zcmV-`0)PENT4*^jL0KkKSphLXJpcjcfB*mg{@hjPeA!>sazOv*-f+MOKwv-s1Yrok
zKmY<jU_`(H^LJT?Ts1TiJq0}oVq|D&18NO401X;xrV~M?fXHHLlR=`R)jdY^O{n!T
zG>tM14@scN834osKm$gDO*F^=(?v~2$kfvlLqGsD$&)64G-;p!WY7kh8UO|<H9*m|
z8flTEA*Pxb5M%=;gF{0=&;v~X#52E==z<>x!9+4ikd=&TmWU9Bo54(GL?j4+)v;VQ
za8=L3X<LeJX~$plYXNVBMRU2`DwLm*fLDwVn39A6P0L~!1RQZmCR~7^B1@Y=ra_8W
zI$w~jHN{{M1XLj?79fZyY^%gb;6&*-!b(IDly)3&q#&XntdvLqh&Do%c|C?rG7QSa
zKnEfw1uB1Od2kT<#LCZ{UbBTr-))c_7vXI%k97YbkdQAObfCcNTGq9V1a&PmIhE=K
zDn0^)V-TWDAtN7E5rc~Y@SuudpK^*|6(X9LZ0Wio<$Ct#FE$X!rwRD`bs{?Yyikw<
zAtSReLWLbBv`8Z)nmC0Dn!kxDpRma7QxO?D6oaC#NSgjl6~J3!J7YvumcpHGEYZ9^
zZ8&YxFrG^ls5@GKhH+ixq)s~nzA`Ul0|Z1lf=Tw7uBlgU)JXDzeOvY%^KeCj07D={
z@x^-ttKfv;n0vcsd<#_p#hGl=GkKx1`na&0Wc9?7d{(eYQ0^oI#&n!|8$pL)qVmLo
zRqN?d-&>44a#{?BL}q)|BEEpld_a(58$$qkiqd7fA=Jo^eMm%|KDbtR5q{fWvl_v!
att%KHfp|NFJ<h-G3%MekC`bU9pdNrUKoB7S
literal 0
HcmV?d00001
diff --git a/tests/testfilecfaloop.c b/tests/testfilecfaloop.c
new file mode 100644
index 0000000..14a2fca
--- /dev/null
+++ b/tests/testfilecfaloop.c
@@ -0,0 +1,22 @@
+/* Test program for run-cfaloop.sh.
+ Copyright (C) 2014 Red Hat, Inc.
+ This file is part of elfutils.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+// gcc -o testfilecfaloop.S testfilecfaloop.c -Wall -O2 -dA
-fno-dwarf2-cfi-asm -nostdlib -S
+void _start(void) {
+ volatile int *volatile p = 0;
+ *p = 0;
+}
diff --git a/tests/testfilecfaloop.core.bz2 b/tests/testfilecfaloop.core.bz2
new file mode 100644
index
0000000000000000000000000000000000000000..923d5e566200df60988e5880dcc2c268adbef4eb
GIT binary patch
literal 5765
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
D=5F$~
literal 0
HcmV?d00001
--
1.8.4.2
--- End Message ---