mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
asymcute: fix one byte out-of-bounds access in _len_get
As per Section 5.2.1 of the MQTT-SN specification, the MQTT-SN length header is either 1- or 3-octet long. If it is 3-octet long then the first octet is 0x01. The asymcute implementation currently only checks that the incoming packet is at least 2-octet long before attempting to parse it (MIN_PKT_LEN). However, if the first octet is 0x01 the packet must be more than 3 octet long in order to be valid. Since asymcute does not check this it reads one octet beyond the packet data for a 2-octet packet where the first octet has the value 0x01. This commit fixes this issue by adding an additional sanity check to _len_get.
This commit is contained in:
parent
50e4498c84
commit
06d572c2fc
@ -83,13 +83,16 @@ static size_t _len_set(uint8_t *buf, size_t len)
|
||||
}
|
||||
}
|
||||
|
||||
static size_t _len_get(uint8_t *buf, size_t *len)
|
||||
static ssize_t _len_get(uint8_t *buf, size_t pkt_len, size_t *len)
|
||||
{
|
||||
if (buf[0] != 0x01) {
|
||||
*len = (uint16_t)buf[0];
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
if (pkt_len < 3) {
|
||||
return -1;
|
||||
}
|
||||
*len = byteorder_bebuftohs(&buf[1]);
|
||||
return 3;
|
||||
}
|
||||
@ -107,8 +110,10 @@ static uint16_t _msg_id_next(asymcute_con_t *con)
|
||||
static uint8_t _req_type(asymcute_req_t *req)
|
||||
{
|
||||
size_t len;
|
||||
size_t pos = _len_get(req->data, &len);
|
||||
return req->data[pos];
|
||||
ssize_t pos = _len_get(req->data, req->data_len, &len);
|
||||
/* requests are created by us and should thus always be valid */
|
||||
assert(pos != -1 && (size_t)pos < req->data_len);
|
||||
return req->data[(size_t)pos];
|
||||
}
|
||||
|
||||
/* @pre con is locked */
|
||||
@ -590,7 +595,12 @@ void _on_pkt(sock_udp_t *sock, sock_async_flags_t type, void *arg)
|
||||
CONFIG_ASYMCUTE_BUFSIZE, 0, NULL);
|
||||
if (pkt_len >= MIN_PKT_LEN) {
|
||||
size_t len;
|
||||
size_t pos = _len_get(con->rxbuf, &len);
|
||||
ssize_t lret = _len_get(con->rxbuf, pkt_len, &len);
|
||||
if (lret == -1) {
|
||||
/* first octet was 0x01 but pkt does not have more than 3 octets */
|
||||
return;
|
||||
}
|
||||
size_t pos = (size_t)lret;
|
||||
|
||||
/* validate incoming data: verify message length */
|
||||
if (((size_t)pkt_len <= pos) || ((size_t)pkt_len < len)) {
|
||||
|
Loading…
Reference in New Issue
Block a user