From 4429334ea61864ea8d2636e2daadc1e05967552d Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Fri, 7 Oct 2022 09:55:59 +0200 Subject: parser_bison: display too many levels of nesting error Instead of hitting this assertion: nft: parser_bison.y:70: open_scope: Assertion `state->scope < array_size(state->scopes) - 1' failed. Aborted this is easier to trigger with implicit chains where one level of nesting from the existing chain scope is supported. Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1615 Signed-off-by: Pablo Neira Ayuso --- include/parser.h | 1 + src/parser_bison.y | 27 +++++++++++++++++++++++---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/include/parser.h b/include/parser.h index 2fb037cb..f55da0fd 100644 --- a/include/parser.h +++ b/include/parser.h @@ -22,6 +22,7 @@ struct parser_state { struct scope *scopes[SCOPE_NEST_MAX]; unsigned int scope; + bool scope_err; unsigned int flex_state_pop; unsigned int startcond_type; diff --git a/src/parser_bison.y b/src/parser_bison.y index 0266819a..760c23cf 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -65,15 +65,26 @@ static struct scope *current_scope(const struct parser_state *state) return state->scopes[state->scope]; } -static void open_scope(struct parser_state *state, struct scope *scope) +static int open_scope(struct parser_state *state, struct scope *scope) { - assert(state->scope < array_size(state->scopes) - 1); + if (state->scope >= array_size(state->scopes) - 1) { + state->scope_err = true; + return -1; + } + scope_init(scope, current_scope(state)); state->scopes[++state->scope] = scope; + + return 0; } static void close_scope(struct parser_state *state) { + if (state->scope_err) { + state->scope_err = false; + return; + } + assert(state->scope > 0); state->scope--; } @@ -1674,7 +1685,11 @@ describe_cmd : primary_expr table_block_alloc : /* empty */ { $$ = table_alloc(); - open_scope(state, &$$->scope); + if (open_scope(state, &$$->scope) < 0) { + erec_queue(error(&@$, "too many levels of nesting"), + state->msgs); + state->nerrs++; + } } ; @@ -1836,7 +1851,11 @@ table_block : /* empty */ { $$ = $-1; } chain_block_alloc : /* empty */ { $$ = chain_alloc(NULL); - open_scope(state, &$$->scope); + if (open_scope(state, &$$->scope) < 0) { + erec_queue(error(&@$, "too many levels of nesting"), + state->msgs); + state->nerrs++; + } } ; -- cgit v1.2.3