From 78dffb470fcf7b1c0b1b3d6f43fcc056c337a808 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Fri, 8 Dec 2023 19:41:39 +0100 Subject: parser_bison: fix objref statement corruption Consider this: counter_stmt : counter_stmt_alloc | counter_stmt_alloc counter_args counter_stmt_alloc : COUNTER { $$ = counter_stmt_alloc(&@$); } | COUNTER NAME stmt_expr { $$ = objref_stmt_alloc(&@$); $$->objref.type = NFT_OBJECT_COUNTER; $$->objref.expr = $3; } ; counter_args : counter_arg { $$ = $0; } | counter_args counter_arg ; counter_arg : PACKETS NUM { $0->counter.packets = $2; } [..] This has 'counter_stmt_alloc' EITHER return counter or objref statement. Both are the same structure but with different (union'd) trailer content. counter_stmt permits the 'packet' and 'byte' argument. But the 'counter_arg' directive only works with a statement coming from counter_stmt_alloc(). afl++ came up with following input: table inet x { chain y { counter name ip saddr bytes 1.1.1. 1024 } } This clobbers $->objref.expr pointer, we then crash when calling expr_evaluate() on it. Split the objref related statements into their own directive. After this, the input will fail with: "syntax error, unexpected bytes, expecting newline or semicolon". Also split most of the other objref statements into their own blocks. synproxy seems to have same problem, limit and quota appeared to be ok. v1 added objref_stmt to stateful_stmt list, this is wrong, we will assert when generating the 'counter' statement. Place it in the normal statement list so netlink_gen_stmt_stateful_assert throws the expected parser error. Fixes: dccab4f646b4 ("parser_bison: consolidate stmt_expr rule") Signed-off-by: Florian Westphal --- tests/shell/testcases/bogons/nft-f/counter_objref_crash | 5 +++++ tests/shell/testcases/bogons/nft-f/netlink_gen_stmt_stateful_assert | 6 ++++++ 2 files changed, 11 insertions(+) create mode 100644 tests/shell/testcases/bogons/nft-f/counter_objref_crash create mode 100644 tests/shell/testcases/bogons/nft-f/netlink_gen_stmt_stateful_assert (limited to 'tests') diff --git a/tests/shell/testcases/bogons/nft-f/counter_objref_crash b/tests/shell/testcases/bogons/nft-f/counter_objref_crash new file mode 100644 index 00000000..3a4b981b --- /dev/null +++ b/tests/shell/testcases/bogons/nft-f/counter_objref_crash @@ -0,0 +1,5 @@ +table inet x { + chain y { + counter name ip saddr bytes 1.1.1. 1024 + } +} diff --git a/tests/shell/testcases/bogons/nft-f/netlink_gen_stmt_stateful_assert b/tests/shell/testcases/bogons/nft-f/netlink_gen_stmt_stateful_assert new file mode 100644 index 00000000..547b937f --- /dev/null +++ b/tests/shell/testcases/bogons/nft-f/netlink_gen_stmt_stateful_assert @@ -0,0 +1,6 @@ +table ip x { + map sctm_o1 { + type mark : counter + counter name meta mark + } +} -- cgit v1.2.3