uip6: sanitize parsing of ext header options
This commit is contained in:
parent
ff825daaea
commit
9194e82168
@ -823,10 +823,21 @@ ext_hdr_options_process(uint8_t *ext_buf)
|
|||||||
* 8 bytes, excluding the first 8 bytes
|
* 8 bytes, excluding the first 8 bytes
|
||||||
* length field in an option : the length of data in the option
|
* 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;
|
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);
|
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) {
|
switch(opt_hdr->type) {
|
||||||
/*
|
/*
|
||||||
* for now we do not support any options except padding ones
|
* for now we do not support any options except padding ones
|
||||||
@ -839,7 +850,7 @@ ext_hdr_options_process(uint8_t *ext_buf)
|
|||||||
break;
|
break;
|
||||||
case UIP_EXT_HDR_OPT_PADN:
|
case UIP_EXT_HDR_OPT_PADN:
|
||||||
LOG_DBG("Processing PADN option\n");
|
LOG_DBG("Processing PADN option\n");
|
||||||
opt_offset += ((struct uip_ext_hdr_opt_padn *)opt_hdr)->opt_len + 2;
|
opt_offset += opt_len;
|
||||||
break;
|
break;
|
||||||
case UIP_EXT_HDR_OPT_RPL:
|
case UIP_EXT_HDR_OPT_RPL:
|
||||||
/* Fixes situation when a node that is not using 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");
|
LOG_ERR("RPL Option Error: Dropping Packet\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
opt_offset += opt_hdr->len + 2;
|
opt_offset += opt_len;
|
||||||
return 0;
|
break;
|
||||||
default:
|
default:
|
||||||
/*
|
/*
|
||||||
* check the two highest order bits of the option
|
* check the two highest order bits of the option
|
||||||
@ -887,7 +898,7 @@ ext_hdr_options_process(uint8_t *ext_buf)
|
|||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
/* in the cases were we did not discard, update ext_opt* */
|
/* in the cases were we did not discard, update ext_opt* */
|
||||||
opt_offset += opt_hdr->len + 2;
|
opt_offset += opt_len;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user