mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-02-04 04:50:31 +01:00
Fix possible out-of-bound reads in get_jpx_info
Inspired by [1], I looked into the other functions in cairo-image-info.c. This commit fixes the possible out-of-bound reads that I found just by staring at the code. _jpx_next_box() would happily read beyond the end of the data via get_unaligned_be32(). This commit adds checks that at least for bytes of data are available. Additionally, I made this function check that its returned pointer is within bounds, just because I found this easier to reason about. Also, _jpx_extract_info() did not check that it had enough data to read. This is fixed by making the function fallible and giving it information about the end of data. [1]: https://gitlab.freedesktop.org/cairo/cairo/-/merge_requests/386 Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
parent
52e964da69
commit
e60e562fd1
1 changed files with 19 additions and 9 deletions
|
|
@ -162,9 +162,15 @@ static const unsigned char _jpx_signature[] = {
|
|||
};
|
||||
|
||||
static const unsigned char *
|
||||
_jpx_next_box (const unsigned char *p)
|
||||
_jpx_next_box (const unsigned char *p, const unsigned char *end)
|
||||
{
|
||||
return p + get_unaligned_be32 (p);
|
||||
if (p + 4 < end) {
|
||||
uint32_t length = get_unaligned_be32 (p);
|
||||
if (p + length < end)
|
||||
return p + length;
|
||||
}
|
||||
|
||||
return end;
|
||||
}
|
||||
|
||||
static const unsigned char *
|
||||
|
|
@ -193,19 +199,25 @@ _jpx_find_box (const unsigned char *p, const unsigned char *end, uint32_t type)
|
|||
while (p < end) {
|
||||
if (_jpx_match_box (p, end, type))
|
||||
return p;
|
||||
p = _jpx_next_box (p);
|
||||
p = _jpx_next_box (p, end);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_jpx_extract_info (const unsigned char *p, cairo_image_info_t *info)
|
||||
static cairo_int_status_t
|
||||
_jpx_extract_info (const unsigned char *p, cairo_image_info_t *info, const unsigned char *end)
|
||||
{
|
||||
if (p + 11 >= end) {
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
info->height = get_unaligned_be32 (p);
|
||||
info->width = get_unaligned_be32 (p + 4);
|
||||
info->num_components = (p[8] << 8) + p[9];
|
||||
info->bits_per_component = p[10];
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_int_status_t
|
||||
|
|
@ -227,7 +239,7 @@ _cairo_image_info_get_jpx_info (cairo_image_info_t *info,
|
|||
if (! _jpx_match_box (p, end, JPX_FILETYPE))
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
p = _jpx_next_box (p);
|
||||
p = _jpx_next_box (p, end);
|
||||
|
||||
/* Locate the JP2 header box. */
|
||||
p = _jpx_find_box (p, end, JPX_JP2_HEADER);
|
||||
|
|
@ -242,9 +254,7 @@ _cairo_image_info_get_jpx_info (cairo_image_info_t *info,
|
|||
|
||||
/* Get the image info */
|
||||
p = _jpx_get_box_contents (p);
|
||||
_jpx_extract_info (p, info);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
return _jpx_extract_info (p, info, end);
|
||||
}
|
||||
|
||||
/* PNG (image/png)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue