Source: minidlna Version: 1.3.3+dfsg-1.1 Severity: important Tags: security upstream patch
Hi, CVE-2026-29508 is listed as undetermined and has no Debian bug. It does affect Debian, and I found no upstream fix: the upstream repository's latest commit is from 2023, and tagutils/tagutils-dff.c last changed in 2020. A patch is attached. _get_dfffileinfo() in tagutils/tagutils-dff.c takes the 64-bit PROP chunk size from the file and declares a stack array of that size, with no bound: propckDataSize = GET_DFF_INT64(ckbuf + 4); unsigned char propckData[propckDataSize]; The sub-chunk parsing that follows also reads and advances using sizes from the file without checking them against the chunk. The file is identical in 1.3.3+dfsg-1.1 and 1.3.0+dfsg-2.2+deb12u1. Per the CVE description, a crafted .dff file in a scanned directory is enough to reach it. The patch rejects PROP sizes outside 4..4096 bytes, since the PROP chunks in the files I generated are well under that. It also checks that each sub-chunk read stays inside the chunk. What I checked: the patch applies to both versions. I compiled the parser on its own before and after the patch under ASan/UBSan, against each version's tagutils.h, with small stand-ins for logging. Four valid DFF files that I generated (1, 2 and 6 channels, with and without the optional ABSS and LSCO chunks) gave identical sample rate, channels, bitrate and length before and after, with no sanitizer reports. What I did not test: I did not reproduce the overflow or run oversized or malformed files through the patched code. I also did not do a full package build, or test real-world DFF files, which is the main risk of the 4096-byte limit. Please adjust it if you know of files with larger PROP chunks. Separately, and not addressed by this patch: the DST branch divides by a frame rate taken from the file, without a zero check. Regards, Sumit Verma
Description: Bound the DFF PROP chunk before allocating it on the stack _get_dfffileinfo() declared a variable-length stack array from the 64-bit PROP chunk size in the file. Reject sizes outside 4..4096 bytes, and check that each sub-chunk read stays inside the chunk. Author: Sumit Verma <[email protected]> Bug-Debian-Security: CVE-2026-29508 Forwarded: no Last-Update: 2026-11-08 --- --- a/tagutils/tagutils-dff.c +++ b/tagutils/tagutils-dff.c @@ -36,6 +36,9 @@ #define GET_DFF_INT16(p) ((((uint16_t)((p)[0])) << 8) | \ (((uint16_t)((p)[1])))) +/* A real PROP chunk is a few hundred bytes at most, and it lives on the stack */ +#define DFF_MAX_PROP_SIZE 4096 + static int _get_dfffileinfo(char *file, struct song_metadata *psong) { @@ -125,6 +128,12 @@ if (strncmp((char*)ckbuf, "PROP", 4) == 0) { propckDataSize = GET_DFF_INT64(ckbuf + 4); + if (propckDataSize < 4 || propckDataSize > DFF_MAX_PROP_SIZE) + { + DPRINTF(E_WARN, L_SCANNER, "Invalid Property chunk size in %s\n", file); + fclose(fp); + return -1; + } totalcount += propckDataSize + 12; unsigned char propckData[propckDataSize]; @@ -144,11 +153,13 @@ } count += 4; - while (count < propckDataSize) + while (count + 12 <= propckDataSize) { if (strncmp((char*)propckData + count, "FS ", 4) == 0) { //Sample Rate Chunk + if (count + 16 > propckDataSize) + break; count += 12; samplerate = GET_DFF_INT32(propckData + count); psong->samplerate = samplerate; @@ -159,6 +170,8 @@ else if (strncmp((char*)propckData + count, "CHNL", 4) == 0) { //Channels Chunk + if (count + 14 > propckDataSize) + break; count += 12; channels = GET_DFF_INT16(propckData + count); psong->channels = channels; @@ -169,8 +182,12 @@ else if (strncmp((char*)propckData + count, "CMPR", 4) == 0) { //Compression Type Chunk + if (count + 16 > propckDataSize) + break; count += 4; cmprckDataSize = GET_DFF_INT64(propckData + count); + if (cmprckDataSize > propckDataSize) + break; count += 8; memcpy(compressionType, propckData + count, 4); count += cmprckDataSize; @@ -180,6 +197,8 @@ //Absolute Start Time Chunk count += 4; abssckDataSize = GET_DFF_INT64(propckData + count); + if (abssckDataSize > propckDataSize) + break; count += abssckDataSize + 8; } else if (strncmp((char*)propckData + count, "LSCO", 4) == 0) @@ -187,6 +206,8 @@ //Loudsperaker Configuration Chunk count += 4; lscockDataSize = GET_DFF_INT64(propckData + count); + if (lscockDataSize > propckDataSize) + break; count += lscockDataSize + 8; } else

