diff options
author | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2018-01-15 01:26:31 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2018-01-17 22:25:42 +0300 |
commit | 07aed404cfb2759f97c60b9f64d8a9392dabaf1a (patch) | |
tree | ae47bdb684d0fbc8928dd2c011ca24a7fbfcb0d7 | |
parent | d30cc1ea0b9ba64d8a1e22105528b6cb8077692c (diff) |
Fix buffer overflow vulernability in thumbnail file reading.
Fixes CVE-2017-2908 from T52924.
Differential Revision: https://developer.blender.org/D3001
-rw-r--r-- | source/blender/blenkernel/BKE_main.h | 3 | ||||
-rw-r--r-- | source/blender/blenloader/BLO_blend_defs.h | 2 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 55 | ||||
-rw-r--r-- | source/blender/makesdna/intern/dna_genfile.c | 4 |
4 files changed, 42 insertions, 22 deletions
diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h index 387045878f3..d8318bfcf5d 100644 --- a/source/blender/blenkernel/BKE_main.h +++ b/source/blender/blenkernel/BKE_main.h @@ -145,7 +145,8 @@ typedef struct Main { #define BLEN_THUMB_SIZE 128 -#define BLEN_THUMB_MEMSIZE(_x, _y) (sizeof(BlendThumbnail) + (size_t)((_x) * (_y)) * sizeof(int)) +#define BLEN_THUMB_MEMSIZE(_x, _y) (sizeof(BlendThumbnail) + ((size_t)(_x) * (size_t)(_y)) * sizeof(int)) +#define BLEN_THUMB_SAFE_MEMSIZE(_x, _y) ((uint64_t)_x * (uint64_t)_y < (SIZE_MAX / (sizeof(int) * 4))) #ifdef __cplusplus } diff --git a/source/blender/blenloader/BLO_blend_defs.h b/source/blender/blenloader/BLO_blend_defs.h index a6b06a080cc..6776b1c3338 100644 --- a/source/blender/blenloader/BLO_blend_defs.h +++ b/source/blender/blenloader/BLO_blend_defs.h @@ -75,6 +75,6 @@ enum { ENDB = BLEND_MAKE_ID('E', 'N', 'D', 'B'), }; -#define BLEN_THUMB_MEMSIZE_FILE(_x, _y) (sizeof(int) * (size_t)(2 + (_x) * (_y))) +#define BLEN_THUMB_MEMSIZE_FILE(_x, _y) (sizeof(int) * (2 + (size_t)(_x) * (size_t)(_y))) #endif /* __BLO_BLEND_DEFS_H__ */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 40b53d4c684..51b77938dea 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -982,7 +982,13 @@ static int *read_file_thumbnail(FileData *fd) BLI_endian_switch_int32(&data[1]); } - if (bhead->len < BLEN_THUMB_MEMSIZE_FILE(data[0], data[1])) { + int width = data[0]; + int height = data[1]; + + if (!BLEN_THUMB_SAFE_MEMSIZE(width, height)) { + break; + } + if (bhead->len < BLEN_THUMB_MEMSIZE_FILE(width, height)) { break; } @@ -1421,23 +1427,28 @@ bool BLO_library_path_explode(const char *path, char *r_dir, char **r_group, cha BlendThumbnail *BLO_thumbnail_from_file(const char *filepath) { FileData *fd; - BlendThumbnail *data; + BlendThumbnail *data = NULL; int *fd_data; fd = blo_openblenderfile_minimal(filepath); fd_data = fd ? read_file_thumbnail(fd) : NULL; if (fd_data) { - const size_t sz = BLEN_THUMB_MEMSIZE(fd_data[0], fd_data[1]); - data = MEM_mallocN(sz, __func__); + int width = fd_data[0]; + int height = fd_data[1]; - BLI_assert((sz - sizeof(*data)) == (BLEN_THUMB_MEMSIZE_FILE(fd_data[0], fd_data[1]) - (sizeof(*fd_data) * 2))); - data->width = fd_data[0]; - data->height = fd_data[1]; - memcpy(data->rect, &fd_data[2], sz - sizeof(*data)); - } - else { - data = NULL; + /* Protect against buffer overflow vulnerability. */ + if (BLEN_THUMB_SAFE_MEMSIZE(width, height)) { + const size_t sz = BLEN_THUMB_MEMSIZE(width, height); + data = MEM_mallocN(sz, __func__); + + if (data) { + BLI_assert((sz - sizeof(*data)) == (BLEN_THUMB_MEMSIZE_FILE(width, height) - (sizeof(*fd_data) * 2))); + data->width = width; + data->height = height; + memcpy(data->rect, &fd_data[2], sz - sizeof(*data)); + } + } } blo_freefiledata(fd); @@ -8624,14 +8635,20 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath) const int *data = read_file_thumbnail(fd); if (data) { - const size_t sz = BLEN_THUMB_MEMSIZE(data[0], data[1]); - bfd->main->blen_thumb = MEM_mallocN(sz, __func__); - - BLI_assert((sz - sizeof(*bfd->main->blen_thumb)) == - (BLEN_THUMB_MEMSIZE_FILE(data[0], data[1]) - (sizeof(*data) * 2))); - bfd->main->blen_thumb->width = data[0]; - bfd->main->blen_thumb->height = data[1]; - memcpy(bfd->main->blen_thumb->rect, &data[2], sz - sizeof(*bfd->main->blen_thumb)); + int width = data[0]; + int height = data[1]; + + /* Protect against buffer overflow vulnerability. */ + if (BLEN_THUMB_SAFE_MEMSIZE(width, height)) { + const size_t sz = BLEN_THUMB_MEMSIZE(width, height); + bfd->main->blen_thumb = MEM_mallocN(sz, __func__); + + BLI_assert((sz - sizeof(*bfd->main->blen_thumb)) == + (BLEN_THUMB_MEMSIZE_FILE(width, height) - (sizeof(*data) * 2))); + bfd->main->blen_thumb->width = width; + bfd->main->blen_thumb->height = height; + memcpy(bfd->main->blen_thumb->rect, &data[2], sz - sizeof(*bfd->main->blen_thumb)); + } } } diff --git a/source/blender/makesdna/intern/dna_genfile.c b/source/blender/makesdna/intern/dna_genfile.c index 181d01e04fc..dec93f97c6c 100644 --- a/source/blender/makesdna/intern/dna_genfile.c +++ b/source/blender/makesdna/intern/dna_genfile.c @@ -173,7 +173,9 @@ void DNA_sdna_free(SDNA *sdna) MEM_freeN(sdna->structs); #ifdef WITH_DNA_GHASH - BLI_ghash_free(sdna->structs_map, NULL, NULL); + if (sdna->structs_map) { + BLI_ghash_free(sdna->structs_map, NULL, NULL); + } #endif MEM_freeN(sdna); |