diff mbox series

[nft,1/2] parser_bison: display too many levels of nesting error

Message ID 20221007082430.333046-1-pablo@netfilter.org
State Accepted
Delegated to: Pablo Neira
Headers show
Series [nft,1/2] parser_bison: display too many levels of nesting error | expand

Commit Message

Pablo Neira Ayuso Oct. 7, 2022, 8:24 a.m. UTC
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 <pablo@netfilter.org>
---
 include/parser.h   |  1 +
 src/parser_bison.y | 27 +++++++++++++++++++++++----
 2 files changed, 24 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/include/parser.h b/include/parser.h
index 2fb037cb8470..f55da0fd47bf 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 0266819a779b..760c23cf3322 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 */	{ $$ = $<table>-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++;
+				}
 			}
 			;