summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-02-02 08:47:26 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2013-02-02 08:55:37 +0000
commit18cff63e3d288bf2d7773760f2ab25c80a4a2bc1 (patch)
tree069c8f0a069521ecb9ad13746ff3ac93c3435981
parentc391093f40472c2300f38d0e5857858f85586b60 (diff)
surface: Prevent writes to the user-data arrays during teardown
As we cleanup the user-data arrays, we call the user provided destroy notifier callbacks. These callbacks are at liberty to write back into the parent surface, and in particular try to write into the arrays that we have just freed. This causes hard to control and fairly unpredictable use-after-frees in the client, so lets just rule out the dangerous behaviour. References:https://bugzilla.mozilla.org/show_bug.cgi?id=722975 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/cairo-surface.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index ffffef86..5ec659e0 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -1126,6 +1126,9 @@ cairo_surface_set_user_data (cairo_surface_t *surface,
if (CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count))
return surface->status;
+ if (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count))
+ return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
+
return _cairo_user_data_array_set_data (&surface->user_data,
key, user_data, destroy);
}
@@ -1276,6 +1279,12 @@ cairo_surface_set_mime_data (cairo_surface_t *surface,
cairo_status_t status;
cairo_mime_data_t *mime_data;
+ if (CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count))
+ return surface->status;
+
+ if (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count))
+ return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
+
if (unlikely (surface->status))
return surface->status;
if (unlikely (surface->finished))