[cairo-commit] 2 commits - src/cairo-image-info.c
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Mon Jan 2 09:28:44 UTC 2023
src/cairo-image-info.c | 28 +++++++++++++++++++---------
1 file changed, 19 insertions(+), 9 deletions(-)
New commits:
commit 8dbc5893f70b2dde42bdc327f2ab6407394a447d
Merge: 3cc15cb40 e60e562fd
Author: Uli Schlachter <psychon at znc.in>
Date: Mon Jan 2 09:28:42 2023 +0000
Merge branch 'jpx-out-of-bounds' into 'master'
Fix possible out-of-bound reads in get_jpx_info
See merge request cairo/cairo!387
commit e60e562fd1eed43f2fc21fd1307004ae09b6e9e5
Author: Uli Schlachter <psychon at znc.in>
Date: Sun Jan 1 14:01:46 2023 +0100
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 at znc.in>
diff --git a/src/cairo-image-info.c b/src/cairo-image-info.c
index f207ae887..a2403ef3f 100644
--- a/src/cairo-image-info.c
+++ b/src/cairo-image-info.c
@@ -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)
More information about the cairo-commit
mailing list