Fix OOB reads and infinite loop in TLV and DMAP parsers

pair_ap/pair-tlv.c (pair_tlv_parse):
- Add bounds check before reading type and length bytes (i + 2 > length)
- Fix off-by-one in chunked TLV scan loop (j + 1 < length)
- Add bounds checks inside data copy loop to prevent OOB memcpy
- Add else branch to advance index when size == 0 (prevents infinite loop)

rtsp.c (handle_set_parameter_metadata):
- Require 8 bytes remaining for tag + length fields (off + 8 <= cl)
- Validate value length against remaining buffer before read

Reported-by: Tristan Madani <tristan@talencesecurity.com>
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
This commit is contained in:
TristanInSec
2026-06-16 10:33:18 -04:00
parent b4751a09ef
commit 476677b0f0
2 changed files with 19 additions and 3 deletions
+15 -2
View File
@@ -162,18 +162,21 @@ pair_tlv_parse(const uint8_t *buffer, size_t length, pair_tlv_values_t *values)
size_t i = 0;
int ret;
while (i < length) {
if (i + 2 > length)
return PAIR_TLV_ERROR_INSUFFICIENT_SIZE;
uint8_t type = buffer[i];
size_t size = 0;
uint8_t *data = NULL;
// scan TLVs to accumulate total size of subsequent TLVs with same type (chunked data)
size_t j = i;
while (j < length && buffer[j] == type && buffer[j+1] == 255) {
while (j + 1 < length && buffer[j] == type && buffer[j+1] == 255) {
size_t chunk_size = buffer[j+1];
size += chunk_size;
j += chunk_size + 2;
}
if (j < length && buffer[j] == type) {
if (j + 1 < length && buffer[j] == type) {
size_t chunk_size = buffer[j+1];
size += chunk_size;
}
@@ -188,12 +191,22 @@ pair_tlv_parse(const uint8_t *buffer, size_t length, pair_tlv_values_t *values)
size_t remaining = size;
while (remaining) {
if (i + 2 > length) {
free(data);
return PAIR_TLV_ERROR_INSUFFICIENT_SIZE;
}
size_t chunk_size = buffer[i+1];
if (chunk_size > length - i - 2) {
free(data);
return PAIR_TLV_ERROR_INSUFFICIENT_SIZE;
}
memcpy(p, &buffer[i+2], chunk_size);
p += chunk_size;
i += chunk_size + 2;
remaining -= chunk_size;
}
} else {
i += 2;
}
ret = tlv_add_value_(values, type, data, size);
+4 -1
View File
@@ -3275,7 +3275,7 @@ static void handle_set_parameter_metadata(__attribute__((unused)) rtsp_conn_info
unsigned int off = 8;
uint32_t itag, vl;
while (off < cl) {
while (off + 8 <= cl) {
// pick up the metadata tag as an unsigned longint
memcpy(&itag, (uint32_t *)(cp + off), sizeof(uint32_t)); /* can be misaligned, thus memcpy */
itag = ntohl(itag);
@@ -3286,6 +3286,9 @@ static void handle_set_parameter_metadata(__attribute__((unused)) rtsp_conn_info
vl = ntohl(vl);
off += sizeof(uint32_t);
if (vl > cl - off)
break;
// pass the data over
if (vl == 0)
send_metadata('core', itag, NULL, 0, NULL, 1);