mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-25 09:40:37 +00:00
queuearray: Fix potential heap overflow when expanding GstQueueArray
Check that elt_size*newsize doesn't overflow when expanding a GstQueueArray, which has the potential for a heap overwrite. Co-authored-by: Sebastian Dröge <sebastian@centricular.com> Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1232 Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2607>
This commit is contained in:
parent
b6bb400f14
commit
cc4b1b4e6e
1 changed files with 17 additions and 8 deletions
|
@ -332,16 +332,24 @@ gst_queue_array_peek_nth_struct (GstQueueArray * array, guint idx)
|
||||||
static void
|
static void
|
||||||
gst_queue_array_do_expand (GstQueueArray * array)
|
gst_queue_array_do_expand (GstQueueArray * array)
|
||||||
{
|
{
|
||||||
guint elt_size = array->elt_size;
|
gsize elt_size = array->elt_size;
|
||||||
/* newsize is 50% bigger */
|
/* newsize is 50% bigger */
|
||||||
guint oldsize = array->size;
|
gsize oldsize = array->size;
|
||||||
guint newsize = MAX ((3 * oldsize) / 2, oldsize + 1);
|
guint64 newsize;
|
||||||
|
|
||||||
|
newsize = MAX ((3 * (guint64) oldsize) / 2, (guint64) oldsize + 1);
|
||||||
|
if (newsize > G_MAXUINT)
|
||||||
|
g_error ("growing the queue array would overflow");
|
||||||
|
|
||||||
/* copy over data */
|
/* copy over data */
|
||||||
if (array->tail != 0) {
|
if (array->tail != 0) {
|
||||||
guint8 *array2 = g_malloc0 (elt_size * newsize);
|
guint8 *array2 = NULL;
|
||||||
guint t1 = array->head;
|
gsize t1 = 0;
|
||||||
guint t2 = oldsize - array->head;
|
gsize t2 = 0;
|
||||||
|
|
||||||
|
array2 = g_malloc0_n (newsize, elt_size);
|
||||||
|
t1 = array->head;
|
||||||
|
t2 = oldsize - array->head;
|
||||||
|
|
||||||
/* [0-----TAIL][HEAD------SIZE]
|
/* [0-----TAIL][HEAD------SIZE]
|
||||||
*
|
*
|
||||||
|
@ -352,7 +360,8 @@ gst_queue_array_do_expand (GstQueueArray * array)
|
||||||
* 2) move [0-------TAIL] part new array, after previous part
|
* 2) move [0-------TAIL] part new array, after previous part
|
||||||
*/
|
*/
|
||||||
|
|
||||||
memcpy (array2, array->array + (elt_size * array->head), t2 * elt_size);
|
memcpy (array2, array->array + (elt_size * (gsize) array->head),
|
||||||
|
t2 * elt_size);
|
||||||
memcpy (array2 + t2 * elt_size, array->array, t1 * elt_size);
|
memcpy (array2 + t2 * elt_size, array->array, t1 * elt_size);
|
||||||
|
|
||||||
g_free (array->array);
|
g_free (array->array);
|
||||||
|
@ -360,7 +369,7 @@ gst_queue_array_do_expand (GstQueueArray * array)
|
||||||
array->head = 0;
|
array->head = 0;
|
||||||
} else {
|
} else {
|
||||||
/* Fast path, we just need to grow the array */
|
/* Fast path, we just need to grow the array */
|
||||||
array->array = g_realloc (array->array, elt_size * newsize);
|
array->array = g_realloc_n (array->array, newsize, elt_size);
|
||||||
memset (array->array + elt_size * oldsize, 0,
|
memset (array->array + elt_size * oldsize, 0,
|
||||||
elt_size * (newsize - oldsize));
|
elt_size * (newsize - oldsize));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue