mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 12:44:03 +02:00
drm/amd/display: clamp DMUB AUX reply length to payload buffer
[Why]
amdgpu_dm_process_dmub_aux_transfer_sync() copies p_notify->aux_reply.length
bytes into payload->data without clamping. payload->data is typically a 16-byte
DPCD scratch buffer, while aux_reply.length is echoed from the sink via the DMUB
ring. While this is clamped by DMUB it's prudent to ensure we validate
this in the driver as well.
[How]
Clamp the copy to sizeof(aux_reply.data), the scratch buffer the reply was read
into, and use that for both the memcpy and the return value. For regular
transfers additionally clamp to payload->length to cover callers whose
destination buffer is smaller than 16 bytes. The write-status-update retry path
(dce_aux_transfer_with_retries) deliberately zeroes payload->length while still
expecting the partial-write status byte, so that bound is skipped in that case
to avoid dropping the reply. Also guard against a NULL payload->data.
Fixes: 81927e2808 ("drm/amd/display: Support for DMUB AUX")
Assisted-by: Copilot:claude-opus-4.8
Reviewed-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: George Zhang <george.zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
f3403ab74a
commit
8cbe3648aa
|
|
@ -797,12 +797,26 @@ int amdgpu_dm_process_dmub_aux_transfer_sync(
|
||||||
payload->reply[0] = (adev->dm.dmub_notify->aux_reply.command >> 4) & 0xF;
|
payload->reply[0] = (adev->dm.dmub_notify->aux_reply.command >> 4) & 0xF;
|
||||||
|
|
||||||
/*write req may receive a byte indicating partially written number as well*/
|
/*write req may receive a byte indicating partially written number as well*/
|
||||||
if (p_notify->aux_reply.length)
|
if (p_notify->aux_reply.length && payload->data) {
|
||||||
memcpy(payload->data, p_notify->aux_reply.data,
|
/* Bound the reply to the scratch buffer it was read into. */
|
||||||
p_notify->aux_reply.length);
|
ret = min((uint32_t)p_notify->aux_reply.length,
|
||||||
|
(uint32_t)sizeof(p_notify->aux_reply.data));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* During a write-status-update retry the caller zeroes
|
||||||
|
* payload->length while still expecting the partial-write
|
||||||
|
* status byte in payload->data (see dce_aux_transfer_with_retries),
|
||||||
|
* so only clamp to payload->length for regular transfers.
|
||||||
|
*/
|
||||||
|
if (!payload->write_status_update)
|
||||||
|
ret = min(ret, payload->length);
|
||||||
|
|
||||||
|
memcpy(payload->data, p_notify->aux_reply.data, ret);
|
||||||
|
} else {
|
||||||
|
/* success */
|
||||||
|
ret = p_notify->aux_reply.length;
|
||||||
|
}
|
||||||
|
|
||||||
/* success */
|
|
||||||
ret = p_notify->aux_reply.length;
|
|
||||||
*operation_result = p_notify->result;
|
*operation_result = p_notify->result;
|
||||||
out:
|
out:
|
||||||
reinit_completion(&adev->dm.dmub_aux_transfer_done);
|
reinit_completion(&adev->dm.dmub_aux_transfer_done);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user