All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Jonghyuk Kim(MalHyuk)" <malhyuk97@gmail.com>
Cc: dri-devel@lists.freedesktop.org
Subject: Re: [PATCH v4 1/3] drm/sched: cache the timeline name to fix a use-after-free
Date: Fri, 04 Sep 2026 08:18:28 +0000	[thread overview]
Message-ID: <20260904081829.67C321F00A3D@smtp.kernel.org> (raw)
In-Reply-To: <20260904080618.2098450-2-malhyuk97@gmail.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

New issues:
- [High] The patch attempts to fix a Use-After-Free by caching the timeline name in `fence->sched_name`, but it introduces a direct Use-After-Free of the string memory itself. The commit message incorrectly assumes all drivers pass a string literal or keep the string alive via RCU. However, `panthor` dynamically allocates the timeline name (`kasprintf`) and synchronously frees it (`kfree(queue->name)`) when the queue is destroyed. Furthermore, for `xe`, `kfree_rcu` does not protect against a `sync_file` fd held open by userspace for an arbitrary duration (userspace holding an fd does not equate to holding an RCU read lock). When userspace queries the fence info via the `SYNC_IOC_FILE_INFO` ioctl after the string is freed, `drm_sched_fence_get_timeline_name()` returns the cached pointer to the freed memory, leading to an info leak to userspace.

Pre-existing issues:
- [High] The AMDGPU driver's `amdgpu_sync_same_dev()` function incorrectly assumes that any `drm_sched_fence` belongs to an AMDGPU ring. `to_drm_sched_fence()` returns non-NULL for *any* DRM scheduler fence globally (e.g., from `panthor`, `xe`, `nouveau`). If a foreign fence is passed via a `dma-buf` or `syncobj`, `amdgpu_sync_same_dev()` unconditionally calculates `ring = container_of(s_fence->sched, struct amdgpu_ring, sched)` and dereferences `ring->adev`. This results in an out-of-bounds read (Type Confusion). Additionally, if the foreign fence originated from a per-context scheduler that has been freed (like a destroyed `panthor` queue), this results in a Use-After-Free read.
- [High] The PowerVR driver's `pvr_queue_fence_is_native()` accesses `sched_fence->sched->ops` to determine if a fence is native to the driver. However, if the `drm_sched_fence` originated from a per-context scheduler (whether from `pvr` or another driver like `panthor`) and that scheduler has been destroyed, `sched_fence->sched` is a dangling pointer. Dereferencing it to check `->ops` causes a Use-After-Free read.
--

commit 99163b915ba8e6d549d23c04536ae0f2ac030b70
Author: Jonghyuk Kim(MalHyuk) <malhyuk97@gmail.com>

drm/sched: cache the timeline name to fix a use-after-free

This commit caches the scheduler's timeline name inside drm_sched_fence to
prevent a use-after-free when a userspace-held finished fence outlives a
per-context scheduler. It documents that the name must outlive the fence,
assuming all in-tree drivers pass string literals or keep the name alive.

>     Every in-tree driver passes a string literal, which satisfies this;

[Severity: High]
Is this assumption correct for all in-tree drivers?

For example, panthor dynamically allocates the timeline name and synchronously
frees it when the queue is destroyed:

drivers/gpu/drm/panthor/panthor_sched.c:group_free_queue() {
    ...
    kfree(queue->name);
    ...
}

If a user creates a panthor queue, submits a job to get a fence, exports it
to a sync_file, and destroys the queue, the string memory is freed. When
userspace then queries the fence info via the SYNC_IOC_FILE_INFO ioctl,
wouldn't the cached pointer point to freed memory, leading to an info leak?

