zink: Clean up file descriptor closing in export_dmabuf_semaphore()

First, we handle the case where GetMemoryFdKHR fails.  This is unlikely
and, if it's a Mesa driver it probably won't stomp the FD but we should
be extra careful.  Then, we can close the dma-buf file immediately after
we call drmIoctl() on it, ensuring we don't leak the dma-buf file
descriptor if drmIoctl() fails.  If ImportSemaphoreFdKHR() fails, then
we need to clean up the sync file.

Fixes: d4f8ad27f2 ("zink: handle implicit sync for dmabufs")
Reviewed-by: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36048>
(cherry picked from commit de4224a57c)
This commit is contained in:
Faith Ekstrand 2025-07-10 10:41:50 -04:00 committed by Eric Engestrom
parent 9edbab562e
commit eb217aa317
2 changed files with 5 additions and 3 deletions

View file

@ -4224,7 +4224,7 @@
"description": "zink: Clean up file descriptor closing in export_dmabuf_semaphore()",
"nominated": true,
"nomination_type": 2,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": "d4f8ad27f2d7ebc74ea32d587ae854a791c94133",
"notes": null

View file

@ -2316,7 +2316,8 @@ zink_screen_export_dmabuf_semaphore(struct zink_screen *screen, struct zink_reso
fd_info.sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR;
fd_info.memory = zink_bo_get_mem(res->obj->bo);
fd_info.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
VKSCR(GetMemoryFdKHR)(screen->dev, &fd_info, &fd);
if (VKSCR(GetMemoryFdKHR)(screen->dev, &fd_info, &fd) != VK_SUCCESS)
fd = -1;
}
if (unlikely(fd < 0)) {
@ -2325,6 +2326,7 @@ zink_screen_export_dmabuf_semaphore(struct zink_screen *screen, struct zink_reso
}
int ret = drmIoctl(fd, DMA_BUF_IOCTL_EXPORT_SYNC_FILE, &export);
close(fd);
if (ret) {
if (errno == ENOTTY || errno == EBADF || errno == ENOSYS) {
assert(!"how did this fail?");
@ -2345,8 +2347,8 @@ zink_screen_export_dmabuf_semaphore(struct zink_screen *screen, struct zink_reso
.fd = export.fd,
};
bool success = VKSCR(ImportSemaphoreFdKHR)(screen->dev, &sdi) == VK_SUCCESS;
close(fd);
if (!success) {
close(export.fd);
VKSCR(DestroySemaphore)(screen->dev, sem, NULL);
return VK_NULL_HANDLE;
}