Blame SOURCES/0026-parser_bison-Fix-for-ECN-keyword-in-LHS-of-relationa.patch

9ff721
From 64b101f4a124f39b494dc5906159a8890568d1f9 Mon Sep 17 00:00:00 2001
9ff721
From: Phil Sutter <phil@nwl.cc>
9ff721
Date: Fri, 24 Aug 2018 13:26:57 +0200
9ff721
Subject: [PATCH] parser_bison: Fix for ECN keyword in LHS of relational
9ff721
9ff721
Of all possible TCP flags, 'ecn' is special since it is recognized by
9ff721
lex as a keyword (there is a a field in IPv4 and IPv6 headers with the
9ff721
same name). Therefore it is listed in keyword_expr, but that was
9ff721
sufficient for RHS only. The following statement reproduces the issue:
9ff721
9ff721
| tcp flags & (syn | ecn) == (syn | ecn)
9ff721
9ff721
The solution is to limit binop expressions to accept an RHS expression
9ff721
on RHS ("real" LHS expressions don't make much sense there anyway),
9ff721
which then allows keyword_expr to occur there. In order to maintain the
9ff721
recursive behaviour if braces are present, allow primary_rhs_expr to
9ff721
consist of a basic_rhs_expr enclosed in braces. This in turn requires
9ff721
for braced RHS part in relational_expr to be dropped, otherwise bison
9ff721
complains about shift/reduce conflict.
9ff721
9ff721
Signed-off-by: Phil Sutter <phil@nwl.cc>
9ff721
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
9ff721
(cherry picked from commit 14a9968a56f8b35138bab172aa7ce796f5d98e03)
9ff721
Signed-off-by: Phil Sutter <psutter@redhat.com>
9ff721
---
9ff721
 src/parser_bison.y              | 15 ++++++---------
9ff721
 tests/py/inet/tcp.t             |  1 +
9ff721
 tests/py/inet/tcp.t.json        | 23 +++++++++++++++++++++++
9ff721
 tests/py/inet/tcp.t.json.output | 16 ++++++++++++++++
9ff721
 tests/py/inet/tcp.t.payload     |  8 ++++++++
9ff721
 5 files changed, 54 insertions(+), 9 deletions(-)
9ff721
9ff721
diff --git a/src/parser_bison.y b/src/parser_bison.y
9ff721
index d75cd50fa29b9..a6b6fc1745a72 100644
9ff721
--- a/src/parser_bison.y
9ff721
+++ b/src/parser_bison.y
9ff721
@@ -2948,32 +2948,32 @@ fib_tuple		:  	fib_flag	DOT	fib_tuple
9ff721
 			;
9ff721
 
9ff721
 shift_expr		:	primary_expr
9ff721
-			|	shift_expr		LSHIFT		primary_expr
9ff721
+			|	shift_expr		LSHIFT		primary_rhs_expr
9ff721
 			{
9ff721
 				$$ = binop_expr_alloc(&@$, OP_LSHIFT, $1, $3);
9ff721
 			}
9ff721
-			|	shift_expr		RSHIFT		primary_expr
9ff721
+			|	shift_expr		RSHIFT		primary_rhs_expr
9ff721
 			{
9ff721
 				$$ = binop_expr_alloc(&@$, OP_RSHIFT, $1, $3);
9ff721
 			}
9ff721
 			;
9ff721
 
9ff721
 and_expr		:	shift_expr
9ff721
-			|	and_expr		AMPERSAND	shift_expr
9ff721
+			|	and_expr		AMPERSAND	shift_rhs_expr
9ff721
 			{
9ff721
 				$$ = binop_expr_alloc(&@$, OP_AND, $1, $3);
9ff721
 			}
9ff721
 			;
9ff721
 
9ff721
 exclusive_or_expr	:	and_expr
9ff721
-			|	exclusive_or_expr	CARET		and_expr
9ff721
+			|	exclusive_or_expr	CARET		and_rhs_expr
9ff721
 			{
9ff721
 				$$ = binop_expr_alloc(&@$, OP_XOR, $1, $3);
9ff721
 			}
9ff721
 			;
9ff721
 
9ff721
 inclusive_or_expr	:	exclusive_or_expr
9ff721
-			|	inclusive_or_expr	'|'		exclusive_or_expr
9ff721
+			|	inclusive_or_expr	'|'		exclusive_or_rhs_expr
9ff721
 			{
9ff721
 				$$ = binop_expr_alloc(&@$, OP_OR, $1, $3);
9ff721
 			}
9ff721
@@ -3252,10 +3252,6 @@ relational_expr		:	expr	/* implicit */	rhs_expr
9ff721
 			{
9ff721
 				$$ = relational_expr_alloc(&@2, $2, $1, $3);
9ff721
 			}
9ff721
-			|	expr	relational_op	'(' rhs_expr ')'
9ff721
-			{
9ff721
-				$$ = relational_expr_alloc(&@2, $2, $1, $4);
9ff721
-			}
9ff721
 			;
9ff721
 
9ff721
 list_rhs_expr		:	basic_rhs_expr		COMMA		basic_rhs_expr
9ff721
@@ -3439,6 +3435,7 @@ primary_rhs_expr	:	symbol_expr		{ $$ = $1; }
9ff721
 							 BYTEORDER_HOST_ENDIAN,
9ff721
 							 sizeof(data) * BITS_PER_BYTE, &data);
