Fix heap buffer overflow appending/linking from a blend file
Add new function `blo_bhead_is_id_valid_type()` to correctly check the blend file block type. File block type codes have four bytes, and two of those are only in use when these blocks contain ID datablocks (like `"OB\0\0"`). However, there are other types defined in `BLO_blend_defs.h` that have four bytes, like `TEST`, `ENDB`, etc. The function `BKE_idtype_idcode_is_valid(short idcode)` was used to check for ID datablocks while reading a blend file. This only takes a 2-byte parameter, and thus its result is invalid for the 4-byte codes. For `TEST` blocks, it would actually consider it a `TE` block, which is a valid identifier for a Texture. This caused the heap buffer overflow, as the datablock is not a valid ID, and thus the bytes that were expected to form an ID name actually encode something completely different. Reviewed By: mont29 Differential Revision: https://developer.blender.org/D10703
This commit is contained in:
parent
f0c3ec3dc8
commit
bcac17196a
@ -555,6 +555,23 @@ static void read_file_version(FileData *fd, Main *main)
|
||||
}
|
||||
}
|
||||
|
||||
static bool blo_bhead_is_id(BHead *bhead)
|
||||
{
|
||||
/* BHead codes are four bytes (like 'ENDB', 'TEST', etc.), but if the two most-significant bytes
|
||||
* are zero, the values actually indicate an ID type. */
|
||||
return bhead->code <= 0xFFFF;
|
||||
}
|
||||
|
||||
static bool blo_bhead_is_id_valid_type(BHead *bhead)
|
||||
{
|
||||
if (!blo_bhead_is_id(bhead)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const short id_type_code = bhead->code & 0xFFFF;
|
||||
return BKE_idtype_idcode_is_valid(id_type_code);
|
||||
}
|
||||
|
||||
#ifdef USE_GHASH_BHEAD
|
||||
static void read_file_bhead_idname_map_create(FileData *fd)
|
||||
{
|
||||
@ -568,8 +585,9 @@ static void read_file_bhead_idname_map_create(FileData *fd)
|
||||
for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
|
||||
if (code_prev != bhead->code) {
|
||||
code_prev = bhead->code;
|
||||
is_link = BKE_idtype_idcode_is_valid(code_prev) ? BKE_idtype_idcode_is_linkable(code_prev) :
|
||||
false;
|
||||
is_link = blo_bhead_is_id_valid_type(bhead) ?
|
||||
BKE_idtype_idcode_is_linkable((short)code_prev) :
|
||||
false;
|
||||
}
|
||||
|
||||
if (is_link) {
|
||||
@ -584,8 +602,9 @@ static void read_file_bhead_idname_map_create(FileData *fd)
|
||||
for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
|
||||
if (code_prev != bhead->code) {
|
||||
code_prev = bhead->code;
|
||||
is_link = BKE_idtype_idcode_is_valid(code_prev) ? BKE_idtype_idcode_is_linkable(code_prev) :
|
||||
false;
|
||||
is_link = blo_bhead_is_id_valid_type(bhead) ?
|
||||
BKE_idtype_idcode_is_linkable((short)code_prev) :
|
||||
false;
|
||||
}
|
||||
|
||||
if (is_link) {
|
||||
@ -973,7 +992,7 @@ const char *blo_bhead_id_name(const FileData *fd, const BHead *bhead)
|
||||
/* Warning! Caller's responsibility to ensure given bhead **is** an ID one! */
|
||||
AssetMetaData *blo_bhead_id_asset_data_address(const FileData *fd, const BHead *bhead)
|
||||
{
|
||||
BLI_assert(BKE_idtype_idcode_is_valid(bhead->code));
|
||||
BLI_assert(blo_bhead_is_id_valid_type(bhead));
|
||||
return (fd->id_asset_data_offset >= 0) ?
|
||||
*(AssetMetaData **)POINTER_OFFSET(bhead, sizeof(*bhead) + fd->id_asset_data_offset) :
|
||||
NULL;
|
||||
@ -3711,7 +3730,7 @@ static BHead *read_libblock(FileData *fd,
|
||||
|
||||
BHead *blo_read_asset_data_block(FileData *fd, BHead *bhead, AssetMetaData **r_asset_data)
|
||||
{
|
||||
BLI_assert(BKE_idtype_idcode_is_valid(bhead->code));
|
||||
BLI_assert(blo_bhead_is_id_valid_type(bhead));
|
||||
|
||||
bhead = read_data_into_datamap(fd, bhead, "asset-data read");
|
||||
|
||||
@ -4923,7 +4942,7 @@ int BLO_library_link_copypaste(Main *mainl, BlendHandle *bh, const uint64_t id_t
|
||||
break;
|
||||
}
|
||||
|
||||
if (BKE_idtype_idcode_is_valid(bhead->code) && BKE_idtype_idcode_is_linkable(bhead->code) &&
|
||||
if (blo_bhead_is_id_valid_type(bhead) && BKE_idtype_idcode_is_linkable((short)bhead->code) &&
|
||||
(id_types_mask == 0 ||
|
||||
(BKE_idtype_idcode_to_idfilter((short)bhead->code) & id_types_mask) != 0)) {
|
||||
read_libblock(fd, mainl, bhead, LIB_TAG_NEED_EXPAND | LIB_TAG_INDIRECT, false, &id);
|
||||
|
Loading…
Reference in New Issue
Block a user