mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-09-16 00:59:28 -05: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:
committed by
Alex Deucher
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;
|
||||
|
||||
/*write req may receive a byte indicating partially written number as well*/
|
||||
if (p_notify->aux_reply.length)
|
||||
memcpy(payload->data, p_notify->aux_reply.data,
|
||||
p_notify->aux_reply.length);
|
||||
if (p_notify->aux_reply.length && payload->data) {
|
||||
/* Bound the reply to the scratch buffer it was read into. */
|
||||
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;
|
||||
out:
|
||||
reinit_completion(&adev->dm.dmub_aux_transfer_done);
|
||||
|
||||
Reference in New Issue
Block a user