9ff721
 			}
9ff721
+			|	'('	basic_rhs_expr	')'	{ $$ = $2; }
9ff721
 			;
9ff721
 
9ff721
 relational_op		:	EQ		{ $$ = OP_EQ; }
9ff721
diff --git a/tests/py/inet/tcp.t b/tests/py/inet/tcp.t
9ff721
index d66ba8438a32f..f96e3634f41ed 100644
9ff721
--- a/tests/py/inet/tcp.t
9ff721
+++ b/tests/py/inet/tcp.t
9ff721
@@ -78,6 +78,7 @@ tcp flags cwr;ok
9ff721
 tcp flags != cwr;ok
9ff721
 tcp flags == syn;ok
9ff721
 tcp flags & (syn|fin) == (syn|fin);ok;tcp flags & (fin | syn) == fin | syn
9ff721
+tcp flags & (fin | syn | rst | psh | ack | urg | ecn | cwr) == fin | syn | rst | psh | ack | urg | ecn | cwr;ok;tcp flags == 0xff
9ff721
 
9ff721
 tcp window 22222;ok
9ff721
 tcp window 22;ok
9ff721
diff --git a/tests/py/inet/tcp.t.json b/tests/py/inet/tcp.t.json
9ff721
index f5df72aa252a6..9ae51018e93ee 100644
9ff721
--- a/tests/py/inet/tcp.t.json
9ff721
+++ b/tests/py/inet/tcp.t.json
9ff721
@@ -1068,6 +1068,29 @@
9ff721
     }
9ff721
 ]
9ff721
 
9ff721
+# tcp flags & (fin | syn | rst | psh | ack | urg | ecn | cwr) == fin | syn | rst | psh | ack | urg | ecn | cwr
9ff721
+[
9ff721
+    {
9ff721
+        "match": {
9ff721
+            "left": {
9ff721
+                "&": [
9ff721
+                    {
9ff721
+                        "payload": {
9ff721
+                            "field": "flags",
9ff721
+                            "protocol": "tcp"
9ff721
+                        }
9ff721
+                    },
9ff721
+                    {
9ff721
+                        "|": [ "fin", { "|": [ "syn", { "|": [ "rst", { "|": [ "psh", { "|": [ "ack", { "|": [ "urg", { "|": [ "ecn", "cwr" ] } ] } ] } ] } ] } ] } ]
9ff721
+                    }
9ff721
+                ]
9ff721
+            },
9ff721
+            "op": "==",
9ff721
+            "right": { "|": [ "fin", { "|": [ "syn", { "|": [ "rst", { "|": [ "psh", { "|": [ "ack", { "|": [ "urg", { "|": [ "ecn", "cwr" ] } ] } ] } ] } ] } ] } ] }
9ff721
+        }
9ff721
+    }
9ff721
+]
9ff721
+
9ff721
 # tcp window 22222
9ff721
 [
9ff721
     {
9ff721
diff --git a/tests/py/inet/tcp.t.json.output b/tests/py/inet/tcp.t.json.output
9ff721
index d099d6febb122..ff58756cf596d 100644
9ff721
--- a/tests/py/inet/tcp.t.json.output
9ff721
+++ b/tests/py/inet/tcp.t.json.output
9ff721
@@ -132,3 +132,19 @@
9ff721
     }
9ff721
 ]
9ff721
 
9ff721
+# tcp flags & (fin | syn | rst | psh | ack | urg | ecn | cwr) == fin | syn | rst | psh | ack | urg | ecn | cwr
9ff721
+[
9ff721
+    {
9ff721
+        "match": {
9ff721
+            "left": {
9ff721
+                "payload": {
9ff721
+                    "field": "flags",
9ff721
+                    "protocol": "tcp"
9ff721
+                }
9ff721
+            },
9ff721
+            "op": "==",
9ff721
+            "right": 255
9ff721
+        }
9ff721
+    }
9ff721
+]
9ff721
+
9ff721
diff --git a/tests/py/inet/tcp.t.payload b/tests/py/inet/tcp.t.payload
9ff721
index 09538aed746c9..2390a24ead15c 100644
9ff721
--- a/tests/py/inet/tcp.t.payload
9ff721
+++ b/tests/py/inet/tcp.t.payload
9ff721
@@ -436,6 +436,14 @@ inet test-inet input
9ff721
   [ bitwise reg 1 = (reg=1 & 0x00000003 ) ^ 0x00000000 ]
9ff721
   [ cmp eq reg 1 0x00000003 ]
9ff721
 
9ff721
+# tcp flags & (fin | syn | rst | psh | ack | urg | ecn | cwr) == fin | syn | rst | psh | ack | urg | ecn | cwr
9ff721
+inet test-inet input
9ff721
+  [ meta load l4proto => reg 1 ]
9ff721
+  [ cmp eq reg 1 0x00000006 ]
9ff721
+  [ payload load 1b @ transport header + 13 => reg 1 ]
9ff721
+  [ bitwise reg 1 = (reg=1 & 0x000000ff ) ^ 0x00000000 ]
9ff721
+  [ cmp eq reg 1 0x000000ff ]
9ff721
+
9ff721
 # tcp window 22222
9ff721
 inet test-inet input
9ff721
   [ meta load l4proto => reg 1 ]
9ff721
-- 
bacbc8
2.21.0
9ff721