validate property value bounds in flatgeobuf_decode_properties by nvxbug · Pull Request #7545 · MapServer/MapServer · GitHub
Skip to content

validate property value bounds in flatgeobuf_decode_properties#7545

Open
nvxbug wants to merge 2 commits into
MapServer:mainfrom
nvxbug:fgb-property-bounds
Open

validate property value bounds in flatgeobuf_decode_properties#7545
nvxbug wants to merge 2 commits into
MapServer:mainfrom
nvxbug:fgb-property-bounds

Conversation

@nvxbug

@nvxbug nvxbug commented Jul 1, 2026

Copy link
Copy Markdown

AddressSanitizer, on a crafted .fgb feature whose string property length field claims more bytes than the property blob holds:

READ of size 65536 at 0x60200000... thread T0
    #0 __asan_memcpy
    #1 flatgeobuf_decode_properties src/flatgeobuf/flatgeobuf_c.cpp:229
0x602000... is located 0 bytes after 6-byte region allocated by msSmallMalloc

flatgeobuf_decode_properties walks a feature property blob taken straight from the file (feature->properties()->data()/size()). The loop only checks that the 2-byte column index fits; the value payload is never bounded against size. For fixed-width columns parse_value dereferences up to 8 bytes past the buffer, and for string/datetime the 4-byte len is read with no cap, so msSmallMalloc(len + 1) wraps to 0 when len is 0xFFFFFFFF and the following memcpy runs off the heap.

Pass size into parse_value and bound both the fixed-width read and the string len against the remaining bytes before touching data.

@jmckenna

jmckenna commented Jul 2, 2026

Copy link
Copy Markdown
Member

flatgeobuf_decode_feature ignored the return of
flatgeobuf_decode_properties, so a feature rejected for an out-of-bounds
property length was still handed back with unset values, which crashed
the WFS query path on the NULL value. Propagate the failure so the
feature is skipped.

Add a msautotest case with a one-feature data/flatgeobuf-invalid.fgb
whose string property claims more bytes than the property blob holds; a
WFS GetFeature request now returns a clean service exception instead of
reading past the buffer.
@nvxbug

nvxbug commented Jul 3, 2026

Copy link
Copy Markdown
Author

Added a test under msautotest/misc/. data/flatgeobuf-invalid.fgb is a one-feature file (written with ogr2ogr, then the string property's 4-byte length field patched to claim more bytes than the 8-byte property blob holds), and flatgeobuf-invalid.map runs a WFS GetFeature against it. GDAL's own FlatGeobuf reader rejects that same file, so it exercises exactly the path this PR guards.

While wiring it up I found that flatgeobuf_decode_feature ignored the return of flatgeobuf_decode_properties, so the crafted feature was still handed back with an unset value and segfaulted downstream on the query path. Propagating that failure is in the same commit, and GetFeature now returns a clean service exception (see the expected output). Passes locally via run_test.py.

@jratike80

Copy link
Copy Markdown

@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.

4 participants