Mesa (main): drm-shim: Better mmap offsets

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon May 2 20:19:56 UTC 2022


Module: Mesa
Branch: main
Commit: c4b5ebe1fc911ff4a50c30efdcf31b66f47e5bae
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=c4b5ebe1fc911ff4a50c30efdcf31b66f47e5bae

Author: Rob Clark <robdclark at chromium.org>
Date:   Thu Apr 28 15:36:54 2022 -0700

drm-shim: Better mmap offsets

Using the bo pointer address as the offset doesn't go over well when
someone is fuzzing you.  But we already have the mem_addr, we can simply
use that instead.

Signed-off-by: Rob Clark <robdclark at chromium.org>
Reviewed-by: Emma Anholt <emma at anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16250>

---

 src/drm-shim/device.c                 | 26 +++++++++++++++++---------
 src/drm-shim/drm_shim.h               |  3 +++
 src/intel/tools/intel_noop_drm_shim.c |  3 ++-
 3 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/src/drm-shim/device.c b/src/drm-shim/device.c
index dc7294050c9..ba1cc907f5e 100644
--- a/src/drm-shim/device.c
+++ b/src/drm-shim/device.c
@@ -82,6 +82,8 @@ drm_shim_device_init(void)
                                                 uint_key_hash,
                                                 uint_key_compare);
 
+   shim_device.offset_map = _mesa_hash_table_u64_create(NULL);
+
    mtx_init(&shim_device.mem_lock, mtx_plain);
 
    shim_device.mem_fd = memfd_create("shim mem", MFD_CLOEXEC);
@@ -372,18 +374,16 @@ drm_shim_bo_get_handle(struct shim_fd *shim_fd, struct shim_bo *bo)
 }
 
 /* Creates an mmap offset for the BO in the DRM fd.
- *
- * XXX: We should be maintaining a u_mm allocator where the mmap offsets
- * allocate the size of the BO and it can be used to look the BO back up.
- * Instead, we just stuff the shim's pointer as the return value, and treat
- * the incoming mmap offset on the DRM fd as a BO pointer.  This doesn't work
- * if someone tries to map a subset of the BO, but it's enough to get V3D
- * working for now.
  */
 uint64_t
 drm_shim_bo_get_mmap_offset(struct shim_fd *shim_fd, struct shim_bo *bo)
 {
-   return (uintptr_t)bo;
+   mtx_lock(&shim_device.mem_lock);
+   _mesa_hash_table_u64_insert(shim_device.offset_map, bo->mem_addr, bo);
+   mtx_unlock(&shim_device.mem_lock);
+
+   /* reuse the buffer address as the mmap offset: */
+   return bo->mem_addr;
 }
 
 /* For mmap() on the DRM fd, look up the BO from the "offset" and map the BO's
@@ -393,7 +393,15 @@ void *
 drm_shim_mmap(struct shim_fd *shim_fd, size_t length, int prot, int flags,
               int fd, off64_t offset)
 {
-   struct shim_bo *bo = (void *)(uintptr_t)offset;
+   mtx_lock(&shim_device.mem_lock);
+   struct shim_bo *bo = _mesa_hash_table_u64_search(shim_device.offset_map, offset);
+   mtx_unlock(&shim_device.mem_lock);
+
+   if (!bo)
+      return MAP_FAILED;
+
+   if (length > bo->size)
+      return MAP_FAILED;
 
    /* The offset we pass to mmap must be aligned to the page size */
    assert((bo->mem_addr & (shim_page_size - 1)) == 0);
diff --git a/src/drm-shim/drm_shim.h b/src/drm-shim/drm_shim.h
index 579d700b8e5..95cce8f4372 100644
--- a/src/drm-shim/drm_shim.h
+++ b/src/drm-shim/drm_shim.h
@@ -41,6 +41,9 @@ struct shim_device {
    /* Mapping from int fd to struct shim_fd *. */
    struct hash_table *fd_map;
 
+   /* Mapping from mmap offset to shim_bo */
+   struct hash_table_u64 *offset_map;
+
    mtx_t mem_lock;
    /* Heap from which shim_bo are allocated */
    struct util_vma_heap mem_heap;
diff --git a/src/intel/tools/intel_noop_drm_shim.c b/src/intel/tools/intel_noop_drm_shim.c
index 689a95594ad..3210740bcee 100644
--- a/src/intel/tools/intel_noop_drm_shim.c
+++ b/src/intel/tools/intel_noop_drm_shim.c
@@ -120,7 +120,8 @@ i915_ioctl_gem_mmap(int fd, unsigned long request, void *arg)
       return -1;
 
    if (!bo->map)
-      bo->map = drm_shim_mmap(shim_fd, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, -1, (uintptr_t)bo);
+      bo->map = drm_shim_mmap(shim_fd, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, -1,
+                              drm_shim_bo_get_mmap_offset(shim_fd, bo));
 
    mmap_arg->addr_ptr = (uint64_t) (bo->map + mmap_arg->offset);
 



More information about the mesa-commit mailing list