Merge branch 'vmwgfx-fixes-4.15' of git://people.freedesktop.org/~thomash/linux into drm-fixes
Two important fixes for vmwgfx. The off-by-one fix could cause a malicious user to potentially crash the kernel. The framebuffer map cache fix can under some circumstances enable a user to read from or write to freed pages. * 'vmwgfx-fixes-4.15' of git://people.freedesktop.org/~thomash/linux: drm/vmwgfx: Potential off by one in vmw_view_add() drm/vmwgfx: Don't cache framebuffer maps
This commit is contained in:
commit
477d70b673
4 changed files with 15 additions and 36 deletions
|
@ -2731,6 +2731,8 @@ static int vmw_cmd_dx_view_define(struct vmw_private *dev_priv,
|
|||
}
|
||||
|
||||
view_type = vmw_view_cmd_to_type(header->id);
|
||||
if (view_type == vmw_view_max)
|
||||
return -EINVAL;
|
||||
cmd = container_of(header, typeof(*cmd), header);
|
||||
ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
|
||||
user_surface_converter,
|
||||
|
|
|
@ -697,7 +697,6 @@ vmw_du_plane_duplicate_state(struct drm_plane *plane)
|
|||
vps->pinned = 0;
|
||||
|
||||
/* Mapping is managed by prepare_fb/cleanup_fb */
|
||||
memset(&vps->guest_map, 0, sizeof(vps->guest_map));
|
||||
memset(&vps->host_map, 0, sizeof(vps->host_map));
|
||||
vps->cpp = 0;
|
||||
|
||||
|
@ -760,11 +759,6 @@ vmw_du_plane_destroy_state(struct drm_plane *plane,
|
|||
|
||||
|
||||
/* Should have been freed by cleanup_fb */
|
||||
if (vps->guest_map.virtual) {
|
||||
DRM_ERROR("Guest mapping not freed\n");
|
||||
ttm_bo_kunmap(&vps->guest_map);
|
||||
}
|
||||
|
||||
if (vps->host_map.virtual) {
|
||||
DRM_ERROR("Host mapping not freed\n");
|
||||
ttm_bo_kunmap(&vps->host_map);
|
||||
|
|
|
@ -175,7 +175,7 @@ struct vmw_plane_state {
|
|||
int pinned;
|
||||
|
||||
/* For CPU Blit */
|
||||
struct ttm_bo_kmap_obj host_map, guest_map;
|
||||
struct ttm_bo_kmap_obj host_map;
|
||||
unsigned int cpp;
|
||||
};
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ struct vmw_screen_target_display_unit {
|
|||
bool defined;
|
||||
|
||||
/* For CPU Blit */
|
||||
struct ttm_bo_kmap_obj host_map, guest_map;
|
||||
struct ttm_bo_kmap_obj host_map;
|
||||
unsigned int cpp;
|
||||
};
|
||||
|
||||
|
@ -695,7 +695,8 @@ static void vmw_stdu_dmabuf_cpu_commit(struct vmw_kms_dirty *dirty)
|
|||
s32 src_pitch, dst_pitch;
|
||||
u8 *src, *dst;
|
||||
bool not_used;
|
||||
|
||||
struct ttm_bo_kmap_obj guest_map;
|
||||
int ret;
|
||||
|
||||
if (!dirty->num_hits)
|
||||
return;
|
||||
|
@ -706,6 +707,13 @@ static void vmw_stdu_dmabuf_cpu_commit(struct vmw_kms_dirty *dirty)
|
|||
if (width == 0 || height == 0)
|
||||
return;
|
||||
|
||||
ret = ttm_bo_kmap(&ddirty->buf->base, 0, ddirty->buf->base.num_pages,
|
||||
&guest_map);
|
||||
if (ret) {
|
||||
DRM_ERROR("Failed mapping framebuffer for blit: %d\n",
|
||||
ret);
|
||||
goto out_cleanup;
|
||||
}
|
||||
|
||||
/* Assume we are blitting from Host (display_srf) to Guest (dmabuf) */
|
||||
src_pitch = stdu->display_srf->base_size.width * stdu->cpp;
|
||||
|
@ -713,7 +721,7 @@ static void vmw_stdu_dmabuf_cpu_commit(struct vmw_kms_dirty *dirty)
|
|||
src += ddirty->top * src_pitch + ddirty->left * stdu->cpp;
|
||||
|
||||
dst_pitch = ddirty->pitch;
|
||||
dst = ttm_kmap_obj_virtual(&stdu->guest_map, ¬_used);
|
||||
dst = ttm_kmap_obj_virtual(&guest_map, ¬_used);
|
||||
dst += ddirty->fb_top * dst_pitch + ddirty->fb_left * stdu->cpp;
|
||||
|
||||
|
||||
|
@ -772,6 +780,7 @@ static void vmw_stdu_dmabuf_cpu_commit(struct vmw_kms_dirty *dirty)
|
|||
vmw_fifo_commit(dev_priv, sizeof(*cmd));
|
||||
}
|
||||
|
||||
ttm_bo_kunmap(&guest_map);
|
||||
out_cleanup:
|
||||
ddirty->left = ddirty->top = ddirty->fb_left = ddirty->fb_top = S32_MAX;
|
||||
ddirty->right = ddirty->bottom = S32_MIN;
|
||||
|
@ -1109,9 +1118,6 @@ vmw_stdu_primary_plane_cleanup_fb(struct drm_plane *plane,
|
|||
{
|
||||
struct vmw_plane_state *vps = vmw_plane_state_to_vps(old_state);
|
||||
|
||||
if (vps->guest_map.virtual)
|
||||
ttm_bo_kunmap(&vps->guest_map);
|
||||
|
||||
if (vps->host_map.virtual)
|
||||
ttm_bo_kunmap(&vps->host_map);
|
||||
|
||||
|
@ -1277,33 +1283,11 @@ vmw_stdu_primary_plane_prepare_fb(struct drm_plane *plane,
|
|||
*/
|
||||
if (vps->content_fb_type == SEPARATE_DMA &&
|
||||
!(dev_priv->capabilities & SVGA_CAP_3D)) {
|
||||
|
||||
struct vmw_framebuffer_dmabuf *new_vfbd;
|
||||
|
||||
new_vfbd = vmw_framebuffer_to_vfbd(new_fb);
|
||||
|
||||
ret = ttm_bo_reserve(&new_vfbd->buffer->base, false, false,
|
||||
NULL);
|
||||
if (ret)
|
||||
goto out_srf_unpin;
|
||||
|
||||
ret = ttm_bo_kmap(&new_vfbd->buffer->base, 0,
|
||||
new_vfbd->buffer->base.num_pages,
|
||||
&vps->guest_map);
|
||||
|
||||
ttm_bo_unreserve(&new_vfbd->buffer->base);
|
||||
|
||||
if (ret) {
|
||||
DRM_ERROR("Failed to map content buffer to CPU\n");
|
||||
goto out_srf_unpin;
|
||||
}
|
||||
|
||||
ret = ttm_bo_kmap(&vps->surf->res.backup->base, 0,
|
||||
vps->surf->res.backup->base.num_pages,
|
||||
&vps->host_map);
|
||||
if (ret) {
|
||||
DRM_ERROR("Failed to map display buffer to CPU\n");
|
||||
ttm_bo_kunmap(&vps->guest_map);
|
||||
goto out_srf_unpin;
|
||||
}
|
||||
|
||||
|
@ -1350,7 +1334,6 @@ vmw_stdu_primary_plane_atomic_update(struct drm_plane *plane,
|
|||
stdu->display_srf = vps->surf;
|
||||
stdu->content_fb_type = vps->content_fb_type;
|
||||
stdu->cpp = vps->cpp;
|
||||
memcpy(&stdu->guest_map, &vps->guest_map, sizeof(vps->guest_map));
|
||||
memcpy(&stdu->host_map, &vps->host_map, sizeof(vps->host_map));
|
||||
|
||||
if (!stdu->defined)
|
||||
|
|
Loading…
Add table
Reference in a new issue