Commit d8af20bcae25e8792ccd8c94404e6e57e7db75f2
Exists in
master
and in
13 other branches
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, |