Commit d8af20bcae25e8792ccd8c94404e6e57e7db75f2

Authored by Dave Airlie

Merge branch 'vmwgfx-fixes-3.15' of git://people.freedesktop.org/~thomash/linux into drm-next

single security fix, cc'd stable.

* 'vmwgfx-fixes-3.15' of git://people.freedesktop.org/~thomash/linux:
  drm/vmwgfx: Make sure user-space can't DMA across buffer object boundaries v2

Showing 1 changed file 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,