[PATCH xserver] prime: Clear PixmapDirtyUpdateRec::damage when it's destroyed

Michel Dänzer michel at daenzer.net
Thu Feb 16 07:13:56 UTC 2017


From: Michel Dänzer <michel.daenzer at amd.com>

The root window, and by extension any damage records referencing it,
may be destroyed before shared pixmaps referencing it, which resulted in
use-after-free / double-free in PixmapStopDirtyTracking.

Fixes: b5b292896f64 ("prime: Sync shared pixmap from root window instead of screen pixmap")
Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
---

Thanks Adam for suggesting this fix!

 dix/pixmap.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/dix/pixmap.c b/dix/pixmap.c
index ef0083083..b67a2e8a6 100644
--- a/dix/pixmap.c
+++ b/dix/pixmap.c
@@ -172,6 +172,14 @@ PixmapPtr PixmapShareToSlave(PixmapPtr pixmap, ScreenPtr slave)
     return spix;
 }
 
+static void
+PixmapDirtyDamageDestroy(DamagePtr damage, void *closure)
+{
+    PixmapDirtyUpdatePtr dirty = closure;
+
+    dirty->damage = NULL;
+}
+
 Bool
 PixmapStartDirtyTracking(PixmapPtr src,
                          PixmapPtr slave_dst,
@@ -195,10 +203,10 @@ PixmapStartDirtyTracking(PixmapPtr src,
     dirty_update->dst_x = dst_x;
     dirty_update->dst_y = dst_y;
     dirty_update->rotation = rotation;
-    dirty_update->damage = DamageCreate(NULL, NULL,
+    dirty_update->damage = DamageCreate(NULL, PixmapDirtyDamageDestroy,
                                         DamageReportNone,
                                         TRUE, src->drawable.pScreen,
-                                        src->drawable.pScreen);
+                                        dirty_update);
 
     if (rotation != RR_Rotate_0) {
         RRTransformCompute(x, y,
@@ -247,7 +255,8 @@ PixmapStopDirtyTracking(PixmapPtr src, PixmapPtr slave_dst)
 
     xorg_list_for_each_entry_safe(ent, safe, &screen->pixmap_dirty_list, ent) {
         if (ent->src == src && ent->slave_dst == slave_dst) {
-            DamageDestroy(ent->damage);
+            if (ent->damage)
+                DamageDestroy(ent->damage);
             xorg_list_del(&ent->ent);
             free(ent);
         }
-- 
2.11.0



More information about the xorg-devel mailing list