[SCM] PostGIS branch master updated. 3.6.0rc2-321-g46bf88378

git at osgeo.org git at osgeo.org
Tue Jan 27 13:24:11 PST 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  46bf883788e74c678f6eaa13df7e63e04d790165 (commit)
      from  c6e7bc8e4381194f3bac5b7cc0a30e30b7cd346c (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 46bf883788e74c678f6eaa13df7e63e04d790165
Author: bdreiss <bd_reiss at gmx.at>
Date:   Tue Jan 27 12:39:28 2026 -0800

    The geodetic flag was queried after gser has been freed
    
    ################################################### BUG REPORT ##################################################
    
    ### DESCRITPION ###
    
    The geodetic flag was queried after gser has been freed in line 143, leading to a use-after-free bug. This means the behaviour is undefined and it is not clear, which branch will be taken (and therefor, whether geometry or geography is returned). Below you find the output from gdb can be seen, that confirms that a) the point is indeed inserted with the wrong flag and b) also after selecting the point from the table remains unset. Issues when using SQL could not be produced.
    
    ### SETUP IN PG ###
    
    CREATE EXTENSION postgis;
    CREATE TABLE test_geog (id SERIAL PRIMARY KEY, geog geography(POINT, 4326));
    INSERT INTO test_geog (geog) VALUES (ST_GeogFromText('SRID=4326;POINT(-77.0092 38.889588)'));
    
    ### GDB OUPUT AND STEPS TO REPRODUCE ###
    
    postgres at localhost:~$ gdb --args /usr/local/pgsql/bin/postgres --single -D $PGDATA postgres
    (gdb) break gserialized_typmod.c:143
    (gdb) break gserialized_typmod.c:150
    (gdb) break geography_out
    (gdb) run
    backend> INSERT INTO test_geog (geog) VALUES (ST_GeogFromText('SRID=4326;MULTIPOINT EMPTY'));
    Breakpoint 1, postgis_valid_typmod (gser=0x58f991a3f378, typmod=1107460) at gserialized_typmod.c:143
    143     gserialized_typmod.c: No such file or directory.
    (gdb) call gserialized_is_geodetic(gser)
    $1 = 1
    (gdb) c
    Continuing.
    
    Breakpoint 2, postgis_valid_typmod (gser=0x58f991a8e150, typmod=1107460) at gserialized_typmod.c:151
    151     in gserialized_typmod.c
    (gdb) call gserialized_is_geodetic(gser)
    $2 = 0
    (gdb) c
    Continuing.
    backend>
    backend> INSERT INTO test_geog (geog) VALUES (ST_GeogFromText('SRID=4326;POINT(-77.0092 38.889588)'));
    
    Breakpoint 2, postgis_valid_typmod (gser=0x58f991a3dca8, typmod=1107460) at gserialized_typmod.c:151
    151     in gserialized_typmod.c
    (gdb) call gserialized_is_geodetic(gser)
    $4 = 1
    (gdb) c
    Continuing.
    backend>
    backend> select geog from test_geog where id=1;
             1: geog        (typeid = 14296, len = -1, typmod = 1107460, byval = f)
            ----
    
    Breakpoint 3, geography_out (fcinfo=0x7ffe871b40e0) at /usr/local/pgsql/include/server/postgres.h:319
    319             return (Pointer) X;
    (gdb) set $gser = (GSERIALIZED *) pg_detoast_datum((void *) fcinfo->args[0].value)
    (gdb) call gserialized_is_geodetic($gser)
    $7 = 0
    (gdb) c
    Continuing.
             1: geog = "0101000020E6100000000000000000F87F000000000000F87F" (typeid = 14296, len = -1, typmod = 1107460, byval = f)
            ----
    backend> select geog from test_geog where id=2;
             1: geog        (typeid = 14296, len = -1, typmod = 1107460, byval = f)
            ----
    
    Breakpoint 3, geography_out (fcinfo=0x7ffe871b40e0) at /usr/local/pgsql/include/server/postgres.h:319
    319             return (Pointer) X;
    (gdb) set $gser = (GSERIALIZED *) pg_detoast_datum((void *) fcinfo->args[0].value)
    (gdb) call gserialized_is_geodetic($gser)
    $8 = 1
    (gdb) c
    Continuing.
             1: geog = "0101000020E6100000E3C798BB964053C000750305DE714340" (typeid = 14296, len = -1, typmod = 1107460, byval = f)
            ----
    backend>
    
    ### INFO ###
    
    postgres=# SELECT version();
                                                  version
    ---------------------------------------------------------------------------------------------------
     PostgreSQL 18.1 on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14+deb12u1) 12.2.0, 64-bit
    (1 row)
    
    postgres=# SELECT postgis_full_version();
                                                                                                                                                                     postgis_full_version
    
    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    ---------------------------------------------------------------------------------------------------------------------------------------------------------------
     POSTGIS="3.6.1 f533623" [EXTENSION] PGSQL="180" GEOS="3.11.1-CAPI-1.17.1" PROJ="9.1.1 NETWORK_ENABLED=OFF URL_ENDPOINT=https://cdn.proj.org USER_WRITABLE_DIRECTORY=/home/postgres/.loc
    al/share/proj DATABASE_PATH=/usr/share/proj/proj.db" (compiled against PROJ 9.1.1) LIBXML="2.9.14" LIBJSON="0.16" LIBPROTOBUF="1.4.1" WAGYU="0.5.0 (Internal)"
    (1 row)
    
    COMPILE FLAGS USED:
    
    CC=clang ./configure --with-pgconfig=/usr/bin/pg_config CFLAGS="-O0 -g -fsanitize=address -fno-omit-frame-pointer" LDFLAGS="-fsanitize=address"
    
    
    ###############################################################################################################

diff --git a/postgis/gserialized_typmod.c b/postgis/gserialized_typmod.c
index 308297fa7..9f7b46f5f 100644
--- a/postgis/gserialized_typmod.c
+++ b/postgis/gserialized_typmod.c
@@ -140,8 +140,9 @@ GSERIALIZED* postgis_valid_typmod(GSERIALIZED *gser, int32_t typmod)
 	{
 		LWPOINT *empty_point = lwpoint_construct_empty(geom_srid, geom_z, geom_m);
 		geom_type = POINTTYPE;
+		bool is_geodetic = gserialized_is_geodetic(gser);
 		pfree(gser);
-		if ( gserialized_is_geodetic(gser) )
+		if ( is_geodetic )
 			gser = geography_serialize(lwpoint_as_lwgeom(empty_point));
 		else
 			gser = geometry_serialize(lwpoint_as_lwgeom(empty_point));

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

Summary of changes:
 postgis/gserialized_typmod.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)


hooks/post-receive
-- 
PostGIS


More information about the postgis-tickets mailing list