The dma_free_coherent() should be called when memory fails to
be allocated for list, or drm_map_handle() fails, otherwise there
will be a memory leak, so add dma_free_coherent to fix it.

In addition, if drm_map_handle() fails in drm_addmap_core(), list
will be freed, but list->head will not be removed from dev->map_list,
then list traversal may cause UAF, fix it by removeing it from
dev->map_list before kfree().

Fixes: 8e4ff9b56957 ("drm: Remove the dma_alloc_coherent wrapper for internal 
usage")
Fixes: 8d153f7107ff ("drm: update user token hashing and map handles")
Signed-off-by: Gaosheng Cui <cuigaoshe...@huawei.com>
---
 drivers/gpu/drm/drm_bufs.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c
index fcca21e8efac..3b9563194715 100644
--- a/drivers/gpu/drm/drm_bufs.c
+++ b/drivers/gpu/drm/drm_bufs.c
@@ -344,6 +344,8 @@ static int drm_addmap_core(struct drm_device *dev, 
resource_size_t offset,
        if (!list) {
                if (map->type == _DRM_REGISTERS)
                        iounmap(map->handle);
+               if (map->type == _DRM_CONSISTENT)
+                       dma_free_coherent(dev->dev, map->size, map->handle, 
map->offset);
                kfree(map);
                return -EINVAL;
        }
@@ -361,7 +363,10 @@ static int drm_addmap_core(struct drm_device *dev, 
resource_size_t offset,
        if (ret) {
                if (map->type == _DRM_REGISTERS)
                        iounmap(map->handle);
+               if (map->type == _DRM_CONSISTENT)
+                       dma_free_coherent(dev->dev, map->size, map->handle, 
map->offset);
                kfree(map);
+               list_del(&list->head);
                kfree(list);
                mutex_unlock(&dev->struct_mutex);
                return ret;
-- 
2.25.1

Reply via email to