1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-25 14:33:52 +01:00

gnrc_ipv6: validates payload size

This commit is contained in:
Yonezawa-T2 2016-03-11 12:44:14 +09:00
parent a10151d5f0
commit 0de34c91c6
3 changed files with 56 additions and 0 deletions

View File

@ -69,6 +69,14 @@ void gnrc_icmpv6_demux(kernel_pid_t iface, gnrc_pktsnip_t *pkt)
assert(ipv6 != NULL);
if (icmpv6->size < sizeof(icmpv6_hdr_t)) {
DEBUG("icmpv6: packet too short.\n");
return;
}
/* Note: size will be checked again in gnrc_icmpv6_echo_req_handle,
gnrc_ndp_rtr_sol_handle, and others */
hdr = (icmpv6_hdr_t *)icmpv6->data;
if (_calc_csum(icmpv6, ipv6, pkt)) {

View File

@ -138,6 +138,30 @@ static gnrc_pktsnip_t *_mark_extension_header(gnrc_pktsnip_t *current,
return next;
}
static inline bool _has_valid_size(gnrc_pktsnip_t *pkt, uint8_t nh)
{
ipv6_ext_t *ext;
if (pkt->size < sizeof(ipv6_ext_t)) {
return false;
}
ext = pkt->data;
switch (nh) {
case PROTNUM_IPV6_EXT_RH:
case PROTNUM_IPV6_EXT_HOPOPT:
case PROTNUM_IPV6_EXT_DST:
case PROTNUM_IPV6_EXT_FRAG:
case PROTNUM_IPV6_EXT_AH:
case PROTNUM_IPV6_EXT_ESP:
case PROTNUM_IPV6_EXT_MOB:
return ((ext->len * IPV6_EXT_LEN_UNIT) + IPV6_EXT_LEN_UNIT) <= pkt->size;
default:
return true;
}
}
/*
* current pkt
@ -158,6 +182,13 @@ void gnrc_ipv6_ext_demux(kernel_pid_t iface,
switch (nh) {
case PROTNUM_IPV6_EXT_RH:
#ifdef MODULE_GNRC_RPL_SRH
/* if current != pkt, size is already checked */
if (current == pkt && !_has_valid_size(pkt, nh)) {
DEBUG("ipv6_ext: invalid size\n");
gnrc_pktbuf_release(pkt);
return;
}
switch (_handle_rh(current, pkt)) {
case GNRC_IPV6_EXT_OK:
/* We are the final destination. So proceeds like normal packet. */
@ -191,6 +222,14 @@ void gnrc_ipv6_ext_demux(kernel_pid_t iface,
case PROTNUM_IPV6_EXT_ESP:
case PROTNUM_IPV6_EXT_MOB:
/* TODO: add handling of types */
/* if current != pkt, size is already checked */
if (current == pkt && !_has_valid_size(pkt, nh)) {
DEBUG("ipv6_ext: invalid size\n");
gnrc_pktbuf_release(pkt);
return;
}
nh = ext->nh;
DEBUG("ipv6_ext: next header = %" PRIu8 "\n", nh);

View File

@ -853,6 +853,7 @@ static void _receive(gnrc_pktsnip_t *pkt)
ipv6 = gnrc_pktbuf_mark(pkt, sizeof(ipv6_hdr_t), GNRC_NETTYPE_IPV6);
first_ext = pkt;
pkt->type = GNRC_NETTYPE_UNDEF; /* snip is no longer IPv6 */
if (ipv6 == NULL) {
DEBUG("ipv6: error marking IPv6 header, dropping packet\n");
@ -885,6 +886,14 @@ static void _receive(gnrc_pktsnip_t *pkt)
if (byteorder_ntohs(hdr->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))) {
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)));
gnrc_pktbuf_release(pkt);
return;
}
DEBUG("ipv6: Received (src = %s, ",
ipv6_addr_to_str(addr_str, &(hdr->src), sizeof(addr_str)));