libsystemd-network: check size of icmpv6 packets

Coverity was complaining that we use the received packet size as a loop bound
without checking. This is indeed a bit iffy, because depending on how the host
is configured, the packet could be rather large. Let's refuse anything more
than the standard size early to prevent suspicious activity.

Resolves coverity CID#1534892, CID#1543949.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2024-05-14 18:43:29 +02:00
parent f7a6418d47
commit caa4bfd468
2 changed files with 9 additions and 0 deletions

View File

@@ -88,6 +88,11 @@ static int icmp6_packet_verify(ICMP6Packet *p) {
if (hdr->icmp6_code != 0)
return -EBADMSG;
/* Drop any overly large packets early. We are not interested in jumbograms,
* which could cause excessive processing. */
if (p->raw_size > ICMP6_MAX_NORMAL_PAYLOAD_SIZE)
return -EMSGSIZE;
return 0;
}

View File

@@ -21,6 +21,10 @@ ICMP6Packet* icmp6_packet_ref(ICMP6Packet *p);
ICMP6Packet* icmp6_packet_unref(ICMP6Packet *p);
DEFINE_TRIVIAL_CLEANUP_FUNC(ICMP6Packet*, icmp6_packet_unref);
/* IPv6 Header is 40 bytes and reserves 2 bytes to represent the Payload Length. Thus, the max payload size,
* including extension headers, is 65535 bytes (2^16 - 1). Jumbograms can be larger (2^32 - 1). */
#define ICMP6_MAX_NORMAL_PAYLOAD_SIZE 65535
int icmp6_packet_set_sender_address(ICMP6Packet *p, const struct in6_addr *addr);
int icmp6_packet_get_sender_address(ICMP6Packet *p, struct in6_addr *ret);
int icmp6_packet_get_timestamp(ICMP6Packet *p, clockid_t clock, usec_t *ret);