Commit cbd75e97a525e3819c02dc18bc2d67aa544c9e45

Authored by Thomas Hellstrom
1 parent abaafc0af9

drm/vmwgfx: Make sure user-space can't DMA across buffer object boundaries v2

We already check that the buffer object we're accessing is registered with
the file. Now also make sure that we can't DMA across buffer object boundaries.

v2: Code commenting update.

Cc: stable@vger.kernel.org
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Jakob Bornecrantz <jakob@vmware.com>

Showing 1 changed file with 22 additions and 0 deletions Side-by-side Diff

drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
... ... @@ -1214,13 +1214,35 @@
1214 1214 SVGA3dCmdSurfaceDMA dma;
1215 1215 } *cmd;
1216 1216 int ret;
  1217 + SVGA3dCmdSurfaceDMASuffix *suffix;
  1218 + uint32_t bo_size;
1217 1219  
1218 1220 cmd = container_of(header, struct vmw_dma_cmd, header);
  1221 + suffix = (SVGA3dCmdSurfaceDMASuffix *)((unsigned long) &cmd->dma +
  1222 + header->size - sizeof(*suffix));
  1223 +
  1224 + /* Make sure device and verifier stays in sync. */
  1225 + if (unlikely(suffix->suffixSize != sizeof(*suffix))) {
  1226 + DRM_ERROR("Invalid DMA suffix size.\n");
  1227 + return -EINVAL;
  1228 + }
  1229 +
1219 1230 ret = vmw_translate_guest_ptr(dev_priv, sw_context,
1220 1231 &cmd->dma.guest.ptr,
1221 1232 &vmw_bo);
1222 1233 if (unlikely(ret != 0))
1223 1234 return ret;
  1235 +
  1236 + /* Make sure DMA doesn't cross BO boundaries. */
  1237 + bo_size = vmw_bo->base.num_pages * PAGE_SIZE;
  1238 + if (unlikely(cmd->dma.guest.ptr.offset > bo_size)) {
  1239 + DRM_ERROR("Invalid DMA offset.\n");
  1240 + return -EINVAL;
  1241 + }
  1242 +
  1243 + bo_size -= cmd->dma.guest.ptr.offset;
  1244 + if (unlikely(suffix->maximumOffset > bo_size))
  1245 + suffix->maximumOffset = bo_size;
1224 1246  
1225 1247 ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
1226 1248 user_surface_converter, &cmd->dma.host.sid,