git: abba58766fdd - main - LRO: Add missing checks for invalid IP addresses

From: Andrew Gallatin <gallatin_at_FreeBSD.org>
Date: Sat, 25 Mar 2023 16:05:03 UTC
The branch main has been updated by gallatin:

URL: https://cgit.FreeBSD.org/src/commit/?id=abba58766fdd7f9720761aba39c2b9653eb4fbd3

commit abba58766fdd7f9720761aba39c2b9653eb4fbd3
Author:     Andrew Gallatin <gallatin@FreeBSD.org>
AuthorDate: 2023-03-25 15:51:51 +0000
Commit:     Andrew Gallatin <gallatin@FreeBSD.org>
CommitDate: 2023-03-25 15:56:02 +0000

    LRO: Add missing checks for invalid IP addresses
    
    LRO bypasses normal ip_input()/tcp_input() and lacks several checks
    that are present in the normal path.  Without these checks, it
    is possible to trigger assertions added in b0ccf53f2455
    
    Reviewed by: glebius, rrs
    Sponsored by: Netflix
---
 sys/netinet/tcp_lro.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/sys/netinet/tcp_lro.c b/sys/netinet/tcp_lro.c
index bde8fadbc05b..908f9cdd7ea4 100644
--- a/sys/netinet/tcp_lro.c
+++ b/sys/netinet/tcp_lro.c
@@ -292,6 +292,10 @@ tcp_lro_low_level_parser(void *ptr, struct lro_parser *parser, bool update_data,
 		/* .. and the packet is not fragmented. */
 		if (parser->ip4->ip_off & htons(IP_MF|IP_OFFMASK))
 			break;
+		/* .. and the packet has valid src/dst addrs */
+		if (__predict_false(parser->ip4->ip_src.s_addr == INADDR_ANY ||
+			parser->ip4->ip_dst.s_addr == INADDR_ANY))
+			break;
 		ptr = (uint8_t *)ptr + (parser->ip4->ip_hl << 2);
 		mlen -= sizeof(struct ip);
 		if (update_data) {
@@ -339,6 +343,10 @@ tcp_lro_low_level_parser(void *ptr, struct lro_parser *parser, bool update_data,
 		parser->ip6 = ptr;
 		if (__predict_false(mlen < sizeof(struct ip6_hdr)))
 			return (NULL);
+		/* Ensure the packet has valid src/dst addrs */
+		if (__predict_false(IN6_IS_ADDR_UNSPECIFIED(&parser->ip6->ip6_src) ||
+			IN6_IS_ADDR_UNSPECIFIED(&parser->ip6->ip6_dst)))
+			return (NULL);
 		ptr = (uint8_t *)ptr + sizeof(*parser->ip6);
 		if (update_data) {
 			parser->data.s_addr.v6 = parser->ip6->ip6_src;