Currently eth_get_l3_proto() has a check that the offset of the protocol field is not off the end of the iovec; this is actually unnecessary because iov_to_buf() guarantees to return 0 for offsets off the end of the iovec. On the other hand, it assumes that the l2hdr_len it is passed is not so small that the protocol offset calculation underflows and it doesn't check that the packet is actually big enough for the l2hdr_len. This shouldn't matter if other parts of the code are checking, but for defence in depth we tighten this check.
Cc: [email protected] Fixes: eb700029c783 ("net_pkt: Extend packet abstraction as required by e1000e functionality") Signed-off-by: Peter Maydell <[email protected]> --- net/eth.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/eth.c b/net/eth.c index 955f2bff5e6..d9113da58eb 100644 --- a/net/eth.c +++ b/net/eth.c @@ -74,11 +74,13 @@ eth_get_l3_proto(const struct iovec *l2hdr_iov, int iovcnt, size_t l2hdr_len) uint16_t proto; size_t copied; size_t size = iov_size(l2hdr_iov, iovcnt); - size_t proto_offset = l2hdr_len - sizeof(proto); + size_t proto_offset; - if (size < proto_offset) { + if (l2hdr_len < sizeof(struct eth_header) || size < l2hdr_len) { + /* We don't have a complete ethernet header */ return ETH_P_UNKNOWN; } + proto_offset = l2hdr_len - sizeof(proto); copied = iov_to_buf(l2hdr_iov, iovcnt, proto_offset, &proto, sizeof(proto)); -- 2.43.0
