From: sashiko-bot@kernel.org
To: "Maxime Ripard" <mripard@kernel.org>
Cc: dri-devel@lists.freedesktop.org
Subject: Re: [PATCH v6 13/28] drm/atomic_sro: Provide helpers to implement hardware state readout
Date: Thu, 15 Oct 2026 16:21:33 +0000 [thread overview]
Message-ID: <sashiko-outbox-173171@kernel.org> (raw)
In-Reply-To: <20261015-drm-state-readout-v6-13-6cc02cd10998@kernel.org>
Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:
- [High] drm: NULL pointer dereference in drm_atomic_helper_sro_readout_state() due to missing fallback
- [High] drm: NULL pointer dereference for legacy bridges in drm_atomic_helper_sro_readout_bridges_state()
- [High] drm/atomic_sro: NULL pointer dereference in disabled bridge readout
- [High] drm/atomic_sro: out-of-bounds write in connector state array
- [Medium] drm: O(N^2) loop and OOB read risk in drm_atomic_sro_install_state()
- [Low] drm/atomic: error code shadowed in drm_atomic_helper_sro_build_state()
--
commit 4ec8820a89de05a3189db7a50590573132825dee
Author: Maxime Ripard <mripard@kernel.org>
drm/atomic_sro: Provide helpers to implement hardware state readout
Drivers implementing SRO need to iterate over their KMS objects,
allocate a pristine state for each, call the readout hook, and store
the result in the SRO state container. Provide helpers for each object type
and a top-level function that calls them in sequence.
> diff --git a/drivers/gpu/drm/drm_atomic_sro_helper.c b/drivers/gpu/drm/drm_atomic_sro_helper.c
> new file mode 100644
> index 0000000000000..50d1af53bfc24
> --- /dev/null
> +++ b/drivers/gpu/drm/drm_atomic_sro_helper.c
[ ... ]
> +int
> +drm_atomic_helper_sro_readout_bridges_state(struct drm_device *dev,
> + struct drm_atomic_sro_state *state)
> +{
> + struct drm_encoder *encoder;
> +
> + might_alloc(GFP_KERNEL);
[ ... ]
> + drm_for_each_encoder(encoder, dev) {
> + struct drm_bridge *bridge;
> + int ret;
> +
> + list_for_each_entry(bridge, &encoder->bridge_chain, chain_node) {
> + struct drm_private_obj *bridge_obj = &bridge->base;
> + const struct drm_private_state_funcs *bridge_obj_funcs =
> + bridge_obj->funcs;
> + struct drm_private_state *bridge_obj_state;
> +
> + if (!bridge_obj_funcs->atomic_sro_readout_state) {
[Severity: High]
Can bridge_obj_funcs be NULL here for legacy non-atomic bridges?
Legacy (non-atomic) bridges do not call drm_atomic_private_obj_init() during
attachment. This means their embedded bridge->base is uninitialized, and its
funcs pointer remains NULL.
If this readout helper encounters a non-atomic bridge in the encoder's bridge
chain, dereferencing bridge_obj_funcs unconditionally will cause a NULL
pointer dereference.
> + drm_warn(dev,
> + "No bridge %s readout implementation.",
> + bridge->name);
> + continue;
> + }
[ ... ]
> +struct drm_atomic_sro_state *
> +drm_atomic_helper_sro_build_state(struct drm_device *dev)
> +{
> + struct drm_atomic_sro_state *state;
> + struct drm_printer p = drm_dbg_printer(dev, DRM_UT_ATOMIC, NULL);
> + int ret;
> +
> + drm_dbg_kms(dev, "Starting to build atomic state from hardware state.\n");
> +
> + state = drm_atomic_sro_state_alloc(dev);
> + if (drm_WARN_ON(dev, IS_ERR(state)))
> + return ERR_PTR(-ENOMEM);
[Severity: Low]
Does this error handling shadow the actual error pointer returned by
drm_atomic_sro_state_alloc()?
In drm_atomic_sro_state_alloc(), an allocation failure incorrectly returns
ERR_PTR(-EINVAL). Then, this function masks that error pointer and replaces
it with ERR_PTR(-ENOMEM) instead of propagating it.
While this results in a misleading error code on failure, it also violates
standard kernel error propagation patterns where the true error pointer is
typically returned directly.
> +
> + ret = drm_atomic_helper_sro_readout_crtcs_state(dev, state);
> + if (ret)
> + goto err_state_free;
[ ... ]
> +int drm_atomic_helper_sro_readout_state(struct drm_device *dev)
> +{
> + const struct drm_mode_config_helper_funcs *funcs =
> + dev->mode_config.helper_private;
> + struct drm_atomic_sro_state *state;
> +
> + if (!drm_atomic_sro_device_can_readout(dev)) {
> + drm_info(dev, "Device doesn't support hardware state readout.");
> + return -ENOTSUPP;
> + }
> +
> + state = funcs->atomic_sro_build_state(dev);
[Severity: High]
Does this code handle cases where funcs is NULL, or where
funcs->atomic_sro_build_state is NULL?
The documentation for atomic_sro_build_state states that
drm_atomic_helper_sro_build_state() is the default implementation, which
implies drivers are not required to provide a custom hook.
If a driver does not provide this hook, or does not use helper private data,
calling funcs->atomic_sro_build_state(dev) unconditionally will result in a
NULL pointer dereference.
> + if (IS_ERR(state))
> + return PTR_ERR(state);
> +
> + drm_atomic_sro_install_state(state);
> + drm_atomic_sro_state_free(state);
> +
> + return 0;
> +}
[Severity: High]
Is there a risk of a NULL pointer dereference during disabled bridge readout
when using drm_atomic_sro_get_crtc_state()?
If the bridge readout is called when the pipeline is inactive, a connector
state may not have an associated CRTC. The
drm_bridge_atomic_readout_priv_state() hook appears to pass this NULL CRTC
directly to drm_atomic_sro_get_crtc_state():
drm_bridge.c:drm_bridge_atomic_readout_priv_state() {
...
crtc_state = drm_atomic_sro_get_crtc_state(state, conn_state->crtc);
...
}
Which unconditionally dereferences the CRTC pointer to fetch its index:
drm_atomic_sro.c:drm_atomic_sro_get_crtc_state() {
...
unsigned int index = drm_crtc_index(crtc);
...
}
This can cause a kernel oops on boot if SRO is enabled and a disabled
pipeline is read out. Note that this issue was identified as being introduced
in a subsequent patch in the series and persists through the final commit.
[Severity: Medium]
Does drm_atomic_sro_install_state() have an O(N^2) loop and an out-of-bounds
read risk?
The loop condition in drm_atomic_sro_install_state() evaluates a dynamic
list count rather than the allocated array bounds:
drm_atomic_sro.c:drm_atomic_sro_install_state() {
...
for (i = 0; i < count_private_obj(state->dev); i++) {
const struct drm_private_state_funcs *obj_funcs;
struct drm_private_state *obj_state;
struct drm_private_obj *obj;
obj = state->private_objs[i].ptr;
...
}
Because count_private_obj() iterates over a linked list on every iteration,
this creates an O(N^2) time complexity. Furthermore, if a private object is
registered between the allocation of the state->private_objs array and the
invocation of this loop, count_private_obj() will return a value larger than
the allocated array size. This would lead to an out-of-bounds read of
state->private_objs[i].ptr.
Using state->num_private_objs instead of count_private_obj() would avoid
both the complexity and the bounds risk.
[Severity: High]
Does drm_atomic_sro_set_connector_state() risk an out-of-bounds write when
connector indices exceed the active connector count?
drm_atomic_sro_state_init() allocates the state->connectors array sized
strictly to the current num_connector count:
drm_atomic_sro.c:drm_atomic_sro_state_init() {
...
state->connectors = kzalloc_objs(*state->connectors,
dev->mode_config.num_connector);
if (!state->connectors) {
...
}
However, drm_connector_index(conn) returns an IDA-allocated index. If
connectors are dynamically added and removed (for example, via DP MST
hot-unplug), the IDA index can be larger than the total number of currently
registered connectors.
drm_atomic_sro_set_connector_state() blindly uses this potentially
out-of-bounds index to write into the array:
drm_atomic_sro.c:drm_atomic_sro_set_connector_state() {
...
unsigned int index = drm_connector_index(conn);
drm_connector_get(conn);
state->connectors[index].ptr = conn;
state->connectors[index].state = conn_state;
...
}
This can corrupt kernel memory if state readout is performed after connector
removals.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261015-drm-state-readout-v6-0-6cc02cd10998@kernel.org?part=13
next prev parent reply other threads:[~2026-10-15 16:21 UTC|newest]
Thread overview: 52+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-15 15:08 [PATCH v6 00/28] drm: Implement state readout support Maxime Ripard
2026-10-15 15:08 ` [PATCH v6 01/28] drm/atomic: Fix private obj error handling Maxime Ripard
2026-10-15 15:23 ` sashiko-bot
2026-10-15 15:08 ` [PATCH v6 02/28] drm/atomic: Add drm_private_obj name Maxime Ripard
2026-10-15 15:23 ` sashiko-bot
2026-10-15 15:08 ` [PATCH v6 03/28] drm/bridge: Switch print_state to use bridge name Maxime Ripard
2026-10-15 15:34 ` sashiko-bot
2026-10-15 15:08 ` [PATCH v6 04/28] drm/bridge: Add drm_private_obj_is_bridge() Maxime Ripard
2026-10-15 15:28 ` sashiko-bot
2026-10-15 15:08 ` [PATCH v6 05/28] drm/atomic: Export drm_atomic_*_print_state Maxime Ripard
2026-10-15 15:33 ` sashiko-bot
2026-10-15 15:08 ` [PATCH v6 06/28] drm/atomic_sro: Create drm_atomic_sro_state container Maxime Ripard
2026-10-15 15:41 ` sashiko-bot
2026-10-15 15:08 ` [PATCH v6 07/28] drm/atomic_sro: Create kernel parameter to force or disable readout Maxime Ripard
2026-10-15 15:46 ` sashiko-bot
2026-10-15 15:09 ` [PATCH v6 08/28] drm/atomic_sro: Add atomic state readout infrastructure Maxime Ripard
2026-10-15 15:52 ` sashiko-bot
2026-10-15 15:09 ` [PATCH v6 09/28] drm/atomic_sro: Add function to install state into drm objects Maxime Ripard
2026-10-15 15:56 ` sashiko-bot
2026-10-15 15:09 ` [PATCH v6 10/28] drm/atomic_sro: Create documentation Maxime Ripard
2026-10-15 15:59 ` sashiko-bot
2026-10-15 15:09 ` [PATCH v6 11/28] drm/bridge: Handle bridges with hardware state readout Maxime Ripard
2026-10-15 16:05 ` sashiko-bot
2026-10-15 15:09 ` [PATCH v6 12/28] drm/mode-config: Read out hardware state in drm_mode_config_create_state Maxime Ripard
2026-10-15 16:14 ` sashiko-bot
2026-10-15 15:09 ` [PATCH v6 13/28] drm/atomic_sro: Provide helpers to implement hardware state readout Maxime Ripard
2026-10-15 16:21 ` sashiko-bot [this message]
2026-10-15 15:09 ` [PATCH v6 14/28] drm/mode-config: Introduce hw_reset hook Maxime Ripard
2026-10-15 15:09 ` [PATCH v6 15/28] drm/modeset-helper: Add drm_mode_config_helper_hw_reset() Maxime Ripard
2026-10-15 15:09 ` [PATCH v6 16/28] drm/atomic_helper: Compare actual and readout states once the commit is done Maxime Ripard
2026-10-15 16:31 ` sashiko-bot
2026-10-15 15:09 ` [PATCH v6 17/28] drm/atomic-state-helper: Provide comparison macros Maxime Ripard
2026-10-15 16:39 ` sashiko-bot
2026-10-15 15:09 ` [PATCH v6 18/28] drm/atomic-state-helper: Provide atomic_compare_state helpers Maxime Ripard
2026-10-15 16:50 ` sashiko-bot
2026-10-15 15:09 ` [PATCH v6 19/28] drm/atomic-helper: Document State Read-Out as a state initialization approach Maxime Ripard
2026-10-15 16:53 ` sashiko-bot
2026-10-15 15:09 ` [PATCH v6 20/28] drm/encoder: Create atomic_sro_get_current_crtc hook Maxime Ripard
2026-10-15 15:09 ` [PATCH v6 21/28] drm/bridge: display-connector: Implement readout support Maxime Ripard
2026-10-15 16:59 ` sashiko-bot
2026-10-15 15:09 ` [PATCH v6 22/28] drm/bridge_connector: Implement hw readout for connector Maxime Ripard
2026-10-15 16:59 ` sashiko-bot
2026-10-15 15:09 ` [PATCH v6 23/28] drm/tidss: crtc: Add atomic_print_state implementation Maxime Ripard
2026-10-15 15:09 ` [PATCH v6 24/28] drm/tidss: dispc: Improve mode checking logs Maxime Ripard
2026-10-15 17:02 ` sashiko-bot
2026-10-15 15:09 ` [PATCH v6 25/28] drm/tidss: Implement hw_reset Maxime Ripard
2026-10-15 17:09 ` sashiko-bot
2026-10-15 15:09 ` [PATCH v6 26/28] drm/tidss: Implement readout support Maxime Ripard
2026-10-15 17:13 ` sashiko-bot
2026-10-15 15:09 ` [PATCH v6 27/28] drm/tidss: encoder: Implement atomic_sro_get_current_crtc Maxime Ripard
2026-10-15 15:09 ` [PATCH v6 28/28] drm/bridge: sii902x: Implement hw state readout Maxime Ripard
2026-10-15 17:20 ` 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=sashiko-outbox-173171@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=mripard@kernel.org \
--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.