shared/cairo-util: fix leak from load_cairo_surface()

Fixes ASan reported leaks:

Direct leak of 256 byte(s) in 1 object(s) allocated from:
    #0 0x7f8266f2d330 in __interceptor_malloc (/lib/x86_64-linux-gnu/libasan.so.5+0xe9330)
    #1 0x7f8266c8589a  (/lib/x86_64-linux-gnu/libpixman-1.so.0+0x5089a)
    #2 0x7f8266c4ea77  (/lib/x86_64-linux-gnu/libpixman-1.so.0+0x19a77)
    #3 0x55fa7818f8e8 in load_png ../../git/weston/shared/image-loader.c:297
    #4 0x55fa7819039e in load_image ../../git/weston/shared/image-loader.c:423
    #5 0x55fa78187b3e in load_cairo_surface ../../git/weston/shared/cairo-util.c:354
    #6 0x55fa7815ff8a in background_draw ../../git/weston/clients/desktop-shell.c:779
    #7 0x55fa7817b2c2 in widget_redraw ../../git/weston/clients/window.c:4520
    #8 0x55fa7817b831 in surface_redraw ../../git/weston/clients/window.c:4578
    #9 0x55fa7817b9a7 in idle_redraw ../../git/weston/clients/window.c:4607
    #10 0x55fa78184ea4 in display_run ../../git/weston/clients/window.c:6527
    #11 0x55fa781646fb in main ../../git/weston/clients/desktop-shell.c:1556
    #12 0x7f826659709a in __libc_start_main ../csu/libc-start.c:308
    #13 0x55fa7815c0a9 in _start (/home/pq/build/weston-meson/clients/weston-desktop-shell+0x120a9)

Indirect leak of 8024 byte(s) in 1 object(s) allocated from:
    #0 0x7f8266f2d330 in __interceptor_malloc (/lib/x86_64-linux-gnu/libasan.so.5+0xe9330)
    #1 0x55fa7818f5e7 in load_png ../../git/weston/shared/image-loader.c:275
    #2 0x55fa7819039e in load_image ../../git/weston/shared/image-loader.c:423
    #3 0x55fa78187b3e in load_cairo_surface ../../git/weston/shared/cairo-util.c:354
    #4 0x55fa7815ff8a in background_draw ../../git/weston/clients/desktop-shell.c:779
    #5 0x55fa7817b2c2 in widget_redraw ../../git/weston/clients/window.c:4520
    #6 0x55fa7817b831 in surface_redraw ../../git/weston/clients/window.c:4578
    #7 0x55fa7817b9a7 in idle_redraw ../../git/weston/clients/window.c:4607
    #8 0x55fa78184ea4 in display_run ../../git/weston/clients/window.c:6527
    #9 0x55fa781646fb in main ../../git/weston/clients/desktop-shell.c:1556
    #10 0x7f826659709a in __libc_start_main ../csu/libc-start.c:308
    #11 0x55fa7815c0a9 in _start (/home/pq/build/weston-meson/clients/weston-desktop-shell+0x120a9)

from the command

	ASAN_OPTIONS=fast_unwind_on_malloc=0,malloc_context_size=50 \
	LSAN_OPTIONS=suppressions=/home/pq/git/weston/.gitlab-ci/leak-sanitizer.supp \
	./tests/test-viewporter test_viewporter_bad_source_rect

by recording the pixman image as user data so it can be freed when the
surface is destroyed.

Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
dev
Pekka Paalanen 4 years ago
parent 928d3a0059
commit 091b1554da
  1. 33
      shared/cairo-util.c

@ -344,9 +344,21 @@ rounded_rect(cairo_t *cr, int x0, int y0, int x1, int y1, int radius)
cairo_close_path(cr); cairo_close_path(cr);
} }
static void
loaded_cairo_surface_destructor(void *data)
{
pixman_image_t *image = data;
pixman_image_unref(image);
}
static const cairo_user_data_key_t weston_cairo_util_load_cairo_surface_key;
cairo_surface_t * cairo_surface_t *
load_cairo_surface(const char *filename) load_cairo_surface(const char *filename)
{ {
cairo_surface_t *surface;
cairo_status_t ret;
pixman_image_t *image; pixman_image_t *image;
int width, height, stride; int width, height, stride;
void *data; void *data;
@ -361,8 +373,25 @@ load_cairo_surface(const char *filename)
height = pixman_image_get_height(image); height = pixman_image_get_height(image);
stride = pixman_image_get_stride(image); stride = pixman_image_get_stride(image);
return cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32, surface = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32,
width, height, stride); width, height, stride);
ret = cairo_surface_status(surface);
if (ret != CAIRO_STATUS_SUCCESS)
goto fail;
ret = cairo_surface_set_user_data(surface,
&weston_cairo_util_load_cairo_surface_key,
image,
loaded_cairo_surface_destructor);
if (ret != CAIRO_STATUS_SUCCESS)
goto fail;
return surface;
fail:
cairo_surface_destroy(surface);
pixman_image_unref(image);
return NULL;
} }
void void

Loading…
Cancel
Save