On 2026-11-02 21:18, Peter Maydell wrote:
eth_get_protocols() parses an ethernet packet and tells the caller
about various offsets into it and other properties of the packet.
For the L4 protocol, in both the IP_PROTO_TCP and IP_PROTO_UDP
branches we implicitly check that the packet does contain a whole TCP
or UDP header at the l4hdr_off offset, because _eth_copy_chunk() will
fail if the input packet size isn't big enough for the whole header
we are copying out of it. But for IP_PROTO_SCTP we don't copy the
SCTP common header. In this case we should still do the length
check, so we don't set l4hdr_info->proto to say there's an SCTP
header present when there isn't.
This shouldn't have any visible effects if the downstream consumers
of the l4hdr_info are conservative about checking before they access
into the packet, but checking here too adds defence in depth, hence
the cc to stable.
Cc: [email protected]
Fixes: 907209e311 ("igb: Implement Rx SCTP CSO")
Signed-off-by: Peter Maydell <[email protected]>
---
include/net/eth.h | 2 ++
net/eth.c | 9 ++++++++-
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/include/net/eth.h b/include/net/eth.h
index 46dc9ed5acd..e10684ed923 100644
--- a/include/net/eth.h
+++ b/include/net/eth.h
@@ -394,6 +394,8 @@ typedef struct eth_l4_hdr_info_st {
bool has_tcp_data;
} eth_l4_hdr_info;
+#define SCTP_COMMON_HEADER_LEN 12
+
void eth_get_protocols(const struct iovec *iov, size_t iovcnt, size_t iovoff,
bool *hasip4, bool *hasip6,
size_t *l3hdr_off,
diff --git a/net/eth.c b/net/eth.c
index bc26d38dc21..341d3bdf02b 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -213,7 +213,14 @@ void eth_get_protocols(const struct iovec *iov, size_t
iovcnt, size_t iovoff,
break;
case IP_PROTO_SCTP:
- l4hdr_info->proto = ETH_L4_HDR_PROTO_SCTP;
+ /*
+ * We don't copy the SCTP common header into l4hdr_info, but
+ * don't report SCTP as present if the packet isn't big enough
+ * to actually have an SCTP header.
+ */
+ if (*l4hdr_off > input_size - SCTP_COMMON_HEADER_LEN) {
Hmm don't we want the opposite "is SCTP common header complete" check?
if (input_size >= *l4hdr_off
&& input_size - *l4hdr_off >= SCTP_COMMON_HEADER_LEN) {
+ l4hdr_info->proto = ETH_L4_HDR_PROTO_SCTP;
+ }
break;
}
}