From a395e6e244e04dd09284e24eb1ca3ff2a7c9f37f Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 30 May 2017 12:14:26 +0200 Subject: catalog: memory leak and crashes related fixes * pj_transform() crashes on a catalog that has no matching grid * pj_free() and pj_gc_unloadall() badly interact. No longer try to free the catalog object in pj_free(). That is the job of pj_gc_unloadall() * Fix memory leaks in pj_gc_readcatalog() and pj_gc_unloadall() Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1923 Credit to OSS Fuzz. --- src/pj_gc_reader.c | 6 ++++++ src/pj_gridcatalog.c | 11 +++++++++++ src/pj_init.c | 7 +++++-- 3 files changed, 22 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/pj_gc_reader.c b/src/pj_gc_reader.c index 4b54d05a..dc528b52 100644 --- a/src/pj_gc_reader.c +++ b/src/pj_gc_reader.c @@ -55,7 +55,10 @@ PJ_GridCatalog *pj_gc_readcatalog( projCtx ctx, const char *catalog_name ) catalog = (PJ_GridCatalog *) calloc(1,sizeof(PJ_GridCatalog)); if( !catalog ) + { + pj_ctx_fclose(ctx, fid); return NULL; + } catalog->catalog_name = strdup(catalog_name); @@ -82,12 +85,15 @@ PJ_GridCatalog *pj_gc_readcatalog( projCtx ctx, const char *catalog_name ) free( catalog->entries[i].definition ); free( catalog->catalog_name ); free( catalog ); + pj_ctx_fclose(ctx, fid); return NULL; } catalog->entries = new_entries; } } + pj_ctx_fclose(ctx, fid); + return catalog; } diff --git a/src/pj_gridcatalog.c b/src/pj_gridcatalog.c index 79543185..053de5e7 100644 --- a/src/pj_gridcatalog.c +++ b/src/pj_gridcatalog.c @@ -56,6 +56,7 @@ void pj_gc_unloadall( projCtx ctx ) free( catalog->entries[i].definition ); } free( catalog->entries ); + free( catalog->catalog_name ); free( catalog ); } } @@ -136,6 +137,11 @@ int pj_gc_apply_gridshift( PJ *defn, int inverse, 1, input, defn->datum_date, &(defn->last_after_region), &(defn->last_after_date)); + if( defn->last_after_grid == NULL ) + { + pj_ctx_set_errno( defn->ctx, -38 ); + return -38; + } } gi = defn->last_after_grid; assert( gi->child == NULL ); @@ -179,6 +185,11 @@ int pj_gc_apply_gridshift( PJ *defn, int inverse, 0, input, defn->datum_date, &(defn->last_before_region), &(defn->last_before_date)); + if( defn->last_before_grid == NULL ) + { + pj_ctx_set_errno( defn->ctx, -38 ); + return -38; + } } gi = defn->last_before_grid; diff --git a/src/pj_init.c b/src/pj_init.c index 764784f5..e3d99a8f 100644 --- a/src/pj_init.c +++ b/src/pj_init.c @@ -735,8 +735,11 @@ pj_free(PJ *P) { if( P->catalog_name != NULL ) pj_dalloc( P->catalog_name ); - if( P->catalog != NULL ) - pj_dalloc( P->catalog ); + /* We used to call pj_dalloc( P->catalog ), but this will leak */ + /* memory. The safe way to clear catalog and grid is to call */ + /* pj_gc_unloadall(pj_get_default_ctx()); and pj_deallocate_grids(); */ + /* TODO: we should probably have a public pj_cleanup() method to do all */ + /* that */ if( P->geod != NULL ) pj_dalloc( P->geod ); -- cgit v1.2.3