[Security] Heap buffer overflow in cpStripToTile (geotifcp.c:944) when strip/tile geometry is inconsistent
I maintainer di solito rispondono entro 2 giorni
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 15/100
Direzione di ricerca
Start with the copy loop at bin/geotifcp.c:944 (cpStripToTile), reached from readContigTilesIntoBuffer (around line 1062) and writeBufferToContigTiles (around line 1194). Build with AddressSanitizer and run the attached crash-input.bin to reproduce the heap-buffer-overflow, then check that negative-control.bin still converts cleanly. Done means the geometry is validated against the buffer sizes so the PoC no longer triggers ASan, with the sibling copy helpers covered too.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
[Security] Heap buffer overflow in cpStripToTile (geotifcp.c:944) when strip/tile geometry is inconsistent
2. Summary
A crafted GeoTIFF with inconsistent strip/tile geometry triggers a heap buffer overflow in cpStripToTile() (bin/geotifcp.c:944) while the geotifcp utility copies image data between tiled and strip layouts. The copy loop at geotifcp.c:944 ("*out++ = *in++;") reads and writes "rows x cols" bytes where rows/cols and the skew offsets are computed from the input file's strip/tile geometry tags without validating them against the allocated buffer sizes; with mismatched geometry the copy runs past the end of a heap buffer. AddressSanitizer consistently reports a heap-buffer-overflow at geotifcp.c:944 in cpStripToTile (with the attached PoC: READ of size 16, 1 byte to the right of a 14-byte region, reached via readContigTilesIntoBuffer); an earlier verification run with a closely related sample from the same fuzzing corpus hit the WRITE manifestation of the same loop (WRITE of size 1 past a 384-byte region, via writeBufferToContigTiles). The same unchecked copy pattern recurs in cpContigBufToSeparateBuf (geotifcp.c:957), cpSeparateBufToContigBuf (geotifcp.c:970), readSeparateStripsIntoBuffer (geotifcp.c:1026) and writeBufferToSeparateStrips (geotifcp.c:1154), which should be hardened together.
3. Affected version / environment
- Repository: https://github.com/OSGeo/libgeotiff
- Tested commit: master @ 75cfca539667c6483e796b24b78ecef72e311a1a (commit date 2026-08-11; tree cloned 2026-10-26)
- Component: libgeotiff/bin/geotifcp.c (cpStripToTile copy loop, line 944), reached via readContigTilesIntoBuffer (line 1062) / writeBufferToContigTiles (line 1194) through cpContigTiles2ContigTiles (line 1312) and tiffcp (line 726)
- Build: AddressSanitizer-instrumented build of the geotifcp CLI (/lh/libgeotiff/install/bin/geotifcp in the verification container)
- Platform: x86_64 Linux (Docker container); no release tarball was tested, so the set of affected released versions is [unknown]
4. Steps to reproduce
1. Build libgeotiff (master, commit 75cfca539667c6483e796b24b78ecef72e311a1a or current master) with AddressSanitizer, e.g. configure CMake with -DCMAKE_C_FLAGS="-fsanitize=address -g -O1" and build the geotifcp utility.
2. Save the attached crash-input.bin (SHA256 3ec73a9620dbcd4b216df8834f9ee66341757dbc37c619dda2382a48b3268784) to disk.
3. Run: geotifcp /path/to/crash-input.bin /tmp/out.tif
4. Observe the AddressSanitizer report below (exit status 1); the crash is deterministic (reproduced on every run with this input).
5. Sanity check: run geotifcp on the attached negative-control.bin (SHA256 a1547229797c73cbaea8147138cdb58b5b8147dd72be7e6c556a57d64ff32fe7); it completes with only its benign "mode=w" output and no sanitizer report, confirming the crash comes from the crafted content and not from the environment.
5. Expected behavior
geotifcp either converts the file or fails gracefully on malformed input; no memory-safety error occurs for any input file, regardless of the strip/tile geometry declared in its tags.
6. Actual behavior
AddressSanitizer aborts geotifcp with a heap-buffer-overflow in cpStripToTile at geotifcp.c:944. Full report from a fresh run with the attached PoC (2026-11-02):
TIFFReadDirectoryCheckOrder: Warning, Invalid TIFF directory; tags are not sorted in ascending order.
TIFFReadDirectory: Warning, Unknown field with tag 65308 (0xff1c) encountered.
/lh/tmp/poc-export/geo-cpstrip/crash-input.bin: Warning, Nonstandard tile width 1, convert file.
TIFFFetchNormalTag: Warning, ASCII value for tag "Tag 65308" does not end in null byte. Forcing it to be null.
TIFFFetchNormalTag: Warning, ASCII value for tag "GeoASCIIParams" does not end in null byte.
TIFFFetchStripThing: Warning, Incorrect count for "StripOffsets"; tag ignored.
TIFFReadDirectory: Warning, Wrong "StripByteCounts" field, ignoring and calculating from imagelength.
Error: Key 25957 of unknown type.
=================================================================
==573133==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020000081bf at pc 0x559f87125942 bp 0x7fff94ca3330 sp 0x7fff94ca3328
READ of size 16 at 0x6020000081bf thread T0
#0 0x559f87125941 in cpStripToTile /lh/libgeotiff/src/libgeotiff/bin/geotifcp.c:944:13
#1 0x559f87125941 in readContigTilesIntoBuffer /lh/libgeotiff/src/libgeotiff/bin/geotifcp.c:1062:5
#2 0x559f8711a4ba in cpImage /lh/libgeotiff/src/libgeotiff/bin/geotifcp.c:984:3
#3 0x559f8711a4ba in cpContigTiles2ContigTiles /lh/libgeotiff/src/libgeotiff/bin/geotifcp.c:1312:9
#4 0x559f871175d5 in tiffcp /lh/libgeotiff/src/libgeotiff/bin/geotifcp.c:726:15
#5 0x559f871175d5 in main /lh/libgeotiff/src/libgeotiff/bin/geotifcp.c:224:9
#6 0x7f74dca30d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#7 0x7f74dca30e3f in __libc_start_main csu/../csu/libc-start.c:392:3
#8 0x559f87054714 in _start (/lh/libgeotiff/install/bin/geotifcp+0x6e714) (BuildId: ab7b038c23bd2d0e08453df2b444529662534d08)
0x6020000081bf is located 1 bytes to the right of 14-byte region [0x6020000081b0,0x6020000081be)
allocated by thread T0 here:
#0 0x559f870d753b in malloc (/lh/libgeotiff/install/bin/geotifcp+0xf153b) (BuildId: ab7b038c23bd2d0e08453df2b444529662534d08)
SUMMARY: AddressSanitizer: heap-buffer-overflow /lh/libgeotiff/src/libgeotiff/bin/geotifcp.c:944:13 in cpStripToTile
==573133==ABORTING
(Addresses are ASLR-dependent and differ between runs; the report was reproduced consistently on every run with this input. For completeness: an earlier verification run, using the original fuzzer crash sample from the same corpus rather than the attached PoC, aborted at the same line with the WRITE manifestation of this loop - "WRITE of size 1" at geotifcp.c:944:11 via writeBufferToContigTiles (geotifcp.c:1194), 0 bytes to the right of a 384-byte region allocated in writeBufferToContigTiles (geotifcp.c:1171). Both are the same unchecked copy loop overflowing whichever buffer bound is exceeded first.)
7. Impact
geotifcp is a command-line GeoTIFF conversion utility, so exploitation requires a scenario where the tool runs on attacker-supplied input (for example automated raster ingest pipelines that convert uploaded or downloaded GeoTIFFs with geotifcp). The unchecked copy loop overflows a heap buffer whose size is derived from the file's declared geometry: the verified manifestation is an out-of-bounds read past a heap allocation (which can leak adjacent heap contents into the converted output file), and the same loop can also perform an out-of-bounds write when the destination bound is exceeded first (observed with a closely related sample: WRITE of size 1 past a 384-byte region). At minimum this is a deterministic denial of service for any pipeline converting untrusted GeoTIFFs with geotifcp; the out-of-bounds write variant is a potential path to code execution.
8. Suggested fix
- Validate the strip/tile geometry of the input against the allocated buffer sizes before the copy: in readContigTilesIntoBuffer (bin/geotifcp.c, around lines 1040-1070) and writeBufferToContigTiles (around lines 1160-1210), clamp nrow/width (or tilew) to what the destination buffer at bufp/obuf and the source tilebuf can actually hold, instead of trusting TIFFTileRowSize/TIFFScanlineSize-derived values that come from attacker-controlled tags.
- Apply the same bounds validation to the sibling copy helpers that share the unchecked pattern: cpContigBufToSeparateBuf (geotifcp.c:957), cpSeparateBufToContigBuf (geotifcp.c:970), readSeparateStripsIntoBuffer (geotifcp.c:1026) and writeBufferToSeparateStrips (geotifcp.c:1154).
- As defense in depth, reject (or error out on) inconsistent combinations such as "Nonstandard tile width 1" together with wrong StripByteCounts/StripOffsets counts instead of only warning.
9. Additional context
- Attachments: crash-input.bin (trigger sample) and negative-control.bin (benign file that differs only in the crafted fields) with their SHA256SUMS files.
- The trigger file declares inconsistent strip/tile geometry (nonstandard tile width 1, incorrect StripOffsets/StripByteCounts counts, unknown field tag 65308), which is exactly the condition the unchecked copy path does not validate.
- Environment note: the crash was observed and re-verified in an ASAN-instrumented Docker build of the project; the commands above reproduce it in any ASAN build of the same commit.
- Lingua principale
- C
- Stelle
- 912
- Fork
- 598
- Merge medio
- 1g 10h
- PR unite (30g)
- 24
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di CCExtractor/ccextractor
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
CCExtractor/ccextractor#2449 ·
I maintainer di solito rispondono entro 2 giorni
-
[BUG] DVB subtitle decoder: heap-buffer-overflow write in dvbsub_parse_clut_segment via unbounded entry_idForse già presa @Aditya-Saroha l’ha presa 2 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
CCExtractor/ccextractor#2440 ·
I maintainer di solito rispondono entro 2 giorni
-
Heap OOB read in parse_ad_cdp: cc_count not bounded by packet lengthForse già presa @Anurag-S1ngh l’ha presa 3 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
CCExtractor/ccextractor#2425 · 3 commenti ·
I maintainer di solito rispondono entro 2 giorni
-
[BUG] Heap buffer overflow in parse_PMT with C0/C1 section lengthForse già presa @kun-codes l’ha presa 12 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
CCExtractor/ccextractor#2419 ·
I maintainer di solito rispondono entro 2 giorni
-
[BUG] Filename sequence expansion (`+`) panics on numeric values exceeding `i32::MAX`Forse già presa @muntasir-396 l’ha presa 15 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
CCExtractor/ccextractor#2402 ·
I maintainer di solito rispondono entro 2 giorni
Tutte le issue di CCExtractor/ccextractor
Issue simili
-
bug core p3
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
RunanywhereAI/runanywhere-sdks#1258 ·
I maintainer di solito rispondono entro 1 giorno
-
Plugin mapper: latency_samples is 0 for eight UAD 11.8.3 plug-ins that delay by 55-56 samplesAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
rolotrealanis98/open-apollo#126 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
cython/cython#8110 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
onehumanbeing/esp32-iphone-agent#62 ·
I maintainer di solito rispondono entro 1 giorno
-
ai-driven-fuzzing bug claude Minor
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
linagora/open-bastion#425 ·
I maintainer di solito rispondono entro 1 giorno