summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichel Dänzer <michel.daenzer@amd.com>2017-02-16 16:13:56 +0900
committerAdam Jackson <ajax@redhat.com>2017-02-16 14:14:11 -0500
commita6566f9e4dbf9ea9568a14e22cb5d004e10dbd4d (patch)
treeab972ea077b6bda3a70e0b301ed9b1686770e06b
parent371ff0c969a38a0013688391bbd7375bc7b6f933 (diff)
prime: Clear PixmapDirtyUpdateRec::damage when it's destroyed
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") Reviewed-by: Adam Jackson <ajax@redhat.com> Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
-rw-r--r--dix/pixmap.c15
1 files 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);
}