Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean up error messages, check against packed size of 0, integer overflow #1169

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 50 additions & 32 deletions src/lib/OpenEXRCore/chunk.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,14 @@ extract_chunk_table (
ctxt, EXR_ERR_INVALID_ARGUMENT, "Invalid file with no chunks");

if (ctxt->file_size > 0 &&
chunkbytes + chunkoff > (uint64_t) ctxt->file_size)
return ctxt->print_error (
ctxt,
EXR_ERR_INVALID_ARGUMENT,
"chunk table size (%" PRIu64
") too big for file size (%" PRId64 ")",
chunkbytes,
ctxt->file_size);


chunkbytes + chunkoff > (uint64_t) ctxt->file_size)
return ctxt->print_error (
ctxt,
EXR_ERR_INVALID_ARGUMENT,
"chunk table size (%" PRIu64 ") too big for file size (%" PRId64
")",
chunkbytes,
ctxt->file_size);

ctable = (uint64_t*) ctxt->alloc_fn (chunkbytes);
if (ctable == NULL)
Expand Down Expand Up @@ -590,7 +588,8 @@ exr_read_tile_chunk_info (
int64_t fsize, tend, dend;
const exr_attr_chlist_t* chanlist;
const exr_attr_tiledesc_t* tiledesc;
int tilew, tileh, unpacksize = 0;
int tilew, tileh;
uint64_t texels, unpacksize = 0;
uint64_t* ctable;
EXR_PROMOTE_READ_CONST_CONTEXT_AND_PART_OR_ERROR (ctxt, part_index);

Expand Down Expand Up @@ -656,11 +655,11 @@ exr_read_tile_chunk_info (
cinfo->level_y = (uint8_t) levely;

chanlist = part->channels->chlist;
texels = (uint64_t) tilew * (uint64_t) tileh;
for (int c = 0; c < chanlist->num_channels; ++c)
{
const exr_attr_chlist_entry_t* curc = (chanlist->entries + c);
unpacksize +=
tilew * tileh * ((curc->pixel_type == EXR_PIXEL_HALF) ? 2 : 4);
unpacksize += texels * (uint64_t) ((curc->pixel_type == EXR_PIXEL_HALF) ? 2 : 4);
}

rv = extract_chunk_table (pctxt, part, &ctable);
Expand Down Expand Up @@ -691,8 +690,8 @@ exr_read_tile_chunk_info (
return pctxt->print_error (
pctxt,
rv,
"Request for tile (%d, %d), level (%d, %d) but unable to read %" PRId64
" bytes from offset %" PRId64 ", got %" PRId64 " bytes",
"Unable to read information block for tile (%d, %d), level (%d, %d): request %" PRIu64
" bytes from offset %" PRIu64 ", got %" PRIu64 " bytes",
tilex,
tiley,
levelx,
Expand All @@ -711,7 +710,7 @@ exr_read_tile_chunk_info (
return pctxt->print_error (
pctxt,
EXR_ERR_BAD_CHUNK_LEADER,
"Preparing to read tile (%d, %d), level (%d, %d) (chunk %d), found corrupt leader: part says %d, expected %d",
"Corrupt tile (%d, %d), level (%d, %d) (chunk %d): bad part number (%d, expect %d)",
tilex,
tiley,
levelx,
Expand All @@ -727,7 +726,7 @@ exr_read_tile_chunk_info (
return pctxt->print_error (
pctxt,
EXR_ERR_BAD_CHUNK_LEADER,
"Preparing to read tile (%d, %d), level (%d, %d) (chunk %d), found corrupt leader: found tile x %d, expect %d",
"Corrupt tile (%d, %d), level (%d, %d) (chunk %d): bad tile x coordinate (%d, expect %d)",
tilex,
tiley,
levelx,
Expand All @@ -741,7 +740,7 @@ exr_read_tile_chunk_info (
return pctxt->print_error (
pctxt,
EXR_ERR_BAD_CHUNK_LEADER,
"Preparing to read tile (%d, %d), level (%d, %d) (chunk %d), found corrupt leader: found tile y %d, expect %d",
"Corrupt tile (%d, %d), level (%d, %d) (chunk %d): bad tile Y coordinate (%d, expect %d)",
tilex,
tiley,
levelx,
Expand All @@ -755,7 +754,7 @@ exr_read_tile_chunk_info (
return pctxt->print_error (
pctxt,
EXR_ERR_BAD_CHUNK_LEADER,
"Preparing to read tile (%d, %d), level (%d, %d) (chunk %d), found corrupt leader: found tile level x %d, expect %d",
"Corrupt tile (%d, %d), level (%d, %d) (chunk %d): bad tile mip/rip level X (%d, expect %d)",
tilex,
tiley,
levelx,
Expand All @@ -769,7 +768,7 @@ exr_read_tile_chunk_info (
return pctxt->print_error (
pctxt,
EXR_ERR_BAD_CHUNK_LEADER,
"Preparing to read tile (%d, %d), level (%d, %d) (chunk %d), found corrupt leader: found tile level y %d, expect %d",
"Corrupt tile (%d, %d), level (%d, %d) (chunk %d): bad tile mip/rip level Y (%d, expect %d)",
tilex,
tiley,
levelx,
Expand Down Expand Up @@ -798,7 +797,7 @@ exr_read_tile_chunk_info (
return pctxt->print_error (
pctxt,
EXR_ERR_BAD_CHUNK_LEADER,
"Preparing to read deep tile (%d, %d), level (%d, %d) (chunk %d), found corrupt leader: invalid sample table size %" PRId64,
"Corrupt deep tile (%d, %d), level (%d, %d) (chunk %d): invalid sample table size %" PRId64,
tilex,
tiley,
levelx,
Expand All @@ -808,12 +807,12 @@ exr_read_tile_chunk_info (
}

/* not all compressors support 64-bit */
if (ddata[1] < 0 || ddata[1] > (int64_t) INT32_MAX)
if (ddata[1] <= 0 || ddata[1] > (int64_t) INT32_MAX)
{
return pctxt->print_error (
pctxt,
EXR_ERR_BAD_CHUNK_LEADER,
"Preparing to read deep tile (%d, %d), level (%d, %d) (chunk %d), found corrupt leader: invalid packed data size %" PRId64,
"Corrupt deep tile (%d, %d), level (%d, %d) (chunk %d): invalid packed data size %" PRId64,
tilex,
tiley,
levelx,
Expand All @@ -826,7 +825,7 @@ exr_read_tile_chunk_info (
return pctxt->print_error (
pctxt,
EXR_ERR_BAD_CHUNK_LEADER,
"Preparing to read deep tile (%d, %d), level (%d, %d) (chunk %d), found corrupt leader: invalid packed data size %" PRId64,
"Corrupt deep tile (%d, %d), level (%d, %d) (chunk %d): invalid unpacked size %" PRId64,
tilex,
tiley,
levelx,
Expand All @@ -848,7 +847,7 @@ exr_read_tile_chunk_info (
return pctxt->print_error (
pctxt,
EXR_ERR_BAD_CHUNK_LEADER,
"Preparing to read deep tile (%d, %d), level (%d, %d) (chunk %d), found corrupt leader: sample table and data result in access past end of the file: sample table size %" PRId64
"Corrupt deep tile (%d, %d), level (%d, %d) (chunk %d): access past end of the file: sample table size %" PRId64
" + data size %" PRId64 " larger than file %" PRId64,
tilex,
tiley,
Expand All @@ -862,25 +861,44 @@ exr_read_tile_chunk_info (
}
else
{
if (tdata[4] < 0 || tdata[4] > unpacksize ||
(fsize > 0 && tdata[4] > fsize))
if (tdata[4] <= 0 || ((uint64_t) tdata[4] > unpacksize))
{
return pctxt->print_error (
pctxt,
EXR_ERR_BAD_CHUNK_LEADER,
"Preparing to read deep tile (%d, %d), level (%d, %d) (chunk %d), found corrupt leader: invalid packed size (%d) vs unpacked size (%d), and file size %" PRId64,
"Corrupt tile (%d, %d), level (%d, %d) (chunk %d): invalid packed size %d vs unpacked size %" PRIu64,
tilex,
tiley,
levelx,
levely,
cidx,
(int) tdata[4],
(int) unpacksize,
fsize);
unpacksize);
}
else if (fsize > 0)
{
uint64_t finpos = dataoff + (uint64_t) tdata[4];
if (finpos > fsize)
{
return pctxt->print_error (
pctxt,
EXR_ERR_BAD_CHUNK_LEADER,
"Corrupt tile (%d, %d), level (%d, %d) (chunk %d): access past end of file: packed size (%d) at offset %" PRIu64
" vs size of file %" PRId64,
tilex,
tiley,
levelx,
levely,
cidx,
(int) tdata[4],
dataoff,
fsize);
}
}

cinfo->packed_size = (uint64_t) tdata[4];
cinfo->unpacked_size = (uint64_t) unpacksize;
cinfo->data_offset = (uint64_t) dataoff;
cinfo->unpacked_size = unpacksize;
cinfo->data_offset = dataoff;
cinfo->sample_count_data_offset = 0;
cinfo->sample_count_table_size = 0;
}
Expand Down