vc4: Fix race condition in BO imports

When importing a BO, if it is already imported, then the handle will
alias an existing BO instance. It is possible for the existing owner to
free the BO after the import and leave a dangling handle before we get a
chance to increase the refcount, so we need to lock the BO table mutex
before importing, to make sure nobody else goes through the free path
during that window.

Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com>
Signed-off-by: Asahi Lina <lina@asahilina.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20403>
This commit is contained in:
Asahi Lina 2022-12-21 17:25:09 +09:00 committed by Marge Bot
parent 7dbb1a091a
commit f401599f79

View file

@ -382,9 +382,11 @@ vc4_bo_open_handle(struct vc4_screen *screen,
{
struct vc4_bo *bo;
assert(size);
/* Note: the caller is responsible for locking screen->bo_handles_mutex.
* This allows the lock to cover the actual BO import, avoiding a race.
*/
mtx_lock(&screen->bo_handles_mutex);
assert(size);
bo = util_hash_table_get(screen->bo_handles, (void*)(uintptr_t)handle);
if (bo) {
@ -418,10 +420,14 @@ vc4_bo_open_name(struct vc4_screen *screen, uint32_t name)
struct drm_gem_open o = {
.name = name
};
mtx_lock(&screen->bo_handles_mutex);
int ret = vc4_ioctl(screen->fd, DRM_IOCTL_GEM_OPEN, &o);
if (ret) {
fprintf(stderr, "Failed to open bo %d: %s\n",
name, strerror(errno));
mtx_unlock(&screen->bo_handles_mutex);
return NULL;
}
@ -432,10 +438,14 @@ struct vc4_bo *
vc4_bo_open_dmabuf(struct vc4_screen *screen, int fd)
{
uint32_t handle;
mtx_lock(&screen->bo_handles_mutex);
int ret = drmPrimeFDToHandle(screen->fd, fd, &handle);
int size;
if (ret) {
fprintf(stderr, "Failed to get vc4 handle for dmabuf %d\n", fd);
mtx_unlock(&screen->bo_handles_mutex);
return NULL;
}
@ -443,6 +453,7 @@ vc4_bo_open_dmabuf(struct vc4_screen *screen, int fd)
size = lseek(fd, 0, SEEK_END);
if (size == -1) {
fprintf(stderr, "Couldn't get size of dmabuf fd %d.\n", fd);
mtx_unlock(&screen->bo_handles_mutex);
return NULL;
}