uip6: sanitize parsing of ext header options

This commit is contained in:
Simon Duquennoy 2018-10-19 15:45:16 +02:00
parent ff825daaea
commit 9194e82168

View File

@ -823,10 +823,21 @@ ext_hdr_options_process(uint8_t *ext_buf)
* 8 bytes, excluding the first 8 bytes
* length field in an option : the length of data in the option
*/
uint8_t opt_offset = 2;
uint8_t opt_offset = 2; /* 2 first bytes in ext header */
struct uip_hbho_hdr *ext_hdr = (struct uip_hbho_hdr *)ext_buf;
while(opt_offset < ((ext_hdr->len << 3) + 8)) {
uint8_t ext_hdr_len = (ext_hdr->len << 3) + 8;
while(opt_offset + 2 <= ext_hdr_len) { /* + 2 for opt header */
struct uip_ext_hdr_opt *opt_hdr = (struct uip_ext_hdr_opt *)(ext_buf + opt_offset);
uint8_t opt_len = opt_hdr->len + 2;
if(opt_offset + opt_len > ext_hdr_len) {
LOG_ERR("RPL Option too long: Dropping Packet\n");
uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION,
(ext_buf + opt_offset) - uip_buf);
return 2;
}
switch(opt_hdr->type) {
/*
* for now we do not support any options except padding ones
@ -839,7 +850,7 @@ ext_hdr_options_process(uint8_t *ext_buf)
break;
case UIP_EXT_HDR_OPT_PADN:
LOG_DBG("Processing PADN option\n");
opt_offset += ((struct uip_ext_hdr_opt_padn *)opt_hdr)->opt_len + 2;
opt_offset += opt_len;
break;
case UIP_EXT_HDR_OPT_RPL:
/* Fixes situation when a node that is not using RPL
@ -855,8 +866,8 @@ ext_hdr_options_process(uint8_t *ext_buf)
LOG_ERR("RPL Option Error: Dropping Packet\n");
return 1;
}
opt_offset += opt_hdr->len + 2;
return 0;
opt_offset += opt_len;
break;
default:
/*
* check the two highest order bits of the option
@ -887,7 +898,7 @@ ext_hdr_options_process(uint8_t *ext_buf)
return 2;
}
/* in the cases were we did not discard, update ext_opt* */
opt_offset += opt_hdr->len + 2;
opt_offset += opt_len;
break;
}
}