Check whether there is enough space for ND6 option headers when processing
incoming packets.
@@ -123,7 +123,8 @@ static uip_ds6_prefix_t *prefix; /** Pointer to a prefix list entry */
/*------------------------------------------------------------------*/
/* Copy link-layer address from LLAO option to a word-aligned uip_lladdr_t */
static int
-extract_lladdr_from_llao_aligned(uip_lladdr_t *dest) {
+extract_lladdr_from_llao_aligned(uip_lladdr_t *dest)
+{
if(dest != NULL && nd6_opt_llao != NULL) {
memcpy(dest, &nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], UIP_LLADDR_LEN);
return 1;
@@ -135,7 +136,8 @@ extract_lladdr_from_llao_aligned(uip_lladdr_t *dest) {
#if UIP_ND6_SEND_NA /* UIP_ND6_SEND_NA */
/* create a llao */
static void
-create_llao(uint8_t *llao, uint8_t type) {
+create_llao(uint8_t *llao, uint8_t type)
+{
llao[UIP_ND6_OPT_TYPE_OFFSET] = type;
llao[UIP_ND6_OPT_LEN_OFFSET] = UIP_ND6_OPT_LLAO_LEN >> 3;
memcpy(&llao[UIP_ND6_OPT_DATA_OFFSET], &uip_lladdr, UIP_LLADDR_LEN);
@@ -193,7 +195,7 @@ ns_input(void)
/* Options processing */
nd6_opt_llao = NULL;
nd6_opt_offset = UIP_ND6_NS_LEN;
- while(uip_l3_icmp_hdr_len + nd6_opt_offset < uip_len) {
+ while(uip_l3_icmp_hdr_len + nd6_opt_offset + UIP_ND6_OPT_HDR_LEN < uip_len) {
#if UIP_CONF_IPV6_CHECKS
if(ND6_OPT_HDR_BUF(nd6_opt_offset)->len == 0) {
LOG_ERR("NS received is bad\n");
@@ -202,6 +204,11 @@ ns_input(void)
#endif /* UIP_CONF_IPV6_CHECKS */
switch (ND6_OPT_HDR_BUF(nd6_opt_offset)->type) {
case UIP_ND6_OPT_SLLAO:
+ if(uip_l3_icmp_hdr_len + nd6_opt_offset +
+ UIP_ND6_OPT_DATA_OFFSET + UIP_LLADDR_LEN > uip_len) {
+ LOG_ERR("Insufficient data for NS SLLAO option\n");
+ goto discard;
+ }
nd6_opt_llao = &uip_buf[uip_l3_icmp_hdr_len + nd6_opt_offset];
#if UIP_CONF_IPV6_CHECKS
/* There must be NO option in a DAD NS */
