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) { + l4hdr_info->proto = ETH_L4_HDR_PROTO_SCTP; + } break; } } -- 2.43.0
