Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/panthor: Fix UAF in panthor_gem_create_with_handle() debugfs code

The object is potentially already gone after the drm_gem_object_put().
In general the object should be fully constructed before calling
drm_gem_handle_create(), except the debugfs tracking uses a separate
lock and list and separate flag to denotate whether the object is
actually initialized.

Since I'm touching this all anyway simplify this by only adding the
object to the debugfs when it's ready for that, which allows us to
delete that separate flag. panthor_gem_debugfs_bo_rm() already checks
whether we've actually been added to the list or this is some error
path cleanup.

v2: Fix build issues for !CONFIG_DEBUGFS (Adrián)

v3: Add linebreak and remove outdated comment (Liviu)

Fixes: a3707f53eb3f ("drm/panthor: show device-wide list of DRM GEM objects over DebugFS")
Cc: Adrián Larumbe <adrian.larumbe@collabora.com>
Cc: Boris Brezillon <boris.brezillon@collabora.com>
Cc: Steven Price <steven.price@arm.com>
Cc: Liviu Dudau <liviu.dudau@arm.com>
Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
Signed-off-by: Simona Vetter <simona.vetter@intel.com>
Signed-off-by: Simona Vetter <simona.vetter@ffwll.ch>
Reviewed-by: Steven Price <steven.price@arm.com>
Signed-off-by: Steven Price <steven.price@arm.com>
Link: https://lore.kernel.org/r/20250709135220.1428931-1-simona.vetter@ffwll.ch

authored by

Simona Vetter and committed by
Steven Price
fe69a391 0f168e7b

+15 -19
+15 -16
drivers/gpu/drm/panthor/panthor_gem.c
··· 16 16 #include "panthor_mmu.h" 17 17 18 18 #ifdef CONFIG_DEBUG_FS 19 - static void panthor_gem_debugfs_bo_add(struct panthor_device *ptdev, 20 - struct panthor_gem_object *bo) 19 + static void panthor_gem_debugfs_bo_init(struct panthor_gem_object *bo) 21 20 { 22 21 INIT_LIST_HEAD(&bo->debugfs.node); 22 + } 23 + 24 + static void panthor_gem_debugfs_bo_add(struct panthor_gem_object *bo) 25 + { 26 + struct panthor_device *ptdev = container_of(bo->base.base.dev, 27 + struct panthor_device, base); 23 28 24 29 bo->debugfs.creator.tgid = current->group_leader->pid; 25 30 get_task_comm(bo->debugfs.creator.process_name, current->group_leader); ··· 49 44 50 45 static void panthor_gem_debugfs_set_usage_flags(struct panthor_gem_object *bo, u32 usage_flags) 51 46 { 52 - bo->debugfs.flags = usage_flags | PANTHOR_DEBUGFS_GEM_USAGE_FLAG_INITIALIZED; 47 + bo->debugfs.flags = usage_flags; 48 + panthor_gem_debugfs_bo_add(bo); 53 49 } 54 50 #else 55 - static void panthor_gem_debugfs_bo_add(struct panthor_device *ptdev, 56 - struct panthor_gem_object *bo) 57 - {} 58 51 static void panthor_gem_debugfs_bo_rm(struct panthor_gem_object *bo) {} 59 52 static void panthor_gem_debugfs_set_usage_flags(struct panthor_gem_object *bo, u32 usage_flags) {} 53 + static void panthor_gem_debugfs_bo_init(struct panthor_gem_object *bo) {} 60 54 #endif 61 55 62 56 static void panthor_gem_free_object(struct drm_gem_object *obj) ··· 250 246 drm_gem_gpuva_set_lock(&obj->base.base, &obj->gpuva_list_lock); 251 247 mutex_init(&obj->label.lock); 252 248 253 - panthor_gem_debugfs_bo_add(ptdev, obj); 249 + panthor_gem_debugfs_bo_init(obj); 254 250 255 251 return &obj->base.base; 256 252 } ··· 289 285 bo->base.base.resv = bo->exclusive_vm_root_gem->resv; 290 286 } 291 287 288 + panthor_gem_debugfs_set_usage_flags(bo, 0); 289 + 292 290 /* 293 291 * Allocate an id of idr table where the obj is registered 294 292 * and handle has the id what user can see. ··· 301 295 302 296 /* drop reference from allocate - handle holds it now. */ 303 297 drm_gem_object_put(&shmem->base); 304 - 305 - /* 306 - * No explicit flags are needed in the call below, since the 307 - * function internally sets the INITIALIZED bit for us. 308 - */ 309 - panthor_gem_debugfs_set_usage_flags(bo, 0); 310 298 311 299 return ret; 312 300 } ··· 387 387 unsigned int refcount = kref_read(&bo->base.base.refcount); 388 388 char creator_info[32] = {}; 389 389 size_t resident_size; 390 - u32 gem_usage_flags = bo->debugfs.flags & (u32)~PANTHOR_DEBUGFS_GEM_USAGE_FLAG_INITIALIZED; 390 + u32 gem_usage_flags = bo->debugfs.flags; 391 391 u32 gem_state_flags = 0; 392 392 393 393 /* Skip BOs being destroyed. */ ··· 436 436 437 437 scoped_guard(mutex, &ptdev->gems.lock) { 438 438 list_for_each_entry(bo, &ptdev->gems.node, debugfs.node) { 439 - if (bo->debugfs.flags & PANTHOR_DEBUGFS_GEM_USAGE_FLAG_INITIALIZED) 440 - panthor_gem_debugfs_bo_print(bo, m, &totals); 439 + panthor_gem_debugfs_bo_print(bo, m, &totals); 441 440 } 442 441 } 443 442
-3
drivers/gpu/drm/panthor/panthor_gem.h
··· 35 35 36 36 /** @PANTHOR_DEBUGFS_GEM_USAGE_FLAG_FW_MAPPED: BO is mapped on the FW VM. */ 37 37 PANTHOR_DEBUGFS_GEM_USAGE_FLAG_FW_MAPPED = BIT(PANTHOR_DEBUGFS_GEM_USAGE_FW_MAPPED_BIT), 38 - 39 - /** @PANTHOR_DEBUGFS_GEM_USAGE_FLAG_INITIALIZED: BO is ready for DebugFS display. */ 40 - PANTHOR_DEBUGFS_GEM_USAGE_FLAG_INITIALIZED = BIT(31), 41 38 }; 42 39 43 40 /**