vmw_cmd_res_switch_backup lets userspace bind an arbitrary MOB to a resource without checking that the MOB is large enough for the resource's guest_memory_size. The dirty-tracking bitmap is allocated based on the MOB size, but later accessed using the (larger) surface size, causing an out-of-bounds write in the bitmap that corrupts adjacent slab memory.
Add a check that backup_offset + res->guest_memory_size does not exceed
the buffer size before allowing the backup switch.
Fixes: a97e21923b42 ("drm/vmwgfx: Hook up guest-backed surfaces")
Cc: [email protected]
Reported-by: Zero Day Initiative <[email protected]>
Reported-by: [email protected] # ZDI-CAN-34068
Closes:
https://lore.kernel.org/all/byapr01mb38301cfc012e873340f77e3d80...@byapr01mb3830.prod.exchangelabs.com/
---
drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
index a9136a6523cb..0156aee84c9f 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
@@ -1718,6 +1718,7 @@ static int vmw_cmd_res_switch_backup(struct vmw_private
*dev_priv,
{
struct vmw_bo *vbo;
void *info;
+ u64 end;
int ret;
info = vmw_execbuf_info_from_res(sw_context, res);
@@ -1728,6 +1729,13 @@ static int vmw_cmd_res_switch_backup(struct vmw_private
*dev_priv,
if (ret)
return ret;
+ if (check_add_overflow((u64)backup_offset,
+ (u64)res->guest_memory_size, &end) ||
+ end > vbo->tbo.base.size) {
+ VMW_DEBUG_USER("Backup buffer too small for resource.\n");
+ return -EINVAL;
+ }
+
vmw_validation_res_switch_backup(sw_context->ctx, info, vbo,
backup_offset);
return 0;
--
2.53.0
smime.p7s
Description: S/MIME Cryptographic Signature
