mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2025-12-28 11:00:11 +01:00
[malloc] Check for integer overflow when realloc'ing.
Perform similar sanity checks to Vlad's _cairo_malloc_ab() but on the arguments to realloc instead.
This commit is contained in:
parent
8cba73a36c
commit
e49bcde27f
9 changed files with 46 additions and 13 deletions
|
|
@ -138,8 +138,8 @@ _cairo_array_grow_by (cairo_array_t *array, int additional)
|
|||
}
|
||||
|
||||
array->size = new_size;
|
||||
new_elements = realloc (*array->elements,
|
||||
array->size * array->element_size);
|
||||
new_elements = _cairo_realloc_ab (*array->elements,
|
||||
array->size, array->element_size);
|
||||
|
||||
if (new_elements == NULL) {
|
||||
array->size = old_size;
|
||||
|
|
|
|||
|
|
@ -93,7 +93,11 @@ _lzw_buf_grow (lzw_buf_t *buf)
|
|||
if (buf->status)
|
||||
return buf->status;
|
||||
|
||||
new_data = realloc (buf->data, new_size);
|
||||
new_data = NULL;
|
||||
/* check for integer overflow */
|
||||
if (new_size / 2 == buf->data_size)
|
||||
new_data = realloc (buf->data, new_size);
|
||||
|
||||
if (new_data == NULL) {
|
||||
free (buf->data);
|
||||
buf->data_size = 0;
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@
|
|||
* @n: number of elements to allocate
|
||||
* @size: size of each element
|
||||
*
|
||||
* Allocates @a*@size memory using _cairo_malloc(), taking care to not
|
||||
* Allocates @n*@size memory using _cairo_malloc(), taking care to not
|
||||
* overflow when doing the multiplication. Behaves much like
|
||||
* calloc(), except that the returned memory is not set to zero.
|
||||
* The memory should be freed using free().
|
||||
|
|
@ -75,13 +75,35 @@
|
|||
((size) && (unsigned) (a) >= INT32_MAX / (unsigned) (size) ? NULL : \
|
||||
_cairo_malloc((unsigned) (a) * (unsigned) (size)))
|
||||
|
||||
/**
|
||||
* _cairo_realloc_ab:
|
||||
* @ptr: original pointer to block of memory to be resized
|
||||
* @n: number of elements to allocate
|
||||
* @size: size of each element
|
||||
*
|
||||
* Reallocates @ptr a block of @n*@size memory using realloc(), taking
|
||||
* care to not overflow when doing the multiplication. The memory
|
||||
* should be freed using free().
|
||||
*
|
||||
* @size should be a constant so that the compiler can optimize
|
||||
* out a constant division.
|
||||
*
|
||||
* Return value: A pointer to the newly allocated memory, or %NULL in
|
||||
* case of realloc() failure or overflow (whereupon the original block
|
||||
* of memory * is left untouched).
|
||||
*/
|
||||
|
||||
#define _cairo_realloc_ab(ptr, a, size) \
|
||||
((size) && (unsigned) (a) >= INT32_MAX / (unsigned) (size) ? NULL : \
|
||||
realloc(ptr, (unsigned) (a) * (unsigned) (size)))
|
||||
|
||||
/**
|
||||
* _cairo_malloc_abc:
|
||||
* @a: first factor of number of elements to allocate
|
||||
* @n: first factor of number of elements to allocate
|
||||
* @b: second factor of number of elements to allocate
|
||||
* @size: size of each element
|
||||
*
|
||||
* Allocates @a*@b*@size memory using _cairo_malloc(), taking care to not
|
||||
* Allocates @n*@b*@size memory using _cairo_malloc(), taking care to not
|
||||
* overflow when doing the multiplication. Behaves like
|
||||
* _cairo_malloc_ab(). The memory should be freed using free().
|
||||
*
|
||||
|
|
@ -103,7 +125,7 @@
|
|||
* @size: size of each element
|
||||
* @k: additional size to allocate
|
||||
*
|
||||
* Allocates @a*@ksize+@k memory using _cairo_malloc(), taking care to not
|
||||
* Allocates @n*@ksize+@k memory using _cairo_malloc(), taking care to not
|
||||
* overflow when doing the arithmetic. Behaves like
|
||||
* _cairo_malloc_ab(). The memory should be freed using free().
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1064,7 +1064,8 @@ _cairo_rectilinear_stroker_add_segment (cairo_rectilinear_stroker_t *stroker,
|
|||
/* Common case is one rectangle of exactly 4 segments. */
|
||||
if (new_size == 0)
|
||||
new_size = 4;
|
||||
new_segments = realloc (stroker->segments, new_size * sizeof (cairo_line_t));
|
||||
new_segments = _cairo_realloc_ab (stroker->segments,
|
||||
new_size, sizeof (cairo_line_t));
|
||||
if (new_segments == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
stroker->segments_size = new_size;
|
||||
|
|
|
|||
|
|
@ -765,7 +765,9 @@ _cairo_pattern_gradient_grow (cairo_gradient_pattern_t *pattern)
|
|||
if (new_stops)
|
||||
memcpy (new_stops, pattern->stops, old_size * sizeof (cairo_gradient_stop_t));
|
||||
} else {
|
||||
new_stops = realloc (pattern->stops, new_size * sizeof (cairo_gradient_stop_t));
|
||||
new_stops = _cairo_realloc_ab (pattern->stops,
|
||||
new_size,
|
||||
sizeof (cairo_gradient_stop_t));
|
||||
}
|
||||
|
||||
if (new_stops == NULL) {
|
||||
|
|
|
|||
|
|
@ -142,7 +142,8 @@ _cairo_pen_add_points (cairo_pen_t *pen, cairo_point_t *point, int num_points)
|
|||
int i;
|
||||
|
||||
num_vertices = pen->num_vertices + num_points;
|
||||
vertices = realloc (pen->vertices, num_vertices * sizeof (cairo_pen_vertex_t));
|
||||
vertices = _cairo_realloc_ab (pen->vertices,
|
||||
num_vertices, sizeof (cairo_pen_vertex_t));
|
||||
if (vertices == NULL) {
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
|
|
|||
|
|
@ -97,7 +97,8 @@ _cairo_polygon_grow (cairo_polygon_t *polygon)
|
|||
if (new_edges)
|
||||
memcpy (new_edges, polygon->edges, old_size * sizeof (cairo_edge_t));
|
||||
} else {
|
||||
new_edges = realloc (polygon->edges, new_size * sizeof (cairo_edge_t));
|
||||
new_edges = _cairo_realloc_ab (polygon->edges,
|
||||
new_size, sizeof (cairo_edge_t));
|
||||
}
|
||||
|
||||
if (new_edges == NULL) {
|
||||
|
|
|
|||
|
|
@ -113,7 +113,8 @@ _cairo_spline_grow (cairo_spline_t *spline)
|
|||
if (new_points)
|
||||
memcpy (new_points, spline->points, old_size * sizeof (cairo_point_t));
|
||||
} else {
|
||||
new_points = realloc (spline->points, new_size * sizeof (cairo_point_t));
|
||||
new_points = _cairo_realloc_ab (spline->points,
|
||||
new_size, sizeof (cairo_point_t));
|
||||
}
|
||||
|
||||
if (new_points == NULL) {
|
||||
|
|
|
|||
|
|
@ -265,7 +265,8 @@ _cairo_traps_grow (cairo_traps_t *traps)
|
|||
if (new_traps)
|
||||
memcpy (new_traps, traps->traps, sizeof (traps->traps_embedded));
|
||||
} else {
|
||||
new_traps = realloc (traps->traps, new_size * sizeof (cairo_trapezoid_t));
|
||||
new_traps = _cairo_realloc_ab (traps->traps,
|
||||
new_size, sizeof (cairo_trapezoid_t));
|
||||
}
|
||||
|
||||
if (new_traps == NULL) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue