]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
libsystemd-network: check size of icmpv6 packets
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 14 May 2024 16:43:29 +0000 (18:43 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 14 May 2024 16:56:35 +0000 (18:56 +0200)
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.

src/libsystemd-network/icmp6-packet.c
src/libsystemd-network/icmp6-packet.h

index 21d744beaa49b84f6d5d708d5049b1fba67dc0b9..f447549dc86e3399b3751e204e053478d138cb63 100644 (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;
 }
 
index 16f354fc95a4fc033f4c89fa79ff7def60373c0f..b402255806591665c3a83bbf0db3ca7e7c586409 100644 (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);