fix(postgis): patch CVE-2026-73514 / CVE-2026-73515 and gate vulnerable builds - #16
Merged
Merged
Conversation
Build PostGIS from 3.6.4 with the four upstream security commits applied as patch files, and gate every build on a check that the installed extension is not vulnerable.
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The published
constructiveio/postgres-plus:18ships PostGIS 3.6.2, and that build is exploitable from plain SQL today — on the current image, an 8-byte bytea takes the backend down:That matters beyond the image, because
postgisis a hardrequiresof theconstructiveandmetaschemaextensions, PostGIS grantsEXECUTEonST_FromFlatGeobuftoPUBLIC, and both proxy SQL-filter presets allow the call. So the decoder is reachable by any tenant with SQL-lane access.Fix is
POSTGIS_VERSION 3.6.2 → 3.6.4pluspatches/, because no released tarball carries either fix — not 3.6.4, and not the 3.7.0beta2 line for the standardizer. Each patch is agit format-patchof the upstream commit cherry-picked onto the3.6.4tag:0001-flatgeobuf-validate-input-buffers-before-decodingpostgis/stable-3.653e273fae, landed after 3.6.4 — CVE-2026-73515. 3.6.4's release note ("Flatgeobuf schema mismatch vulnerability") is the earlier70d46a679, which does not cover truncated buffers.0002-address_standardizer-harden-scanner-and-rule-parsingstable-3.61ce0012b7; verified byte-equivalent (one blank line) toeda92ce/423570bin the split-outpostgis/address_standardizerrepo, which is where the CVE-2026-73514 fix now lives since master dropped the in-tree extension.0003-address_standardizer-clean-up-partial-2D-allocationsstable-3.6c38c87319.0004-Avoid-out-of-bounds-write-uninitialized-memory5964d6f1a, the actual off-by-one:parse_rule()wroterule_arr[nr]before the bound test, so a 129-token rule wrote pastrule_arr[MAX_RULE_LENGTH]. Present only onstable-3.2/3.3, i.e. absent from every 3.6 tarball.Two conflicts in
0001were resolved in favour of 3.6.4's datum semantics while taking the fix's endian-safe reads (UInt32GetDatumand theFLOAT8OIDcoercion kept;memcpy→flatgeobuf_read_le32/flatgeobuf_read_float_le).patchruns without--force, so a patch that stops applying fails the build instead of being silently skipped — the failure mode that matters when the tarball moves.The gate
scripts/verify-postgis-security.sh <container>interrogates the installed extension, never a Dockerfile ARG or a tag (tags move, and the version alone can't distinguish a patched 3.6.4 from a plain one):pg_extension.extversion >= POSTGIS_MIN_VERSION(3.6.4),/usr/local/share/postgresql/security/postgis-patches.txtrecords both CVE ids,SELECT 1still answers on a fresh connection — the functional proof, and what fails loudly on an unpatched build,standardize_address()still returns a parse, so the standardizer hardening didn't break it.Wired into
make testand into CI on both paths: on a PR the amd64 build isloaded and verified; on push it runs against the pushed digest beforepublish-postgres-plus-manifest, so a vulnerable build can never havelatest/18moved onto it.Verified locally:
make testpasses on the patched image, and the same script fails on the published one withFAIL: postgis 3.6.2 is below the patched floor 3.6.4.Merging and republishing
18is what actually remediates the platform; a follow-up PR inconstructive-dbadds a matching gate and blocks the FlatGeobuf decoders in the proxy presets as defence in depth.Link to Devin session: https://app.devin.ai/sessions/ef16f622f23747b38e801ae0aa1ae1a7
Requested by: @pyramation