In the IPv6 path of eth_get_protocols(), eth_parse_ipv6_hdr() does
various sanity checks on the packet's IPv6 header, so we won't tell
the caller we have an IPv6 header when we have a malformed one.
However for IPv4 we only check the version and that we have at least
the minimum header size.

Harden this codepath by checking also that the header size declared
in the packet's own headers is neither smaller than the minimum nor
larger than the actual packet size.

Missing these checks shouldn't cause problems if the caller is
validating all offsets and lengths before use, but checking here
too is defence-in-depth, hence the cc to stable.

Cc: [email protected]
Fixes: 69ff5ef847457555 ("net/eth: Report if headers are actually present")
Signed-off-by: Peter Maydell <[email protected]>
---
 net/eth.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/eth.c b/net/eth.c
index 341d3bdf02b..e2c1e08ed28 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -156,6 +156,8 @@ void eth_get_protocols(const struct iovec *iov, size_t 
iovcnt, size_t iovoff,
 
         copied = iov_to_buf(iov, iovcnt, *l3hdr_off, iphdr, sizeof(*iphdr));
         if (copied < sizeof(*iphdr) ||
+            IP_HDR_GET_LEN(iphdr) < sizeof(*iphdr) ||
+            input_size - *l3hdr_off < IP_HDR_GET_LEN(iphdr) ||
             IP_HEADER_VERSION(iphdr) != IP_HEADER_VERSION_4) {
             return;
         }
-- 
2.43.0


Reply via email to