[postgis-tickets] [PostGIS] #3980: [SFCGAL] Potential access to freed memory
PostGIS
trac at osgeo.org
Thu Feb 1 09:36:51 PST 2018
#3980: [SFCGAL] Potential access to freed memory
----------------------+---------------------------
Reporter: lucasvr | Owner: colivier
Type: defect | Status: new
Priority: medium | Milestone: PostGIS 2.4.4
Component: sfcgal | Version: 2.4.x
Resolution: | Keywords:
----------------------+---------------------------
Comment (by lucasvr):
I have just checked and confirmed that your intuition is right. For
reference, here is the code path for a conversion of a POINT geometry
(please read this as if it were a simplified stack trace):
{{{
#1 ptarray_construct_reference_data(pt_list):
POINTARRAY *pa = lwalloc(..);
pa->serialized_pointlist = pt_list;
return pa;
#2 lwpoint_from_gserialized_buffer(data_ptr):
LWPOINT *point = lwalloc(..);
point->point = ptarray_construct_reference_data(data_ptr);
return point;
#3 lwgeom_from_gserialized(input_geom):
return lwgeom_from_gserialized_buffer(data_ptr[=input_geom]);
#4 POSTGIS2SFCGALGeometry(input_geom):
LWGEOM *lwgeom = lwgeom_from_gserialized(input_geom);
sfcgal_geometry_t *g = LWGEOM2SFCGAL(lwgeom);
lwgeom_free(lwgeom);
return g;
}}}
On frame 4, the returned LWGEOM holds a reference to input_geom through
point->serialized_pointlist. However, as you suspected,
POSTGIS2SFCGALGeometry will indeed create a deep copy of
serialized_pointlist, so it's safe to keep the calls to PG_FREE_IF_COPY in
their original place in cases where the geometry is retrieved through that
function.
On the other hand, freeing the input on sfcgal_make_solid() is indeed
dangerous. Assuming the input is a POINT:
- {{{LWGEOM *lwgeom = lwgeom_from_gserialized(input_geom)}}} will return
an object with a reference to input_geom through
point->serialized_pointlist
- {{{PG_FREE_IF_COPY(input_geom)}}} will be called
- {{{GSERIALIZED *output = geometry_serialize(lwgeom)}}} will eventually
access freed memory (see stack trace below).
{{{
#1 getPoint_internal(pa):
ptr = pa->serialized_pointlist + size * n;
// access invalid memory through *(ptr+offset)
#2 gserialized_from_lwpoint(point):
memcpy(buf, getPoint_internal(point->point), ..);
#3 gserialized_from_lwgeom_any(lwgeom):
return gserialized_from_lwpoint(lwgeom);
#4 gserialized_from_lwgeom(lwgeom):
gserialized_from_lwgeom_any(lwgeom);
#5 geometry_serialize(lwgeom):
return gserialized_from_lwgeom(lwgeom);
}}}
I will update my patch accordingly.
--
Ticket URL: <https://trac.osgeo.org/postgis/ticket/3980#comment:7>
PostGIS <http://trac.osgeo.org/postgis/>
The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project.
More information about the postgis-tickets
mailing list