Skip to content

Commit

Permalink
Fix memory leak when calling GDALAllRegister() on a deferred loaded p…
Browse files Browse the repository at this point in the history
…lugin that is absent from the system

Fixes rasterio/rasterio#3250
  • Loading branch information
rouault committed Nov 28, 2024
1 parent 4cfbcf8 commit f2af8a5
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 0 deletions.
1 change: 1 addition & 0 deletions .github/workflows/asan/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ cmake ${GDAL_SOURCE_DIR:=..} \
-DUSE_CCACHE=ON \
-DGDAL_USE_GEOTIFF_INTERNAL=ON \
-DGDAL_USE_TIFF_INTERNAL=ON \
-DGDAL_ENABLE_DRIVER_PDF_PLUGIN=ON \
-DGDAL_USE_LIBKML=OFF -DOGR_ENABLE_DRIVER_LIBKML=OFF \
-DFileGDB_ROOT=/usr/local/FileGDB_API
make -j$NPROC
Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/asan/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ export PYTHONMALLOC=malloc
gdalinfo autotest/gcore/data/byte.tif
python3 -c "from osgeo import gdal; print('yes')"

# Check fix for https://github.com/rasterio/rasterio/issues/3250
mv ${GDAL_DRIVER_PATH}/gdal_PDF.so ${GDAL_DRIVER_PATH}/gdal_PDF.so.disabled
echo "from osgeo import gdal" > register_many_times.py
echo "for i in range(1000):" >> register_many_times.py
echo " gdal.AllRegister()" >> register_many_times.py
python3 register_many_times.py
mv ${GDAL_DRIVER_PATH}/gdal_PDF.so.disabled ${GDAL_DRIVER_PATH}/gdal_PDF.so

cd autotest

# Run each module in its own pytest process.
Expand Down
13 changes: 13 additions & 0 deletions gcore/gdaldrivermanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1668,6 +1668,19 @@ void GDALDriverManager::DeclareDeferredPluginDriver(

if (osFullPath.empty())
{
// Do not try to re-register a non-existent deferred plugin
// This would cause memory leaks in case of repeated calls to GDALAllRegister()
// Cf https://github.com/rasterio/rasterio/issues/3250
for (const auto &poDriver : m_aoHiddenDrivers)
{
if (EQUAL(poDriver->GetDescription(),
poProxyDriver->GetDescription()))
{
delete poProxyDriver;
return;
}
}

CPLDebug("GDAL",
"Proxy driver %s *not* registered due to %s not being found",
poProxyDriver->GetDescription(), pszPluginFileName);
Expand Down

0 comments on commit f2af8a5

Please sign in to comment.