mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
drm/amdgpu: Fix CPER ring debugfs read buffer overflow risk
The CPER ring debugfs read code always writes a 12-byte header when the
file is read for the first time (*offset == 0):
copy_to_user(buf, ring_header, 12);
But the code never checks whether the user buffer (@size) is at least
12 bytes long. After writing the 12-byte header, the code then gives the
full original @size to the CPER payload handler:
record_req->buf_size = size;
This means the function can write:
12 bytes (header) + payload bytes (up to @size)
into a buffer that is only @size bytes big. In other words, the kernel
may write more data than the user asked for. This can overflow the user
buffer.
The fix is:
- If the user buffer is smaller than 12 bytes on the first read,
return -EINVAL instead of copying the header.
- After writing the 12-byte header, subtract 12 from @size and pass
the reduced size to record_req->buf_size. This ensures the CPER
payload only uses the remaining free space in the buffer.
Reads after the first one (*offset != 0) do not write the header, so
their behavior stays exactly the same. The only user-visible change is
that tiny buffers now fail safely instead of risking an overflow.
Fixes:
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c:523
amdgpu_ras_cper_debugfs_read()
warn: userbuf overflow? is 'ring_header_size' <= 'size'
Fixes: 527e3d4033 ("drm/amd/ras: Add CPER ring read for uniras")
Reported by: Dan Carpenter <dan.carpenter@linaro.org>
Cc: Xiang Liu <xiang.liu@amd.com>
Cc: Tao Zhou <tao.zhou1@amd.com>
Cc: Yang Wang <kevinyang.wang@amd.com>
Cc: Christian König <christian.koenig@amd.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
Reviewed-by: Tao Zhou <tao.zhou1@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
committed by
Alex Deucher
parent
f3854e04b7
commit
93c19634f7
@@ -520,9 +520,14 @@ static ssize_t amdgpu_ras_cper_debugfs_read(struct file *f, char __user *buf,
|
||||
return -ENOMEM;
|
||||
|
||||
if (!(*offset)) {
|
||||
/* Need at least 12 bytes for the header on the first read */
|
||||
if (size < ring_header_size)
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_to_user(buf, ring_header, ring_header_size))
|
||||
return -EFAULT;
|
||||
buf += ring_header_size;
|
||||
size -= ring_header_size;
|
||||
}
|
||||
|
||||
r = amdgpu_ras_mgr_handle_ras_cmd(ring->adev,
|
||||
|
||||
Reference in New Issue
Block a user