[BUG] DVB subtitle decoder: heap-buffer-overflow write in dvbsub_parse_clut_segment via unbounded entry_id
Los mantenedores suelen responder en 2 días
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 72/100
Línea de trabajo
Empieza en dvbsub_parse_clut_segment() en src/lib_ccx/dvb_subtitle_decoder.c, donde entry_id indexa los arrays clut4, ilut4, clut16 e ilut16 de DVBSubCLUT sin comprobación de rango. Lee la definición de la estructura DVBSubCLUT para confirmar los tamaños de los arrays. Se considera terminado cuando cada rama de 2 bits y de 4 bits rechaza un entry_id fuera de rango antes de escribir, y un segmento CLUT manipulado ya no corrompe la memoria. Como se trata de un informe de seguridad, consulta con los mantenedores cómo deben gestionarse la corrección y cualquier prueba.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Summary
In src/lib_ccx/dvb_subtitle_decoder.c, dvbsub_parse_clut_segment() writes palette entries into fixed-size arrays (clut4, ilut4, clut16, ilut16) using the stream-supplied entry_id byte without verifying that entry_id fits within the array bounds.
When a DVB subtitle stream declares 2-bit depth (depth & 0x80) or 4-bit depth (depth & 0x40), an entry_id >= 4 or entry_id >= 16 causes an out-of-bounds write on the heap, corrupting adjacent members of DVBSubCLUT including the clut->next heap linked-list pointer.
Vulnerability Details
- Affected file:
src/lib_ccx/dvb_subtitle_decoder.c - Function:
dvbsub_parse_clut_segment() - CWE: CWE-787: Out-of-bounds Write (Heap-based Buffer Overflow)
DVBSubCLUT is defined as:
typedef struct DVBSubCLUT
{
int id;
int version;
uint32_t clut4[4]; // 2-bit palette: 4 entries (indices 0..3)
uint32_t clut16[16]; // 4-bit palette: 16 entries (indices 0..15)
uint32_t clut256[256];
uint8_t ilut4[4]; // 2-bit luma: 4 entries (indices 0..3)
uint8_t ilut16[16]; // 4-bit luma: 16 entries (indices 0..15)
uint8_t ilut256[256];
struct DVBSubCLUT *next; // heap linked-list pointer
} DVBSubCLUT;
In dvbsub_parse_clut_segment():
while (buf + 4 < buf_end)
{
entry_id = *buf++; // stream-supplied byte (0..255)
depth = (*buf) & 0xe0;
...
if (depth & 0x80) // 2-bit CLUT
{
clut->clut4[entry_id] = RGBA(r, g, b, 255 - alpha); // OOB write if entry_id >= 4
clut->ilut4[entry_id] = y; // OOB write if entry_id >= 4
}
else if (depth & 0x40) // 4-bit CLUT
{
clut->clut16[entry_id] = RGBA(r, g, b, 255 - alpha); // OOB write if entry_id >= 16
clut->ilut16[entry_id] = y; // OOB write if entry_id >= 16
}
else if (depth & 0x20)
{
clut->clut256[entry_id] = RGBA(r, g, b, 255 - alpha);
clut->ilut256[entry_id] = y;
}
}
- 2-bit CLUT (
depth & 0x80):clut4andilut4have only 4 elements. Ifentry_idis between 4 and 255,clut->clut4[entry_id]writes past the allocated space. - 4-bit CLUT (
depth & 0x40):clut16andilut16have only 16 elements. Ifentry_idis between 16 and 255,clut->clut16[entry_id]writes past the allocated space. - In both cases, the out-of-bounds write overwrites the heap next pointer (
clut->next), leading to crashes or memory corruption during subsequent list traversal or cleanup indvbsub_free().
Reachability
In standard MPEG transport streams with DVB subtitles (stream type 0x06 and DVB subtitling descriptor 0x59), PES packets carrying subtitle segment type 0x12 (DVB_SUB_SEGMENT_CLUT) are decoded by dvbsub_decode() in src/lib_ccx/dvb_subtitle_decoder.c, reaching dvbsub_parse_clut_segment() on the default configuration.
Suggested Fix
Add bounds validation for entry_id against the palette capacity for both 2-bit and 4-bit entries:
--- a/src/lib_ccx/dvb_subtitle_decoder.c
+++ b/src/lib_ccx/dvb_subtitle_decoder.c
@@ -1216,11 +1216,21 @@ static int dvbsub_parse_clut_segment(void *dvb_ctx, const uint8_t *buf,
if (depth & 0x80)
{
+ if (entry_id >= 4)
+ {
+ mprint("dvbsub_parse_clut_segment(): entry_id %d exceeds 2-bit CLUT bounds\n", entry_id);
+ return -1;
+ }
clut->clut4[entry_id] = RGBA(r, g, b, 255 - alpha);
clut->ilut4[entry_id] = y;
}
else if (depth & 0x40)
{
+ if (entry_id >= 16)
+ {
+ mprint("dvbsub_parse_clut_segment(): entry_id %d exceeds 4-bit CLUT bounds\n", entry_id);
+ return -1;
+ }
clut->clut16[entry_id] = RGBA(r, g, b, 255 - alpha);
clut->ilut16[entry_id] = y;
}
- Lenguaje dominante
- C
- Estrellas
- 912
- Forks
- 598
- Merge medio
- 1 d 23 h
- PR fusionados (30 d)
- 25
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de CCExtractor/ccextractor
-
Heap OOB read in parse_ad_cdp: cc_count not bounded by packet lengthPosiblemente ocupada @Anurag-S1ngh la tomó hace 2 días. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
CCExtractor/ccextractor#2425 · 3 comentarios ·
Los mantenedores suelen responder en 2 días
-
[BUG] Heap buffer overflow in parse_PMT with C0/C1 section lengthPosiblemente ocupada @kun-codes la tomó hace 11 días. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
CCExtractor/ccextractor#2419 ·
Los mantenedores suelen responder en 2 días
-
[BUG] Filename sequence expansion (`+`) panics on numeric values exceeding `i32::MAX`Posiblemente ocupada @muntasir-396 la tomó hace 14 días. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
CCExtractor/ccextractor#2402 ·
Los mantenedores suelen responder en 2 días
-
Dificultad 3/5 1-2 días Aptitud para principiantes 18/100
CCExtractor/ccextractor#2447 ·
Los mantenedores suelen responder en 2 días
-
Dificultad 4/5 3-5 días Aptitud para principiantes 15/100
CCExtractor/ccextractor#2446 ·
Los mantenedores suelen responder en 2 días
Todos los issues de CCExtractor/ccextractor
Issues similares
-
examples/dnsdoctor: cleanup.sh stops at the first missing piece of a setup.sh that did not finishAbiertoseverity: low
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
luainkernel/lunatik#2263 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 Medio día Aptitud para principiantes 72/100
vercel-labs/scriptc#2910 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
darktable-org/darktable#22939 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 82/100
espressif/idf-extra-components#903 ·
Los mantenedores suelen responder en 1 día
-
os: input_password leaves terminal echo disabled when reading failsPosiblemente ocupada @davlgd la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
Los mantenedores suelen responder en 1 día