Merge pull request #2218 from TristanInSec/fix-tlv-dmap-oob-reads-v2

Fix Out-Of-Bounds reads and infinite loop in TLV and DMAP parsers.
This commit is contained in:
Mike Brady
2026-06-18 09:27:43 +01:00
committed by GitHub
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);