dri-devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Dmitry Baryshkov" <dmitry.baryshkov@oss.qualcomm.com>
Cc: dri-devel@lists.freedesktop.org, wsa+renesas@sang-engineering.com
Subject: Re: [PATCH v7 8/9] drm: writeback: clean up writeback connectors in drm_connector_cleanup()
Date: Mon, 19 Oct 2026 13:30:46 +0000	[thread overview]
Message-ID: <sashiko-outbox-177157@kernel.org> (raw)
In-Reply-To: <20261019-wb-drop-encoder-v7-8-d4288a26eb54@oss.qualcomm.com>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] drm: out-of-bounds access in drm_writeback_connector_cleanup() downcast
- [High] drm: writeback: drm_writeback_cleanup_job() called under spin_lock_irqsave()
--

commit 01e86ffc01bb0a8fee1f22a88d9725baf85bf61d
Author: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>

drm: writeback: clean up writeback connectors in drm_connector_cleanup()

This commit calls drm_writeback_connector_cleanup() from
drm_connector_cleanup() for writeback connectors so that connectors
initialized with drm_writeback_connector_init() also drop their formats
blob and clean up queued writeback jobs upon teardown.

> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index 893716a9e4895..1c2bef5e06363 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -929,6 +929,9 @@ void drm_connector_cleanup(struct drm_connector *connector)
>  	if (connector->hdmi.scdc_work_initialized)
>  		cancel_delayed_work_sync(&connector->hdmi.scdc_work);
>  
> +	if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
> +		drm_writeback_connector_cleanup(connector);
> +
>  	platform_device_unregister(connector->hdmi_audio.codec_pdev);
>  
>  	if (connector->privacy_screen) {

[Severity: High]
Is every connector with connector_type == DRM_MODE_CONNECTOR_WRITEBACK
guaranteed to be embedded inside a struct drm_writeback_connector?

Unlike connector->hdmi and connector->hdmi_audio, which are fields inside
struct drm_connector itself, drm_writeback_connector_cleanup() downcasts
connector via drm_connector_to_writeback() and accesses
wb_connector->pixel_formats_blob_ptr, wb_connector->job_lock, and
wb_connector->job_queue beyond sizeof(struct drm_connector).

However, drm_connector_init(), drmm_connector_init(), and
drm_connector_dynamic_init() allow initializing a plain struct
drm_connector (or a different wrapper struct) with
DRM_MODE_CONNECTOR_WRITEBACK, and several in-tree KUnit tests do so:

1. In drivers/gpu/drm/tests/drm_connector_test.c, struct
drm_connector_init_priv places a plain struct drm_connector immediately
before struct i2c_adapter ddc:

struct drm_connector_init_priv {
	struct drm_device drm;
	struct drm_connector connector;
	struct i2c_adapter ddc;
};

When drm_test_drmm_connector_init_type_valid() or
drm_test_drm_connector_dynamic_init_type_valid() initializes
priv->connector with DRM_MODE_CONNECTOR_WRITEBACK and later cleans it up
via drm_connector_cleanup(), wb_connector->pixel_formats_blob_ptr aliases
priv->ddc.owner (set to THIS_MODULE). When built as a module,
drm_writeback_connector_cleanup() passes THIS_MODULE to
drm_property_blob_put(), zeroes priv->ddc.owner, locks priv->ddc memory as
job_lock, and iterates job_queue over priv->ddc fields.

2. In drivers/gpu/drm/vc4/tests/vc4_mock_output.c, vc4_dummy_output()
allocates struct vc4_dummy_output (ending with a plain struct
drm_connector) and calls drmm_connector_init() with
DRM_MODE_CONNECTOR_WRITEBACK, causing drm_writeback_connector_cleanup() to
read past the end of the slab allocation.

3. In drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_audio_test.c,
dm_test_audio_component_get_eld_copies_matching_connector() allocates
sizeof(struct drm_connector) with DRM_MODE_CONNECTOR_WRITEBACK and cleans
it up via drm_connector_cleanup(), also reading out of bounds.

Could this out-of-bounds access be avoided by tracking writeback
initialization on struct drm_connector or only cleaning up when initialized
through the writeback connector helpers?

[ ... ]

> diff --git a/drivers/gpu/drm/drm_writeback.c b/drivers/gpu/drm/drm_writeback.c
> index 2f6a7b50336c0..272012a70efee 100644
> --- a/drivers/gpu/drm/drm_writeback.c
> +++ b/drivers/gpu/drm/drm_writeback.c
> @@ -271,21 +273,27 @@ EXPORT_SYMBOL(drm_writeback_connector_init);
>  
>  /**
>   * drm_writeback_connector_cleanup - Cleanup the writeback connector
> - * @dev: DRM device
> - * @data: Pointer to the writeback connector to clean up
> + * @connector: Writeback connector to clean up
>   *
>   * This will decrement the reference counter of blobs. It will also clean the
>   * remaining jobs in this writeback connector. Caution: This helper will not
>   * clean up the attached encoder and the drm_connector.
> + *
> + * Called from drm_connector_cleanup() for all writeback connectors.
>   */
> -static void drm_writeback_connector_cleanup(struct drm_device *dev,
> -					    void *data)
> +void drm_writeback_connector_cleanup(struct drm_connector *connector)
>  {
> -	unsigned long flags;
> +	struct drm_writeback_connector *wb_connector =
> +		drm_connector_to_writeback(connector);
>  	struct drm_writeback_job *pos, *n;
> -	struct drm_writeback_connector *wb_connector = data;
> +	unsigned long flags;
> +
> +	/* __drm_writeback_connector_init() has failed */
> +	if (!wb_connector->pixel_formats_blob_ptr)
> +		return;
>  
>  	drm_property_blob_put(wb_connector->pixel_formats_blob_ptr);
> +	wb_connector->pixel_formats_blob_ptr = NULL;
>  
>  	spin_lock_irqsave(&wb_connector->job_lock, flags);
>  	list_for_each_entry_safe(pos, n, &wb_connector->job_queue, list_entry) {
>  		list_del(&pos->list_entry);
>  		drm_writeback_cleanup_job(pos);
>  	}
>  	spin_unlock_irqrestore(&wb_connector->job_lock, flags);
>  }

[Severity: High]
Can drm_writeback_cleanup_job() be safely called while holding
wb_connector->job_lock with interrupts disabled?

When drm_connector_cleanup() tears down a writeback connector that still
has queued jobs, drm_writeback_connector_cleanup() holds
spin_lock_irqsave(&wb_connector->job_lock, flags) across
drm_writeback_cleanup_job():

drm_writeback_connector_cleanup()
  spin_lock_irqsave(&wb_connector->job_lock, flags)
  drm_writeback_cleanup_job()
    funcs->cleanup_writeback_job()
    drm_framebuffer_put()

Inside drm_writeback_cleanup_job(), dropping the final reference via
drm_framebuffer_put() calls drm_framebuffer_free() ->
drm_mode_object_unregister(), which acquires
mutex_lock(&dev->mode_config.idr_mutex), as well as
drm_framebuffer_cleanup(), which acquires
mutex_lock(&dev->object_name_lock) and
mutex_lock(&dev->mode_config.fb_lock).

In addition, hooking drm_writeback_connector_cleanup() into
drm_connector_cleanup() makes this path reachable for drivers using
drm_writeback_connector_init() such as amdgpu, where
amdgpu_dm_wb_cleanup_job() calls wb_bo_reserve() -> amdgpu_bo_reserve()
and acquires a sleeping dma_resv ww_mutex.

Should the jobs be spliced onto a local list under wb_connector->job_lock
and cleaned up after spin_unlock_irqrestore()?

[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261019-wb-drop-encoder-v7-0-d4288a26eb54@oss.qualcomm.com?part=8

  reply	other threads:[~2026-10-19 13:30 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-19 13:12 [PATCH v7 0/9] drm: writeback: clean up writeback connector initialization Dmitry Baryshkov
2026-10-19 13:12 ` [PATCH v7 1/9] drm/amd/display: embed the writeback encoder in amdgpu_dm_wb_connector Dmitry Baryshkov
2026-10-20 19:14   ` Harry Wentland
2026-10-19 13:12 ` [PATCH v7 2/9] drm/komeda: embed the writeback encoder in komeda_wb_connector Dmitry Baryshkov
2026-10-19 13:12 ` [PATCH v7 3/9] drm/mali: embed the writeback encoder in malidp_drm Dmitry Baryshkov
2026-10-19 13:12 ` [PATCH v7 4/9] drm: renesas: rcar-du: embed the writeback encoder in rcar_du_crtc Dmitry Baryshkov
2026-10-19 13:12 ` [PATCH v7 5/9] drm: writeback: drop excess connector initialization functions Dmitry Baryshkov
2026-10-19 13:12 ` [PATCH v7 6/9] drm: writeback: rename drm_writeback_connector_init_with_encoder() Dmitry Baryshkov
2026-10-20  1:22   ` Chaoyi Chen
2026-10-19 13:12 ` [PATCH v7 7/9] drm: writeback: don't destroy the shared writeback properties Dmitry Baryshkov
2026-10-20  1:28   ` Chaoyi Chen
2026-10-19 13:12 ` [PATCH v7 8/9] drm: writeback: clean up writeback connectors in drm_connector_cleanup() Dmitry Baryshkov
2026-10-19 13:30   ` sashiko-bot [this message]
2026-10-21 18:22   ` John Harrison
2026-10-22 11:59     ` Dmitry Baryshkov
2026-10-22 15:52       ` John Harrison
2026-10-19 13:12 ` [PATCH v7 9/9] drm: writeback: drop the drmm writeback cleanup action Dmitry Baryshkov
2026-10-21 18:32   ` John Harrison
2026-10-19 19:40 ` [PATCH v7 0/9] drm: writeback: clean up writeback connector initialization John Harrison
2026-10-22 12:01   ` Dmitry Baryshkov
2026-10-23 10:21 ` Liviu Dudau

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=sashiko-outbox-177157@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=dmitry.baryshkov@oss.qualcomm.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=wsa+renesas@sang-engineering.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox