bug:Out-of-bounds read in SgiInput::uncompress_rle_channel (bpc==1 RLE "run" branch lacks an input bounds check)
Los mantenedores suelen responder en 2 días
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 80/100
Línea de trabajo
Comienza en src/sgi.imageio/sgiinput.cpp, en SgiInput::uncompress_rle_channel(), centrándote en la rama de ejecución RLE para bpc==1 y comparándola con la comprobación de límites de la rama literal. Ejecuta el poc.sgi adjunto mediante oiiotool bajo ASAN y verifica después que la entrada malformada se rechaza sin una lectura fuera de límites y que las herramientas de imagen afectadas ya no abortan ni informan del fallo del sanitizer.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Summary
While fuzzing oiiotool with AFL++ + ASAN we found that a malformed SGI
(.sgi) file triggers a span out-of-bounds read inside
SgiInput::uncompress_rle_channel(). In builds with contract assertions
enforced (the OIIO 3.x default) the violation aborts the process; in builds
compiled with hardening NONE + NDEBUG the same access is a 1-byte
heap-buffer-overflow read past the rle_scanline allocation.
Still reproduces on current main (dc87b17ab, 2026-09-27).
Reproducer
SGI file, RLE storage, dimension=3, 100x63, 4 channels, bpc=1: poc.sgi
attached (20 KB).
$ oiiotool -i poc.sgi --printinfo
Any of oiiotool / iconvert / iinfo / maketx reading the file hits it;
the crash is in the reader, independent of the tool.
Output
Build: clang 16, -g -O1 -fno-omit-frame-pointer, ASAN, contract
assertions at default (ENFORCE).
src/include/OpenImageIO/span.h:221 (operator[]): Contract assertion failed: idx < m_size
[abort]
With ASAN_OPTIONS=handle_abort=1, the aborting thread stack:
#5 SgiInput::uncompress_rle_channel(long, long, span<unsigned char>) src/sgi.imageio/sgiinput.cpp
#6 SgiInput::read_native_scanline(...) src/sgi.imageio/sgiinput.cpp:211:18
#7 ImageInput::read_native_scanlines(...) src/libOpenImageIO/imageinput.cpp:521:19
Root cause
Current main, src/sgi.imageio/sgiinput.cpp, bpc==1 branch of
uncompress_rle_channel():
while (i < scanline_len) {
unsigned char value = rle_scanline[i++]; // count byte (i < scanline_len OK)
int count = value & 0x7F;
if (!count) break;
if (value & 0x80) { // literal copy
while (count--) {
if (i >= scanline_len || limit <= 0) { // <-- input bound IS checked here (line 286)
errorfmt("Corrupt RLE data"); return false;
}
outbuf[iout++] = rle_scanline[i++];
--limit;
}
} else { // run: repeat next value
value = rle_scanline[i++]; // <-- line 296: NO `i >= scanline_len` check!
while (count--) { ... }
}
}
If the RLE count byte is the last byte of the scanline chunk
(i == scanline_len - 1 at loop top), consuming it advances i to
scanline_len, and the "run" branch then reads rle_scanline[i] one past
the end. The literal branch checks i >= scanline_len (line 286) but the
run branch was missed. The final i != scanline_len sanity check at the end
of the function would have rejected this data — but the OOB read happens
before it.
A minimal fix is mirroring the literal-branch check before line 296:
if (i >= scanline_len) { errorfmt("Corrupt RLE data"); return false; }
value = rle_scanline[i++];
Impact
- Contract assertions enforced (OIIO 3.x default): process abort on a
malformed file — denial of service for CLI tools (oiiotool,iconvert,
iinfo,maketx) and any app using the SGI reader on untrusted input. OIIO_HARDENING_NONE+NDEBUGbuilds: 1-byte heap-buffer-overflow read
past thenew unsigned char[scanline_len]allocation.
Related work
This is in the same function as GHSA-jg3q-vm3q-2j35 / CVE-2026-43903
(fixed in 3.0.18.0 / 3.1.13.0) and #5321 (16-bit odd byte counts), but the
access above is still reachable on current main — it is an
incomplete fix, leaving a remaining unchecked read in the bpc==1 run branch.
Meta
Found by a coverage-guided AFL++ fuzzing campaign (569-file multi-format
seed corpus from the OIIO testsuite) run during verification of #4552 /
CVE-2024-55194. 19 of the campaign's saved crash inputs reproduce this one
bug; the attached PoC is a readily-reproducible one.
Happy to send additional crash inputs or a minimized PoC if useful.
- Lenguaje dominante
- C++
- Estrellas
- 2.4k
- Forks
- 718
- Merge medio
- 2 d 18 h
- PR fusionados (30 d)
- 85
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 AcademySoftwareFoundation/OpenImageIO
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
AcademySoftwareFoundation/OpenImageIO#5662 ·
Los mantenedores suelen responder en 2 días
-
bug: copy() writes destination channels the source does not have, taking the values from past the source's pixelPosiblemente ocupada @lgritz la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 35/100
AcademySoftwareFoundation/OpenImageIO#5661 ·
Los mantenedores suelen responder en 2 días
-
bug: a malformed filename throws std::regex_error out of ImageCache, and catching it deadlocks the file cachePosiblemente ocupada @lgritz la tomó hoy. Abierto
AcademySoftwareFoundation/OpenImageIO#5660 · 1 asignado ·
Los mantenedores suelen responder en 2 días
-
PSD: layers with a "real user supplied layer mask" (channel -3) stored as Raw fail to load ("unsupported compression")Posiblemente ocupada @linsen458-spec la tomó hoy. Abierto
Dificultad 3/5 1-2 días Aptitud para principiantes 72/100
AcademySoftwareFoundation/OpenImageIO#5659 · 1 comentario ·
Los mantenedores suelen responder en 2 días
-
bug: deep paste wraps into the next scanline instead of clipping, and ignores chbeginPosiblemente ocupada @lgritz la tomó hace 2 días. Abierto
Dificultad 4/5 3-5 días Aptitud para principiantes 45/100
AcademySoftwareFoundation/OpenImageIO#5649 ·
Los mantenedores suelen responder en 2 días
Todos los issues de AcademySoftwareFoundation/OpenImageIO
Issues similares
-
documentation enhancement
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
Los mantenedores suelen responder en 1 día
-
enhancement
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
QuantStack/git2cpp#203 ·
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
BaptisteHudyma/Lamp-Da#588 ·
Los mantenedores suelen responder en 1 día
-
bug macOS networking
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
Los mantenedores suelen responder en 2 días
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 85/100
docling-project/docling-parse#448 ·
Los mantenedores suelen responder en 5 días