[postgis-tickets] [PostGIS] #5088: Memory corruption in mvt_agg_transfn

PostGIS trac at osgeo.org
Wed Feb 9 02:02:19 PST 2022


#5088: Memory corruption in mvt_agg_transfn
---------------------+---------------------------
 Reporter:  multun   |      Owner:  pramsey
     Type:  defect   |     Status:  new
 Priority:  high     |  Milestone:  PostGIS 3.3.0
Component:  postgis  |    Version:  3.2.x
 Keywords:           |
---------------------+---------------------------
 Hello!

 We've had frequent crashes in mvt_agg_transfn, with this message: `could
 not find block containing chunk`. I thought it could be a buffer overflow,
 compiled postgis and postgres with debug and valgrind support enabled, and
 sure enough:

 {{{
 ==26== Invalid write of size 4
 ==26==    at 0x10B244C6: add_value_as_string_with_size (mvt.c:481)
 ==26==    by 0x10B295C6: add_value_as_string (mvt.c:490)
 ==26==    by 0x10B295C6: parse_jsonb (mvt.c:551)
 ==26==    by 0x10B295C6: parse_values (mvt.c:686)
 ==26==    by 0x10B295C6: mvt_agg_transfn (mvt.c:1052)
 ==26==    by 0x10B2BA47: pgis_asmvt_transfn (lwgeom_out_mvt.c:172)
 ==26==    by 0x4840EA: ExecAggPlainTransByVal (execExprInterp.c:4298)
 ==26==    by 0x47E974: ExecInterpExpr (execExprInterp.c:1696)
 ==26==    by 0x47ED9E: ExecInterpExprStillValid (execExprInterp.c:1807)
 ==26==    by 0x4A3F2F: ExecEvalExprSwitchContext (executor.h:322)
 ==26==    by 0x4A49E3: advance_aggregates (nodeAgg.c:850)
 ==26==    by 0x4A79AA: agg_retrieve_direct (nodeAgg.c:2462)
 ==26==    by 0x4A7417: ExecAgg (nodeAgg.c:2187)
 ==26==    by 0x4948C1: ExecProcNodeFirst (execProcnode.c:450)
 ==26==    by 0x4884F2: ExecProcNode (executor.h:248)
 ==26==  Address 0x1086e418 is 5,608 bytes inside a block of size 8,192
 alloc'd
 ==26==    at 0x48A26D9: malloc (vg_replace_malloc.c:380)
 ==26==    by 0x8A67B2: AllocSetContextCreateInternal (aset.c:468)
 ==26==    by 0x10B2BB55: pgis_asmvt_transfn (lwgeom_out_mvt.c:158)
 ==26==    by 0x4840EA: ExecAggPlainTransByVal (execExprInterp.c:4298)
 ==26==    by 0x47E974: ExecInterpExpr (execExprInterp.c:1696)
 ==26==    by 0x47ED9E: ExecInterpExprStillValid (execExprInterp.c:1807)
 ==26==    by 0x4A3F2F: ExecEvalExprSwitchContext (executor.h:322)
 ==26==    by 0x4A49E3: advance_aggregates (nodeAgg.c:850)
 ==26==    by 0x4A79AA: agg_retrieve_direct (nodeAgg.c:2462)
 ==26==    by 0x4A7417: ExecAgg (nodeAgg.c:2187)
 ==26==    by 0x4948C1: ExecProcNodeFirst (execProcnode.c:450)
 ==26==    by 0x4884F2: ExecProcNode (executor.h:248)
 ==26==
 }}}


 In this specific instance, when the overflow occurs on line 481 of mvt.c:

 `tags[ctx->row_columns * 2] = k`

 `tags` has room for 10 items (I deduced this from allocation metadata
 headers), yet `ctx->row_columns` is 5.

 So the tags array is too small. It is initially allocated with the number
 of already known hash keys as an initial size: `uint32_t *tags =
 palloc(ctx->keys_hash_i * 2 * sizeof(*tags));`
 It may very well be a good guess, yet nothing ensures the array is big
 enough with properties are added to the feature.

 The array is only resized when a new key is met in parse_jsonb, which does
 not seem to be enough.

-- 
Ticket URL: <https://trac.osgeo.org/postgis/ticket/5088>
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