diff options
author | Even Rouault <even.rouault@spatialys.com> | 2022-12-13 18:06:33 +0100 |
---|---|---|
committer | Even Rouault <even.rouault@spatialys.com> | 2022-12-13 18:06:33 +0100 |
commit | ff9a315b42b66f18a01378cf21e2eb405fbc131e (patch) | |
tree | 4a113d1a536cecacdd4264ef3906785a65702b39 | |
parent | be62af1f181fcc374f7abf10a5a79e7a942b8fea (diff) | |
download | libtiff-git-ff9a315b42b66f18a01378cf21e2eb405fbc131e.tar.gz |
_TIFFCheckDirNumberAndOffset(): fix recently introduced use-after-free found by CIFuzz on GDAL
-rw-r--r-- | libtiff/tif_dirread.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/libtiff/tif_dirread.c b/libtiff/tif_dirread.c index 1be962ce..35425b4b 100644 --- a/libtiff/tif_dirread.c +++ b/libtiff/tif_dirread.c @@ -5400,19 +5400,22 @@ int _TIFFCheckDirNumberAndOffset(TIFF *tif, tdir_t dirn, uint64_t diroff) TIFFOffsetAndDirNumber entryOld; entryOld.offset = foundEntry->offset; entryOld.dirNumber = dirn; + /* We must remove first from tif_map_dir_number_to_offset as the */ + /* entry is owned (and thus freed) by */ + /* tif_map_dir_offset_to_number */ TIFFOffsetAndDirNumber *foundEntryOld = (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( - tif->tif_map_dir_offset_to_number, &entryOld); + tif->tif_map_dir_number_to_offset, &entryOld); if (foundEntryOld) { - TIFFHashSetRemove(tif->tif_map_dir_offset_to_number, + TIFFHashSetRemove(tif->tif_map_dir_number_to_offset, foundEntryOld); } foundEntryOld = (TIFFOffsetAndDirNumber *)TIFFHashSetLookup( - tif->tif_map_dir_number_to_offset, &entryOld); + tif->tif_map_dir_offset_to_number, &entryOld); if (foundEntryOld) { - TIFFHashSetRemove(tif->tif_map_dir_number_to_offset, + TIFFHashSetRemove(tif->tif_map_dir_offset_to_number, foundEntryOld); } @@ -5428,10 +5431,16 @@ int _TIFFCheckDirNumberAndOffset(TIFF *tif, tdir_t dirn, uint64_t diroff) if (!TIFFHashSetInsert(tif->tif_map_dir_offset_to_number, entryPtr)) { + TIFFErrorExtR( + tif, "_TIFFCheckDirNumberAndOffset", + "Insertion in tif_map_dir_offset_to_number failed"); return 0; } if (!TIFFHashSetInsert(tif->tif_map_dir_number_to_offset, entryPtr)) { + TIFFErrorExtR( + tif, "_TIFFCheckDirNumberAndOffset", + "Insertion in tif_map_dir_number_to_offset failed"); return 0; } } @@ -5451,6 +5460,8 @@ int _TIFFCheckDirNumberAndOffset(TIFF *tif, tdir_t dirn, uint64_t diroff) (TIFFOffsetAndDirNumber *)malloc(sizeof(TIFFOffsetAndDirNumber)); if (entryPtr == NULL) { + TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset", + "malloc(sizeof(TIFFOffsetAndDirNumber)) failed"); return 0; } @@ -5459,10 +5470,14 @@ int _TIFFCheckDirNumberAndOffset(TIFF *tif, tdir_t dirn, uint64_t diroff) if (!TIFFHashSetInsert(tif->tif_map_dir_offset_to_number, entryPtr)) { + TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset", + "Insertion in tif_map_dir_offset_to_number failed"); return 0; } if (!TIFFHashSetInsert(tif->tif_map_dir_number_to_offset, entryPtr)) { + TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset", + "Insertion in tif_map_dir_number_to_offset failed"); return 0; } |