[SCM] PostGIS branch master updated. 3.7.0beta2-17-g46203ec75

git at osgeo.org git at osgeo.org
Mon Aug 10 14:52:59 PDT 2026


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "PostGIS".

The branch, master has been updated
       via  46203ec75913d646be780030819af6a6578d6718 (commit)
       via  bd9e37cbd125c528313730b1fba52098b0c670ec (commit)
      from  9e382377bc054c59b4ed4a0d8c431c82e2e86590 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 46203ec75913d646be780030819af6a6578d6718
Merge: 9e382377b bd9e37cbd
Author: Darafei Praliaskouski <komzpa at gmail.com>
Date:   Mon Aug 10 14:52:58 2026 -0700

    Merge pull request 'fuzzers: allocate GSERIALIZED bytea inputs by declared size' (!723) from Komzpa/postgis:fix/ossfuzz-gserialized-gbox-544807008 into master
    
    The GSERIALIZED bytea fuzzer intentionally preserves the hostile varlena size header so malformed declared-size cases still reach the deserializer. When a testcase is shorter than that declared size, UBSAN builds do not provide allocator-size metadata, so the harness could manufacture a short allocation that the parser had no way to distinguish from the declared buffer.
    
    Allocate and zero-fill the fuzzer copy up to a bounded declared GSERIALIZED size while leaving the input header untouched. That keeps the malformed-header coverage but lets the parser validate the declared buffer instead of the UBSAN harness reading past its allocation.
    
    Credit to OSS-Fuzz: https://issues.oss-fuzz.com/issues/544807008
    
    Reviewed-on: https://gitea.osgeo.org/postgis/postgis/pulls/723


commit bd9e37cbd125c528313730b1fba52098b0c670ec
Author: Darafei Praliaskouski <me at komzpa.net>
Date:   Tue Aug 11 01:44:50 2026 +0400

    fuzzers: allocate GSERIALIZED bytea inputs by declared size
    
    Keep the hostile varlena size header intact, but allocate and zero-fill the fuzzer buffer up to the bounded declared size when the testcase bytes are shorter. This lets UBSAN builds exercise parser validation without walking past the fuzzer allocation.
    
    Credit to OSS-Fuzz: https://issues.oss-fuzz.com/issues/544807008

diff --git a/NEWS b/NEWS
index 258077332..59a5c27c8 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,8 @@ These are only changes since 3.7.0beta2.
 
 * Bug Fixes *
 
+ - OSSFuzz 5607611131822080, keep GSERIALIZED bytea fuzzer allocations
+          consistent with hostile varlena size headers (Darafei Praliaskouski)
  - OSSFuzz 6152109301760000, reject overlong encoded polyline coordinate
           varints (Darafei Praliaskouski)
 
diff --git a/fuzzers/gserialized_from_bytea_fuzzer.cpp b/fuzzers/gserialized_from_bytea_fuzzer.cpp
index 087f97d3e..a62fb1c71 100644
--- a/fuzzers/gserialized_from_bytea_fuzzer.cpp
+++ b/fuzzers/gserialized_from_bytea_fuzzer.cpp
@@ -35,6 +35,8 @@ LLVMFuzzerInitialize(int * /*argc*/, char *** /*argv*/)
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len);
 
+static const size_t POSTGIS_FUZZER_MAX_GSERIALIZED_SIZE = 16 * 1024 * 1024;
+
 static void
 postgis_fuzzer_assert(int condition)
 {
@@ -99,17 +101,25 @@ LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)
 		return 0;
 	}
 
-	/* Copy exactly the bytes supplied by the fuzzer and leave g->size
-	 * untouched. The first four bytes are the PostgreSQL varlena size
-	 * header read through LWSIZE_GET(), and they are attacker-controlled
-	 * when GSERIALIZED arrives from a damaged page, binary COPY, bytea cast,
-	 * or hostile dump. Rewriting the header to len would make every input
-	 * self-consistent and hide the over-declared-size cases this target is
-	 * meant to exercise.
+	uint32_t size_header;
+	memcpy(&size_header, buf, sizeof(size_header));
+	const size_t declared_size = LWSIZE_GET(size_header);
+	if (declared_size > POSTGIS_FUZZER_MAX_GSERIALIZED_SIZE)
+		return 0;
+
+	const size_t allocation_size = declared_size > len ? declared_size : len;
+
+	/* Leave the varlena size header untouched. The first four bytes are
+	 * attacker-controlled when GSERIALIZED arrives from a damaged page,
+	 * binary COPY, bytea cast, or hostile dump. When the declared size is
+	 * larger than the supplied testcase, zero-fill the missing tail so the
+	 * parser can validate the declared buffer without UBSAN builds reading
+	 * past the fuzzer allocation.
 	 */
-	GSERIALIZED *gserialized = static_cast<GSERIALIZED *>(postgis_lwgeom_fuzzer_malloc(len));
+	GSERIALIZED *gserialized = static_cast<GSERIALIZED *>(postgis_lwgeom_fuzzer_malloc(allocation_size));
 	if (gserialized == NULL)
 		return 0;
+	memset(gserialized, 0, allocation_size);
 	memcpy(gserialized, buf, len);
 
 	LWGEOM *lwgeom = lwgeom_from_gserialized(gserialized);

-----------------------------------------------------------------------

Summary of changes:
 NEWS                                      |  2 ++
 fuzzers/gserialized_from_bytea_fuzzer.cpp | 26 ++++++++++++++++++--------
 2 files changed, 20 insertions(+), 8 deletions(-)


hooks/post-receive
-- 
PostGIS


More information about the postgis-tickets mailing list