Re: [PATCH v3] drm/panthor: use local variables for firmware interface counts

[email protected] Mon, 03 Aug 2026 14:33:18 +0000
Newsgroups org.freedesktop.lists.dri-devel
Message-ID <[email protected]>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

Pre-existing issues:
- [High] The patch prevents TOCTOU vulnerabilities during firmware interface initialization by using READ_ONCE() for `group_num` and `stream_num`, but fails to apply this protection to `panthor_sched_init()`, which re-reads these exact same fields directly from the volatile firmware-shared memory. This can lead to an initialization mismatch and a subsequent NULL pointer dereference.
- [High] Userspace queue creation validates `group_args->queues.count` against the hardcoded `MAX_CS_PER_CSG`, but fails to validate it against the firmware-reported and initialized `cs_slot_count`, allowing a NULL pointer dereference.
- [Medium] The patch adds `READ_ONCE()` for `group_num` and `stream_num` but leaves `group_stride` and `stream_stride` unprotected, allowing potential out-of-bounds memory accesses if the compiler rematerializes the reads.
--

--- Patch [1]: [PATCH v3] drm/panthor: use local variables for firmware interface counts ---
commit 49abfdca3f9a1c66d7525434ea16162686b42354
Author: Osama Abdelkader <[email protected]>

drm/panthor: use local variables for firmware interface counts

The firmware exposes the global group count and per-group stream count in
the shared control interface. These values are validated before being used
as loop bounds.

> diff --git a/drivers/gpu/drm/panthor/panthor_fw.c b/drivers/gpu/drm/panthor/panthor_fw.c
> index 10b7e12c1f1ed..fbc4d10aed1fb 100644
> --- a/drivers/gpu/drm/panthor/panthor_fw.c
> +++ b/drivers/gpu/drm/panthor/panthor_fw.c
> @@ -955,6 +955,7 @@ static int panthor_init_csg_iface(struct panthor_device *ptdev,
>  	u64 shared_section_sz = panthor_kernel_bo_size(ptdev->fw->shared_section->mem);
>  	u64 iface_offset = CSF_GROUP_CONTROL_OFFSET +
>  			   ((u64)csg_idx * glb_iface->control->group_stride);

[Severity: Medium]
This isn't a bug introduced by this patch, but since we are preventing
TOCTOU vulnerabilities with READ_ONCE(), should group_stride (and
stream_stride in panthor_init_cs_iface) also be protected?

If the compiler rematerializes the reads for the strides after the bounds
checks, could a malicious firmware modify the stride concurrently and cause
out-of-bounds pointer arithmetic when setting up the interface pointers?

> +	u32 stream_num;
>  	unsigned int i;
>  
>  	if (iface_offset > shared_section_sz ||

[ ... ]

> @@ -1036,13 +1043,18 @@ static int panthor_fw_init_ifaces(struct panthor_device *ptdev)
>  		return -EINVAL;
>  	}
>  
> -	if (glb_iface->control->group_num > MAX_CSGS ||
> -	    glb_iface->control->group_num < MIN_CSGS) {
> +	/*
> +	 * To protect against self-modifying control sections
> +	 * take a single snapshot from the control section so validation and
> +	 * iteration use the same value.
> +	 */
> +	group_num = READ_ONCE(glb_iface->control->group_num);
> +	if (group_num > MAX_CSGS || group_num < MIN_CSGS) {
>  		drm_err(&ptdev->base, "Invalid number of control groups");
>  		return -EINVAL;
>  	}

[Severity: High]
This is a pre-existing issue, but does the scheduler also need to use these
protected values?

In drivers/gpu/drm/panthor/panthor_sched.c:panthor_sched_init(), the code
re-reads these fields directly from the volatile firmware memory:

	sched->csg_slot_count = num_groups;
	sched->cs_slot_count = csg_iface->control->stream_num;

If the firmware increases stream_num after the bounds checks here in
panthor_fw_init_ifaces(), could the scheduler configure cs_slot_count to a
larger value than the initialized structures in ptdev->fw->iface?

Later, when iterating up to these counts in tick_ctx_apply() or
csg_slot_prog_locked(), could the driver retrieve a zero-initialized
interface structure and dereference NULL pointers?


[Severity: High]
This is also a pre-existing issue, but is the userspace queue count properly
bounded by the initialized firmware slot count?

In drivers/gpu/drm/panthor/panthor_drv.c:panthor_ioctl_group_create(),
the queue count is validated against the hardcoded maximum:

	if (!args->queues.count || args->queues.count > MAX_CS_PER_CSG)
		return -EINVAL;

However, if the firmware reports fewer slots than MAX_CS_PER_CSG,
panthor_fw_init_ifaces() will only initialize that smaller number of
stream interfaces.

If unprivileged userspace requests more queues than the firmware reported
(but less than MAX_CS_PER_CSG), could cs_slot_prog_locked() fetch an
uninitialized stream interface and crash when dereferencing
cs_iface->input->ringbuf_base?

-- 
Sashiko AI review ยท https://sashiko.dev/#/patchset/[email protected]?part=1