Restrict total recursion number of `ecall()`; fix #3789

parent afd46ecc
...@@ -267,7 +267,8 @@ typedef struct mrb_state { ...@@ -267,7 +267,8 @@ typedef struct mrb_state {
#else #else
mrb_atexit_func *atexit_stack; mrb_atexit_func *atexit_stack;
#endif #endif
mrb_int atexit_stack_len; uint16_t atexit_stack_len;
uint16_t ecall_nest; /* prevent infinite recursive ecall() */
} mrb_state; } mrb_state;
/** /**
......
...@@ -55,7 +55,7 @@ void abort(void); ...@@ -55,7 +55,7 @@ void abort(void);
/* Maximum depth of ecall() recursion. */ /* Maximum depth of ecall() recursion. */
#ifndef MRB_ECALL_DEPTH_MAX #ifndef MRB_ECALL_DEPTH_MAX
#define MRB_ECALL_DEPTH_MAX 32 #define MRB_ECALL_DEPTH_MAX 512
#endif #endif
/* Maximum stack depth. Should be set lower on memory constrained systems. /* Maximum stack depth. Should be set lower on memory constrained systems.
...@@ -337,7 +337,8 @@ ecall(mrb_state *mrb) ...@@ -337,7 +337,8 @@ ecall(mrb_state *mrb)
int nregs; int nregs;
if (i<0) return; if (i<0) return;
if (ci - c->cibase > MRB_ECALL_DEPTH_MAX) { /* restrict total call depth of ecall() */
if (++mrb->ecall_nest > MRB_ECALL_DEPTH_MAX) {
mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
} }
p = c->ensure[i]; p = c->ensure[i];
...@@ -372,6 +373,7 @@ ecall(mrb_state *mrb) ...@@ -372,6 +373,7 @@ ecall(mrb_state *mrb)
c->ci = c->cibase + cioff; c->ci = c->cibase + cioff;
if (!mrb->exc) mrb->exc = exc; if (!mrb->exc) mrb->exc = exc;
mrb_gc_arena_restore(mrb, ai); mrb_gc_arena_restore(mrb, ai);
mrb->ecall_nest--;
} }
#ifndef MRB_FUNCALL_ARGC_MAX #ifndef MRB_FUNCALL_ARGC_MAX
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment