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

nanocoap: Fixed buffer read out of the input packet bounds issue.

If token length in the header was longer than actually provided in the following payload, read out of the input buffer bounds or processing of data beyond the actual input packet bound could happen. In order to remove the risk, the options loop condition was modified to early detect the condition and abort packet processing if a malformed packet is detected.

nanocoap: Added pointer range check after token length parsing.

Added a check to verify if the current packet parsing pointer is still within the packet boundaries after incrementing by the token length declared in the header. If packet is malformed an error code is returned.

nanocoap: Combined packet length checks

Combined packet length checks after reading token length and processing options into a single packet length validation after the options parsing loop. The entry to the options parsing loop is safe as the while loop condition protects against entering the loop if the token length was invalid.
This commit is contained in:
Maciej Jurczak 2020-05-13 23:01:18 +02:00
parent 88e4c0ffef
commit 3be2c51c42

View File

@ -81,6 +81,7 @@ int coap_parse(coap_pkt_t *pkt, uint8_t *buf, size_t len)
/* token value (tkl bytes) */
if (coap_get_token_len(pkt)) {
pkt->token = pkt_pos;
/* pkt_pos range is validated after options parsing loop below */
pkt_pos += coap_get_token_len(pkt);
}
else {
@ -92,7 +93,7 @@ int coap_parse(coap_pkt_t *pkt, uint8_t *buf, size_t len)
unsigned option_nr = 0;
/* parse options */
while (pkt_pos != pkt_end) {
while (pkt_pos < pkt_end) {
uint8_t *option_start = pkt_pos;
uint8_t option_byte = *pkt_pos++;
if (option_byte == 0xff) {
@ -129,14 +130,14 @@ int coap_parse(coap_pkt_t *pkt, uint8_t *buf, size_t len)
}
pkt_pos += option_len;
if (pkt_pos > (buf + len)) {
DEBUG("nanocoap: bad pkt\n");
return -EBADMSG;
}
}
}
if (pkt_pos > pkt_end) {
DEBUG("bad pkt len\n");
return -EBADMSG;
}
pkt->options_len = option_count;
if (!pkt->payload) {
pkt->payload = pkt_pos;