[PATCH] wayland util: Handle malloc failure in wl_array_copy()
Kristian Høgsberg
hoegsberg at gmail.com
Sun Jul 22 11:24:15 PDT 2012
On Thu, Jul 19, 2012 at 03:45:57AM +0200, Martin Minarik wrote:
> If the malloc in wl_array_add() fails, we are memcpy-ing to bad memory.
> This can happen only when copying array to smaller array.
> ---
> src/wayland-util.c | 11 ++++++++---
> src/wayland-util.h | 2 +-
> tests/array-test.c | 8 ++++++--
> 3 files changed, 15 insertions(+), 6 deletions(-)
>
> diff --git a/src/wayland-util.c b/src/wayland-util.c
> index a8c03ad..4e02f95 100644
> --- a/src/wayland-util.c
> +++ b/src/wayland-util.c
> @@ -135,12 +135,17 @@ wl_array_add(struct wl_array *array, size_t size)
> return p;
> }
>
> -WL_EXPORT void
> +WL_EXPORT int
> wl_array_copy(struct wl_array *array, struct wl_array *source)
> {
> - array->size = 0;
> - wl_array_add(array, source->size);
> + if (source->size > array->size) {
> + if (NULL == wl_array_add(array, source->size - array->size))
> + return -1;
> + } else {
> + array->size = source->size;
> + }
wl_array_add will grow the allocated area if necessary, so just
setting size to 0 and adding source->size works fine. To check for
out-of-memory, just do
if (wl_array_add(array, source->size) == 0)
return -1;
instead.
> memcpy(array->data, source->data, source->size);
> + return 0;
> }
>
> union map_entry {
> diff --git a/src/wayland-util.h b/src/wayland-util.h
> index b588505..f54077e 100644
> --- a/src/wayland-util.h
> +++ b/src/wayland-util.h
> @@ -165,7 +165,7 @@ struct wl_array {
> void wl_array_init(struct wl_array *array);
> void wl_array_release(struct wl_array *array);
> void *wl_array_add(struct wl_array *array, size_t size);
> -void wl_array_copy(struct wl_array *array, struct wl_array *source);
> +int wl_array_copy(struct wl_array *array, struct wl_array *source);
>
> typedef int32_t wl_fixed_t;
>
> diff --git a/tests/array-test.c b/tests/array-test.c
> index 7639878..ff5bb8c 100644
> --- a/tests/array-test.c
> +++ b/tests/array-test.c
> @@ -60,7 +60,9 @@ TEST(array_add)
>
> /* add some data */
> for (i = 0; i < iterations; i++) {
> - struct mydata* ptr = wl_array_add(&array, datasize);
> + struct mydata* ptr = NULL;
> + while (ptr == NULL)
> + ptr = wl_array_add(&array, datasize);
> assert((i + 1) * datasize == array.size);
If we want to test our malloc failure paths, we should inject malloc
errors using our malloc wrapper in test/test-runner.c, not by forcing
out-of-memory. The typical approach here is to run the test once to
see how many mallocs there are, then run it once for each malloc,
failing malloc i in iteration i.
> ptr->a = i * 3;
> @@ -94,7 +96,9 @@ TEST(array_copy)
>
> /* add some data */
> for (i = 0; i < iterations; i++) {
> - int *p = wl_array_add(&source, sizeof(int));
> + int *p = NULL;
> + while (p == NULL)
> + p = wl_array_add(&source, sizeof(int));
> *p = i * 2 + i;
> }
>
> --
> 1.7.0.4
>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
More information about the wayland-devel
mailing list