bound gif palette index reads to the color table size by nvxbug · Pull Request #7541 · MapServer/MapServer · GitHub
Skip to content

bound gif palette index reads to the color table size#7541

Open
nvxbug wants to merge 3 commits into
MapServer:mainfrom
nvxbug:gif-palette-bounds
Open

bound gif palette index reads to the color table size#7541
nvxbug wants to merge 3 commits into
MapServer:mainfrom
nvxbug:gif-palette-bounds

Conversation

@nvxbug

@nvxbug nvxbug commented Jun 24, 2026

Copy link
Copy Markdown

readGIF in mapimageio.c indexes the global color table with values taken straight from the file: image->SBackGroundColor for the initial background fill, and the decoded pixel value for every image pixel. giflib does not check either against the table size, so a GIF whose background index or pixel values are larger than the palette walks past cmap->Colors and reads out of bounds. A 2-color global table with a background index of 255 reproduces it, with ASAN reporting a heap read 759 bytes past the color table.

Clamp the background index and skip palette lookups for pixel values that fall outside cmap->ColorCount, rendering those as transparent like the existing transparent-index branch. The check sits in the decoder because the indices come from the file and nothing upstream knows the table size.

@jmckenna

Copy link
Copy Markdown
Member

@nvxbug

nvxbug commented Jun 29, 2026

Copy link
Copy Markdown
Author

Added a test under renderers (gif_palette_bounds.map). It runs two crafted GIFs through readGIF via mapserv: one with a background index past the 2-entry palette, and one with no color map at all. Both come back as the deterministic error page, so they compare cleanly, and under the --run_under_asan job the unpatched decoder trips the heap-buffer-overflow on the background fill before the message ever gets produced. Put the .gif fixtures in misc/data and the expected output in renderers/expected.

@jmckenna

jmckenna commented Jul 3, 2026

Copy link
Copy Markdown
Member

Thanks @nvxbug, your new tests are failing, please make sure that the tests pass.

The no-colormap and img-size-exceeds-screen error paths returned without
releasing the pixel buffer or the giflib handle, so the regression GIFs
tripped LeakSanitizer under the ASAN test job. Release both before
returning.
@nvxbug

nvxbug commented Jul 4, 2026

Copy link
Copy Markdown
Author

Tracked it down: the two error paths those fixtures hit (no color map, and img size exceeds screen) were returning without freeing the pixel buffer or closing the giflib handle, so under the ASAN job LeakSanitizer flagged a leak and the process bailed before the error page got written out, which is why the results looked like a mismatch. Pushed a fix that releases both before returning on those paths. Both GIFs now come back with their error page cleanly under ASAN.

@rouault

rouault commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

@rouault rouault added Security backport branch-8-6 To backport a pull request to branch-8-6 labels Jul 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport branch-8-6 To backport a pull request to branch-8-6 Feedback requested Security

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants