From 9581d060d298dd876aae7bd0ed8ca709fff79f14 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 30 Jan 2024 15:12:54 +0100 Subject: [PATCH] dmabuf: Fix disjoint detection According to the Mesa developers, the correct way to determine disjointness is to check the actual inode of the fd because dup()ing can cause these duplications to happen when planes are carelessly copied or when planes are sent over dbus or other unix sockets. Related: https://bugs.webkit.org/show_bug.cgi?id=267578 --- gdk/gdkdmabuf.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/gdk/gdkdmabuf.c b/gdk/gdkdmabuf.c index d1b8cf2d83..6697934416 100644 --- a/gdk/gdkdmabuf.c +++ b/gdk/gdkdmabuf.c @@ -2329,18 +2329,42 @@ gdk_dmabuf_sanitize (GdkDmabuf *dest, * @dmabuf: a sanitized GdkDmabuf * * A dmabuf is considered disjoint if it uses more than - * 1 file descriptor. + * 1 inode. + * Multiple file descriptors may exist when the creator + * of the dmabuf just dup()ed once for every plane... * * Returns: %TRUE if the dmabuf is disjoint **/ gboolean gdk_dmabuf_is_disjoint (const GdkDmabuf *dmabuf) { + struct stat first_stat; unsigned i; + /* First, do a fast check */ + for (i = 1; i < dmabuf->n_planes; i++) { if (dmabuf->planes[0].fd != dmabuf->planes[i].fd) + break; + } + + if (i == dmabuf->n_planes) + return FALSE; + + /* We have different fds, do the fancy check instead */ + + if (fstat (dmabuf->planes[0].fd, &first_stat) != 0) + return TRUE; + + for (i = 1; i < dmabuf->n_planes; i++) + { + struct stat plane_stat; + + if (fstat (dmabuf->planes[0].fd, &plane_stat) != 0) + return TRUE; + + if (first_stat.st_ino != plane_stat.st_ino) return TRUE; }