[PATCH] awk: fix stack overflow in evaluate()
Sanghyun Park via busybox <[email protected]> Tue, 16 Jun 2026 12:16:05 +0900
| Newsgroups | gmane.linux.busybox |
|---|---|
| Message-ID | <[email protected]> |
Recursive awk functions can keep re-entering evaluate() until the process stack is exhausted. Track active function-call depth and report a normal awk error once the limit is reached instead of overflowing the stack. Signed-off-by: Sanghyun Park <[email protected]> --- editors/awk.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/editors/awk.c b/editors/awk.c index dd8f4ac..f15832b 100644 --- a/editors/awk.c +++ b/editors/awk.c @@ -633,6 +633,7 @@ struct globals { smalluint exitcode; unsigned evaluate__seed; + unsigned evaluate__func_depth; var *evaluate__fnargs; regex_t evaluate__sreg; @@ -703,6 +704,7 @@ static const char EMSG_UNEXP_TOKEN[] ALIGN1 = "Unexpected token"; static const char EMSG_DIV_BY_ZERO[] ALIGN1 = "Division by zero"; static const char EMSG_INV_FMT[] ALIGN1 = "Invalid format specifier"; static const char EMSG_TOO_FEW_ARGS[] ALIGN1 = "Too few arguments"; +static const char EMSG_RECURSION[] ALIGN1 = "Recursion limit exceeded"; static const char EMSG_NOT_ARRAY[] ALIGN1 = "Not an array"; static const char EMSG_POSSIBLE_ERROR[] ALIGN1 = "Possible syntax error"; static const char EMSG_UNDEF_FUNC[] ALIGN1 = "Call to undefined function"; @@ -2988,6 +2990,7 @@ static var *evaluate(node *op, var *res) #define fnargs (G.evaluate__fnargs) /* seed is initialized to 1 */ #define seed (G.evaluate__seed) +#define func_depth (G.evaluate__func_depth) #define sreg (G.evaluate__sreg) var *tmpvars; @@ -3299,13 +3302,17 @@ static var *evaluate(node *op, var *res) var *argvars, *sv_fnargs; const char *sv_progname; int nargs, i; + enum { MAX_AWK_FUNC_DEPTH = 1000 }; debug_printf_eval("FUNC\n"); if (!op->r.f->defined) syntax_error(EMSG_UNDEF_FUNC); + if (func_depth >= MAX_AWK_FUNC_DEPTH) + syntax_error(EMSG_RECURSION); /* The body might be empty, still has to eval the args */ + func_depth++; nargs = op->r.f->nargs; argvars = nvalloc(nargs); i = 0; @@ -3333,6 +3340,7 @@ static var *evaluate(node *op, var *res) g_progname = sv_progname; fnargs = sv_fnargs; + func_depth--; break; } @@ -3690,6 +3698,7 @@ static var *evaluate(node *op, var *res) return res; #undef fnargs #undef seed +#undef func_depth #undef sreg } -- 2.48.1