> diff --git a/drivers/gpu/drm/scheduler/sched_fence.c b/drivers/gpu/drm/scheduler/sched_fence.c
> index 096fe28aa9c9e..b2a842a1c9ba9 100644
> --- a/drivers/gpu/drm/scheduler/sched_fence.c
> +++ b/drivers/gpu/drm/scheduler/sched_fence.c
> @@ -92,7 +92,13 @@ static const char *drm_sched_fence_get_driver_name(struct dma_fence *fence)
>  static const char *drm_sched_fence_get_timeline_name(struct dma_fence *f)
>  {
>  	struct drm_sched_fence *fence = to_drm_sched_fence(f);
> -	return (const char *)fence->sched->name;
> +
> +	/*
> +	 * Do not dereference fence->sched here: a userspace-held finished
> +	 * fence can outlive a per-context scheduler. Return the name cached
> +	 * in drm_sched_fence_init() instead.
> +	 */
> +	return fence->sched_name;

[Severity: High]
Does returning this cached pointer just replace the scheduler use-after-free
with a string memory use-after-free?

Because drivers like panthor can free the string memory synchronously during
queue destruction, this cached pointer will point to freed memory when read
by the caller.

[ ... ]

> @@ -228,6 +242,14 @@ void drm_sched_fence_init(struct drm_sched_fence *fence,
>  	unsigned seq;
>  
>  	fence->sched = entity->rq->sched;
> +	/*
> +	 * Cache the scheduler's timeline name. The finished fence may be
> +	 * exported to userspace and outlive @sched (per-context schedulers are
> +	 * freed on context teardown), so get_timeline_name() must not
> +	 * dereference @sched. The name is required to outlive any exported
> +	 * fence (see @name in struct drm_sched_init_args).
> +	 */
> +	fence->sched_name = fence->sched->name;

[Severity: High]
Does caching the string pointer here without taking ownership or extending
its lifetime erroneously assume the string will inherently outlive the fence?

This is a pre-existing issue, but the dangling fence->sched pointer causes
problems in other drivers as well when foreign fences are imported.

[Severity: High]
Does the AMDGPU driver's amdgpu_sync_same_dev() incorrectly assume any
drm_sched_fence globally belongs to an AMDGPU ring?

drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c:amdgpu_sync_same_dev() {
    ...
    ring = container_of(s_fence->sched, struct amdgpu_ring, sched);
    return ring->adev == adev;
}

If a foreign fence from another driver (e.g., panthor) is passed via a dma-buf
or syncobj and used as an input dependency to the AMDGPU command submission
ioctl, this unconditional container_of() calculation will dereference an
invalid or freed pointer. Can this lead to an out-of-bounds type confusion
read, or a use-after-free read if the original per-context scheduler was
already destroyed?

This is also a pre-existing issue, but similar to the AMDGPU issue above,
does the PowerVR driver also dereference a freed scheduler pointer?

[Severity: High]
drivers/gpu/drm/imagination/pvr_queue.c:pvr_queue_fence_is_native() {
    ...
    if (sched_fence &&
        sched_fence->sched->ops == &pvr_queue_sched_ops)
    ...
}

If a user exports a drm_sched_fence from a queue, destroys that queue (freeing
the scheduler), and then passes the fence as an input dependency to the PVR
job submission ioctl, sched_fence->sched will be a dangling pointer. Will
dereferencing it to check the ops field cause a use-after-free read?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260904080618.2098450-1-malhyuk97@gmail.com?part=1

  reply	other threads:[~2026-09-04  8:18 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-04  8:06 [PATCH v4 0/3] drm/sched: fix use-after-free of the fence timeline name Jonghyuk Kim(MalHyuk)
2026-09-04  8:06 ` [PATCH v4 1/3] drm/sched: cache the timeline name to fix a use-after-free Jonghyuk Kim(MalHyuk)
2026-09-04  8:18   ` sashiko-bot [this message]
2026-09-04  8:20   ` Christian König
2026-09-04  8:31     ` Philipp Stanner
2026-09-04 12:49       ` Christian König
2026-09-04 19:06         ` Philipp Stanner
2026-09-07  9:15           ` Tvrtko Ursulin
2026-09-07  9:42             ` Philipp Stanner
2026-09-07  9:49               ` Philipp Stanner
2026-09-07 10:28               ` Tvrtko Ursulin
2026-09-07 10:34                 ` Tvrtko Ursulin
2026-09-07 10:47                 ` Philipp Stanner
2026-09-07 11:06                   ` Tvrtko Ursulin
2026-09-07 11:15                     ` Philipp Stanner
2026-09-07 12:59                       ` Christian König
2026-09-07 13:38                         ` Philipp Stanner
2026-09-07 15:21                           ` Christian König
2026-09-08 10:49                             ` Jonghyuk Kim(MalHyuk)
2026-09-08 11:07                               ` Philipp Stanner
2026-09-09  0:37                                 ` Jonghyuk Kim(MalHyuk)
2026-09-09  7:44                                   ` Philipp Stanner
2026-09-07 12:28                     ` Tvrtko Ursulin
2026-09-08 15:20                       ` Tvrtko Ursulin
2026-09-07 12:18               ` Alessio Belle
2026-09-07 11:42           ` Christian König
2026-09-07 11:54             ` Philipp Stanner
2026-09-04  8:31     ` Jonghyuk Kim(MalHyuk)
2026-09-04  8:39       ` Philipp Stanner
2026-09-04  9:11         ` Jonghyuk Kim(MalHyuk)
2026-09-04  9:07       ` Tvrtko Ursulin
2026-09-04  9:57   ` Danilo Krummrich
2026-09-04 10:51     ` Philipp Stanner
2026-09-04  8:06 ` [PATCH v4 2/3] drm/sched: add the fence ops-detach cleanup to the TODO list Jonghyuk Kim(MalHyuk)
2026-09-04  8:06 ` [PATCH v4 3/3] drm/sched/tests: add a UAF regression test for the timeline name Jonghyuk Kim(MalHyuk)
2026-09-04  8:15   ` sashiko-bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260904081829.67C321F00A3D@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=malhyuk97@gmail.com \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.