qxl_alloc_release_reserved() receives a requested size from its callers
but never validates it against the actual sub-allocation slot size.
Drawable releases use 256-byte slots (RELEASE_SIZE), yet
qxl_process_single_command() allows command_size up to
PAGE_SIZE - sizeof(union qxl_release_info), approximately 4088 bytes.

The command payload is then copied from userspace via
copy_from_user_inatomic_nontemporal() into the 256-byte slot, causing a
heap buffer overflow that corrupts adjacent release slots in the same
page and can overwrite the neighbouring release_info headers.

Add a check in qxl_alloc_release_reserved() to reject allocations where
the requested size exceeds the slot size for the given release type.

Fixes: f64122c1f6ad ("drm: add qxl driver.")
Cc: [email protected]
Signed-off-by: Aldo Ariel Panzardo <[email protected]>
---
 drivers/gpu/drm/qxl/qxl_release.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/qxl/qxl_release.c 
b/drivers/gpu/drm/qxl/qxl_release.c
index 06979d0e8..049ad167f 100644
--- a/drivers/gpu/drm/qxl/qxl_release.c
+++ b/drivers/gpu/drm/qxl/qxl_release.c
@@ -312,6 +312,9 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, 
unsigned long size,
                return -EINVAL;
        }
 
+       if (size > release_size_per_bo[cur_idx])
+               return -EINVAL;
+
        idr_ret = qxl_release_alloc(qdev, type, release);
        if (idr_ret < 0) {
                if (rbo)
-- 
2.43.0

Reply via email to