This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

FYI unwinder unwinder limits


Hi Mark,

just implemented the discussed simple execution limits.

The diff here is made with -b|--ignore-space-change.


Jan

diff --git a/libdwfl/frame_unwind.c b/libdwfl/frame_unwind.c
index a875e98..94213e5 100644
--- a/libdwfl/frame_unwind.c
+++ b/libdwfl/frame_unwind.c
@@ -36,6 +36,13 @@
 #include "../libdw/dwarf.h"
 #include <sys/ptrace.h>
 
+/* Maximum number of DWARF expression stack slots before returning an error.  */
+#define DWARF_EXPR_STACK_MAX 0x100
+
+/* Maximum number of DWARF expression executed operations before returning an
+   error.  */
+#define DWARF_EXPR_STEPS_MAX 0x1000
+
 #ifndef MAX
 # define MAX(a, b) ((a) > (b) ? (a) : (b))
 #endif
@@ -90,7 +97,6 @@ bra_compar (const void *key_voidp, const void *elem_voidp)
 
 /* If FRAME is NULL is are computing CFI frame base.  In such case another
    DW_OP_call_frame_cfa is no longer permitted.  */
-/* FIXME: Handle bytecode deadlocks and overflows.  */
 
 static bool
 expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
@@ -108,6 +114,11 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
   bool
   push (Dwarf_Addr val)
   {
+    if (stack_used >= DWARF_EXPR_STACK_MAX)
+      {
+	__libdwfl_seterrno (DWFL_E_INVALID_DWARF);
+	return false;
+      }
     if (stack_used == stack_allocated)
       {
 	stack_allocated = MAX (stack_allocated * 2, 32);
@@ -137,7 +148,14 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
 
   Dwarf_Addr val1, val2;
   bool is_location = false;
+  size_t steps_count = 0;
   for (const Dwarf_Op *op = ops; op < ops + nops; op++)
+    {
+      if (++steps_count > DWARF_EXPR_STEPS_MAX)
+	{
+	  __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
+	  return false;
+	}
       switch (op->atom)
       {
 	/* DW_OP_* order matches libgcc/unwind-dw2.c execute_stack_op:  */
@@ -447,6 +465,7 @@ expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
 	  __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
 	  return false;
       }
+    }
   if (! pop (result))
     {
       free (stack);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]