From: Zbigniew Jędrzejewski-Szmek Date: Tue, 14 May 2024 16:43:29 +0000 (+0200) Subject: libsystemd-network: check size of icmpv6 packets X-Git-Tag: v256-rc3~72^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=caa4bfd4688f0997d724acd8be759f17b7ae3291;p=thirdparty%2Fsystemd.git 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. --- diff --git a/src/libsystemd-network/icmp6-packet.c b/src/libsystemd-network/icmp6-packet.c index 21d744beaa4..f447549dc86 100644 --- a/src/libsystemd-network/icmp6-packet.c +++ b/src/libsystemd-network/icmp6-packet.c @@ -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; } diff --git a/src/libsystemd-network/icmp6-packet.h b/src/libsystemd-network/icmp6-packet.h index 16f354fc95a..b4022558065 100644 --- a/src/libsystemd-network/icmp6-packet.h +++ b/src/libsystemd-network/icmp6-packet.h @@ -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);