image: prevent invalid ptr access for > 4GB images

Image data is often accessed using:

  image->data + y * image->stride

On 64-bit achitectures if the image data is > 4GB, this computation
will overflow since both y and stride are 32-bit types.

Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=98165
Reviewed-by: Bryce Harrington <bryce@osg.samsung.com>
This commit is contained in:
Adrian Johnson 2016-10-20 21:12:30 +10:30 committed by Bryce Harrington
parent 35fccff6ec
commit 38fbe621cf
6 changed files with 10 additions and 7 deletions

View file

@ -42,6 +42,7 @@
#undef CAIRO_VERSION_H
#include "../cairo-version.h"
#include <stddef.h>
#include <stdlib.h>
#include <ctype.h>
#include <assert.h>
@ -976,7 +977,8 @@ cairo_surface_t *
cairo_boilerplate_image_surface_create_from_ppm_stream (FILE *file)
{
char format;
int width, height, stride;
int width, height;
ptrdiff_t stride;
int x, y;
unsigned char *data;
cairo_surface_t *image = NULL;

View file

@ -1581,7 +1581,7 @@ typedef struct _cairo_image_span_renderer {
pixman_image_t *src, *mask;
union {
struct fill {
int stride;
ptrdiff_t stride;
uint8_t *data;
uint32_t pixel;
} fill;
@ -1600,7 +1600,7 @@ typedef struct _cairo_image_span_renderer {
struct finish {
cairo_rectangle_int_t extents;
int src_x, src_y;
int stride;
ptrdiff_t stride;
uint8_t *data;
} mask;
} u;

View file

@ -71,7 +71,7 @@ struct _cairo_image_surface {
int width;
int height;
int stride;
ptrdiff_t stride;
int depth;
unsigned owns_data : 1;

View file

@ -470,7 +470,7 @@ draw_pixel (unsigned char *data, int width, int height, int stride,
tg += tg >> 16;
tb += tb >> 16;
*((uint32_t*) (data + y*stride + 4*x)) = ((ta << 16) & 0xff000000) |
*((uint32_t*) (data + y*(ptrdiff_t)stride + 4*x)) = ((ta << 16) & 0xff000000) |
((tr >> 8) & 0xff0000) | ((tg >> 16) & 0xff00) | (tb >> 24);
}
}

View file

@ -678,7 +678,7 @@ read_png (struct png_read_closure_t *png_closure)
}
for (i = 0; i < png_height; i++)
row_pointers[i] = &data[i * stride];
row_pointers[i] = &data[i * (ptrdiff_t)stride];
png_read_image (png, row_pointers);
png_read_end (png, info);

View file

@ -1202,7 +1202,8 @@ static cairo_status_t
_write_image_surface (cairo_output_stream_t *output,
const cairo_image_surface_t *image)
{
int stride, row, width;
int row, width;
ptrdiff_t stride;
uint8_t row_stack[CAIRO_STACK_BUFFER_SIZE];
uint8_t *rowdata;
uint8_t *data;