]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
parser_bison: Fix for ECN keyword in LHS of relational
authorPhil Sutter <phil@nwl.cc>
Fri, 24 Aug 2018 11:26:57 +0000 (13:26 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Thu, 4 Oct 2018 00:11:17 +0000 (02:11 +0200)
Of all possible TCP flags, 'ecn' is special since it is recognized by
lex as a keyword (there is a a field in IPv4 and IPv6 headers with the
same name). Therefore it is listed in keyword_expr, but that was
sufficient for RHS only. The following statement reproduces the issue:

| tcp flags & (syn | ecn) == (syn | ecn)

The solution is to limit binop expressions to accept an RHS expression
on RHS ("real" LHS expressions don't make much sense there anyway),
which then allows keyword_expr to occur there. In order to maintain the
recursive behaviour if braces are present, allow primary_rhs_expr to
consist of a basic_rhs_expr enclosed in braces. This in turn requires
for braced RHS part in relational_expr to be dropped, otherwise bison
complains about shift/reduce conflict.

Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
src/parser_bison.y
tests/py/inet/tcp.t
tests/py/inet/tcp.t.json
tests/py/inet/tcp.t.json.output
tests/py/inet/tcp.t.payload

index 831090b66e8ec45a267c0c3484f667cde17418c3..c9189e9c145e394a4e287e9732135492e64043e0 100644 (file)
@@ -3119,32 +3119,32 @@ osf_expr                :       OSF     NAME
                        ;
 
 shift_expr             :       primary_expr
-                       |       shift_expr              LSHIFT          primary_expr
+                       |       shift_expr              LSHIFT          primary_rhs_expr
                        {
                                $$ = binop_expr_alloc(&@$, OP_LSHIFT, $1, $3);
                        }
-                       |       shift_expr              RSHIFT          primary_expr
+                       |       shift_expr              RSHIFT          primary_rhs_expr
                        {
                                $$ = binop_expr_alloc(&@$, OP_RSHIFT, $1, $3);
                        }
                        ;
 
 and_expr               :       shift_expr
-                       |       and_expr                AMPERSAND       shift_expr
+                       |       and_expr                AMPERSAND       shift_rhs_expr
                        {
                                $$ = binop_expr_alloc(&@$, OP_AND, $1, $3);
                        }
                        ;
 
 exclusive_or_expr      :       and_expr
-                       |       exclusive_or_expr       CARET           and_expr
+                       |       exclusive_or_expr       CARET           and_rhs_expr
                        {
                                $$ = binop_expr_alloc(&@$, OP_XOR, $1, $3);
                        }
                        ;
 
 inclusive_or_expr      :       exclusive_or_expr
-                       |       inclusive_or_expr       '|'             exclusive_or_expr
+                       |       inclusive_or_expr       '|'             exclusive_or_rhs_expr
                        {
                                $$ = binop_expr_alloc(&@$, OP_OR, $1, $3);
                        }
@@ -3473,10 +3473,6 @@ relational_expr          :       expr    /* implicit */  rhs_expr
                        {
                                $$ = relational_expr_alloc(&@2, $2, $1, $3);
                        }
-                       |       expr    relational_op   '(' rhs_expr ')'
-                       {
-                               $$ = relational_expr_alloc(&@2, $2, $1, $4);
-                       }
                        ;
 
 list_rhs_expr          :       basic_rhs_expr          COMMA           basic_rhs_expr
@@ -3660,6 +3656,7 @@ primary_rhs_expr  :       symbol_expr             { $$ = $1; }
                                                         BYTEORDER_HOST_ENDIAN,
                                                         sizeof(data) * BITS_PER_BYTE, &data);
                        }
+                       |       '('     basic_rhs_expr  ')'     { $$ = $2; }
                        ;
 
 relational_op          :       EQ              { $$ = OP_EQ; }
index d66ba8438a32f9d44ea53c6f156ee34f88c0305d..f96e3634f41ed5ce1ea3f8048fe3384a0e74fd0c 100644 (file)
@@ -78,6 +78,7 @@ tcp flags cwr;ok
 tcp flags != cwr;ok
 tcp flags == syn;ok
 tcp flags & (syn|fin) == (syn|fin);ok;tcp flags & (fin | syn) == fin | syn
+tcp flags & (fin | syn | rst | psh | ack | urg | ecn | cwr) == fin | syn | rst | psh | ack | urg | ecn | cwr;ok;tcp flags == 0xff
 
 tcp window 22222;ok
 tcp window 22;ok
index 5744e5942eb12644a7b8c0da8952198bec152123..babe5920892592ce8b336ee36eb1b1a5965151a6 100644 (file)
     }
 ]
 
+# tcp flags & (fin | syn | rst | psh | ack | urg | ecn | cwr) == fin | syn | rst | psh | ack | urg | ecn | cwr
+[
+    {
+        "match": {
+            "left": {
+                "&": [
+                    {
+                        "payload": {
+                            "field": "flags",
+                            "protocol": "tcp"
+                        }
+                    },
+                    {
+                        "|": [ "fin", { "|": [ "syn", { "|": [ "rst", { "|": [ "psh", { "|": [ "ack", { "|": [ "urg", { "|": [ "ecn", "cwr" ] } ] } ] } ] } ] } ] } ]
+                    }
+                ]
+            },
+            "op": "==",
+            "right": { "|": [ "fin", { "|": [ "syn", { "|": [ "rst", { "|": [ "psh", { "|": [ "ack", { "|": [ "urg", { "|": [ "ecn", "cwr" ] } ] } ] } ] } ] } ] } ] }
+        }
+    }
+]
+
 # tcp window 22222
 [
     {
index 50282ec530080e440176c782778b188a09e279df..143490f7322d29b1c48ef4bca8bfb89e42778608 100644 (file)
     }
 ]
 
+# tcp flags & (fin | syn | rst | psh | ack | urg | ecn | cwr) == fin | syn | rst | psh | ack | urg | ecn | cwr
+[
+    {
+        "match": {
+            "left": {
+                "payload": {
+                    "field": "flags",
+                    "protocol": "tcp"
+                }
+            },
+            "op": "==",
+            "right": 255
+        }
+    }
+]
+
index 09538aed746c9a11278e8fb4e63110386245b103..2390a24ead15c3e2d47c9a9d50370ebbbb68c26c 100644 (file)
@@ -436,6 +436,14 @@ inet test-inet input
   [ bitwise reg 1 = (reg=1 & 0x00000003 ) ^ 0x00000000 ]
   [ cmp eq reg 1 0x00000003 ]
 
+# tcp flags & (fin | syn | rst | psh | ack | urg | ecn | cwr) == fin | syn | rst | psh | ack | urg | ecn | cwr
+inet test-inet input
+  [ meta load l4proto => reg 1 ]
+  [ cmp eq reg 1 0x00000006 ]
+  [ payload load 1b @ transport header + 13 => reg 1 ]
+  [ bitwise reg 1 = (reg=1 & 0x000000ff ) ^ 0x00000000 ]
+  [ cmp eq reg 1 0x000000ff ]
+
 # tcp window 22222
 inet test-inet input
   [ meta load l4proto => reg 1 ]