From ad5617fb8383fed0e788de473732ebb260acb44e Mon Sep 17 00:00:00 2001 From: Robin Nehls <git@manol.is> Date: Tue, 3 Apr 2018 18:18:58 +0200 Subject: [PATCH] gnrc_ipv6: discard non-NONXT packets with 0 payload length If the payload length is zero and the next header field is not set to NONXT, GNRC will interpret the current header as the payload because the first snip is always interpreted as the payload. This can lead to loops and or crashes. --- sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c index fa6cf2097c..bfebc0d75c 100644 --- a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c +++ b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c @@ -784,13 +784,20 @@ static void _receive(gnrc_pktsnip_t *pkt) /* extract header */ hdr = (ipv6_hdr_t *)ipv6->data; + uint16_t ipv6_len = byteorder_ntohs(hdr->len); + + if ((ipv6_len == 0) && (hdr->nh != PROTNUM_IPV6_NONXT)) { + /* this doesn't even make sense */ + DEBUG("ipv6: payload length 0, but next header not NONXT\n"); + gnrc_pktbuf_release(pkt); + return; + } /* if available, remove any padding that was added by lower layers * to fulfill their minimum size requirements (e.g. ethernet) */ - if ((ipv6 != pkt) && (byteorder_ntohs(hdr->len) < pkt->size)) { + else if ((ipv6 != pkt) && (ipv6_len < pkt->size)) { gnrc_pktbuf_realloc_data(pkt, byteorder_ntohs(hdr->len)); } - else if (byteorder_ntohs(hdr->len) > - (gnrc_pkt_len_upto(pkt, GNRC_NETTYPE_IPV6) - sizeof(ipv6_hdr_t))) { + else if (ipv6_len > (gnrc_pkt_len_upto(pkt, GNRC_NETTYPE_IPV6) - sizeof(ipv6_hdr_t))) { DEBUG("ipv6: invalid payload length: %d, actual: %d, dropping packet\n", (int) byteorder_ntohs(hdr->len), (int) (gnrc_pkt_len_upto(pkt, GNRC_NETTYPE_IPV6) - sizeof(ipv6_hdr_t))); -- GitLab