From 0a7967dbdb59bce4d791265da8ed643a35e51bd5 Mon Sep 17 00:00:00 2001
From: ABC <abc@openwall.com>
Date: Wed, 18 Jan 2023 09:18:24 +0300
Subject: [PATCH 15/17] Fix possible out-of-bounds read in tcp_options fix

Out-of-bounds read could occur in `p[i] < 2` before boundary of `i` is
checked.

Basically it's returning previous code except for a fix and early
zeroing of `ret`.

Fixes: a1386af ("tcp options: fix possible shift-out-of-bounds")
Signed-off-by: ABC <abc@openwall.com>
---
 ipt_NETFLOW.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/ipt_NETFLOW.c b/ipt_NETFLOW.c
index e9c2567..ab4afda 100644
--- a/ipt_NETFLOW.c
+++ b/ipt_NETFLOW.c
@@ -4852,12 +4852,16 @@ static inline __u32 tcp_options(const struct sk_buff *skb, const unsigned int pt
 	for (i = 0; likely(i < optsize); ) {
 		u_int8_t opt = p[i++];
 
-		if (likely(opt < 32))
+		if (likely(opt < 32)) {
+			/* IANA doc is messed up, see above. */
 			ret |= 1 << (31 - opt);
-		if (likely(opt == 0) || unlikely(p[i] < 2))
+		}
+		if (likely(i >= optsize || opt == 0))
 			break;
-		if (unlikely(opt == 1))
+		else if (unlikely(opt == 1))
 			continue;
+		else if (unlikely(p[i] < 2)) /* "silly options" */
+			break;
 		else
 			i += p[i] - 1;
 	}
-- 
2.39.5

