Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
Pre-existing issues:
- [High] The bridge's atomic enable and disable callbacks execute sleeping functions, violating atomic context rules for display drivers.
- [High] Missing devm-based cancellation of `hpd_work` and unregistration of `dp->aux` leads to a Use-After-Free of devres-managed resources on physical device unbind.
- [High] Out-of-bounds reads and writes in link training arrays due to unbounded lane count derived from untrusted DPCD.
- [High] Missing `reinit_completion()` in DP AUX transfer causes premature completion and data corruption.
--
--- Patch [5]: [PATCH v11 05/21] drm/bridge: synopsys: dw-dp: Add missing mutex cleanups on module removal ---
commit 1e2ea3ee5b8e223fa29b59cba2907fd3cca590e6
Author: Sebastian Reichel <[email protected]>
drm/bridge: synopsys: dw-dp: Add missing mutex cleanups on module removal
The driver is currently missing to fully clean up after itself. Ensure
that the mutex is cleaned up.
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-dp.c b/drivers/gpu/drm/bridge/synopsys/dw-dp.c
> index 52e3b37259a69..b1856418f4419 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-dp.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-dp.c
> @@ -2040,10 +2040,13 @@ struct dw_dp *dw_dp_probe(struct platform_device *pdev, const struct dw_dp_plat_
> dp->pixel_mode = plat_data->pixel_mode;
> dp->plat_data.max_link_rate = plat_data->max_link_rate;
>
> - mutex_init(&dp->irq_lock);
> INIT_WORK(&dp->hpd_work, dw_dp_hpd_work);
[Severity: High]
This is a pre-existing issue, but by making the irq_lock managed by devres,
does this workqueue now trigger a use-after-free on device unbind?
If the physical device is unbound (e.g., via sysfs) while the DRM master is
still active, devres will destroy dp->irq_lock and free the dp structure.
However, hpd_work is only cancelled in dw_dp_bridge_detach(), which is tied
to the DRM master's lifecycle.
If the worker executes:
drivers/gpu/drm/bridge/synopsys/dw-dp.c:dw_dp_hpd_work() {
...
mutex_lock(&dp->irq_lock);
...
}
Will it attempt to lock the destroyed mutex and access the freed dp structure?
Should we use devm_add_action_or_reset() to ensure the work is cancelled
during physical device unbind?
> init_completion(&dp->complete);
[Severity: High]
This isn't a bug introduced by this patch, but is it possible for DP AUX
transfers to prematurely complete due to a missing reinit_completion()?
If dw_dp_aux_transfer() times out, but the hardware eventually signals the
interrupt later, dw_dp_irq() calls complete(&dp->complete).
Because dw_dp_aux_transfer() fails to call reinit_completion() before starting
the next transfer, will the subsequent call to wait_for_completion_timeout()
return immediately and incorrectly read the status registers?
>
> + ret = devm_mutex_init(dev, &dp->irq_lock);
> + if (ret)
> + return ERR_PTR(ret);
> +
> res = devm_platform_ioremap_resource(pdev, 0);
[Severity: High]
This is a pre-existing issue, but do the atomic enable and disable callbacks
execute sleeping functions?
The DRM bridge's atomic disable callback (dw_dp_bridge_atomic_disable) is
reached from the atomic commit tail, but it invokes dw_dp_reset(), which
uses blocking functions:
drivers/gpu/drm/bridge/synopsys/dw-dp.c:dw_dp_reset() {
...
disable_irq(dp->irq);
...
usleep_range(10, 20);
...
regmap_read_poll_timeout(...);
...
}
Similarly, dw_dp_bridge_atomic_enable() reaches dw_dp_link_train_fast()
which calls usleep_range(). Since functions reached from
drm_atomic_helper_commit_tail() run in atomic context, will this cause
scheduling-while-atomic bugs or kernel warnings?
[Severity: High]
This is a pre-existing issue, but is there a risk of out-of-bounds reads and
writes during link training due to an unbounded lane count?
In dw_dp_link_parse(), link->lanes is determined by reading the capability
from the DP sink:
link->lanes = min_t(u8, phy_get_bus_width(dp->phy),
drm_dp_max_lane_count(link->dpcd));
If the PHY driver returns a bus width greater than 4, and the untrusted DPCD
reports more than 4 lanes, link->lanes will exceed 4.
The link training functions then iterate up to link->lanes:
drivers/gpu/drm/bridge/synopsys/dw-dp.c:dw_dp_link_train_update_vs_emph() {
...
for (i = 0; i < lanes; i++) {
phy_cfg.dp.voltage[i] = vs[i];
phy_cfg.dp.pre[i] = pe[i];
}
...
}
Will this cause out-of-bounds writes to arrays like phy_cfg.dp.voltage and
phy_cfg.dp.pre (which are sized for 4 elements) when a non-compliant or
malicious DP sink is connected?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260806-synopsys-dw-dp-improvements-v11-0-0d508505f383@collabora.com?part=5
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.