diff options
-rw-r--r-- | shared-core/radeon_state.c | 12 | ||||
-rw-r--r-- | shared/radeon_state.c | 12 |
2 files changed, 20 insertions, 4 deletions
diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c index fb821055..1cc6bde8 100644 --- a/shared-core/radeon_state.c +++ b/shared-core/radeon_state.c @@ -1666,7 +1666,8 @@ static int radeon_emit_packet3( drm_device_t *dev, static int radeon_emit_packet3_cliprect( drm_device_t *dev, - drm_radeon_cmd_buffer_t *cmdbuf ) + drm_radeon_cmd_buffer_t *cmdbuf, + int orig_nbox ) { drm_radeon_private_t *dev_priv = dev->dev_private; drm_clip_rect_t box; @@ -1687,6 +1688,9 @@ static int radeon_emit_packet3_cliprect( drm_device_t *dev, cmdsz * 4 > cmdbuf->bufsz) return DRM_ERR(EINVAL); + if (!orig_nbox) + goto out; + do { if ( i < cmdbuf->nbox ) { if (DRM_COPY_FROM_USER_UNCHECKED( &box, &boxes[i], sizeof(box) )) @@ -1715,6 +1719,7 @@ static int radeon_emit_packet3_cliprect( drm_device_t *dev, if (cmdbuf->nbox == 1) cmdbuf->nbox = 0; + out: cmdbuf->buf += cmdsz * 4; cmdbuf->bufsz -= cmdsz * 4; return 0; @@ -1731,6 +1736,7 @@ int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) int idx; drm_radeon_cmd_buffer_t cmdbuf; drm_radeon_cmd_header_t header; + int orig_nbox; LOCK_TEST_WITH_RETURN( dev ); @@ -1755,6 +1761,8 @@ int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) cmdbuf.nbox * sizeof(drm_clip_rect_t))) return DRM_ERR(EFAULT); + orig_nbox = cmdbuf.nbox; + while ( cmdbuf.bufsz >= sizeof(header) ) { if (DRM_GET_USER_UNCHECKED( header.i, (int *)cmdbuf.buf )) { @@ -1812,7 +1820,7 @@ int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) break; case RADEON_CMD_PACKET3_CLIP: - if (radeon_emit_packet3_cliprect( dev, &cmdbuf )) { + if (radeon_emit_packet3_cliprect( dev, &cmdbuf, orig_nbox )) { DRM_ERROR("radeon_emit_packet3_clip failed\n"); return DRM_ERR(EINVAL); } diff --git a/shared/radeon_state.c b/shared/radeon_state.c index fb821055..1cc6bde8 100644 --- a/shared/radeon_state.c +++ b/shared/radeon_state.c @@ -1666,7 +1666,8 @@ static int radeon_emit_packet3( drm_device_t *dev, static int radeon_emit_packet3_cliprect( drm_device_t *dev, - drm_radeon_cmd_buffer_t *cmdbuf ) + drm_radeon_cmd_buffer_t *cmdbuf, + int orig_nbox ) { drm_radeon_private_t *dev_priv = dev->dev_private; drm_clip_rect_t box; @@ -1687,6 +1688,9 @@ static int radeon_emit_packet3_cliprect( drm_device_t *dev, cmdsz * 4 > cmdbuf->bufsz) return DRM_ERR(EINVAL); + if (!orig_nbox) + goto out; + do { if ( i < cmdbuf->nbox ) { if (DRM_COPY_FROM_USER_UNCHECKED( &box, &boxes[i], sizeof(box) )) @@ -1715,6 +1719,7 @@ static int radeon_emit_packet3_cliprect( drm_device_t *dev, if (cmdbuf->nbox == 1) cmdbuf->nbox = 0; + out: cmdbuf->buf += cmdsz * 4; cmdbuf->bufsz -= cmdsz * 4; return 0; @@ -1731,6 +1736,7 @@ int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) int idx; drm_radeon_cmd_buffer_t cmdbuf; drm_radeon_cmd_header_t header; + int orig_nbox; LOCK_TEST_WITH_RETURN( dev ); @@ -1755,6 +1761,8 @@ int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) cmdbuf.nbox * sizeof(drm_clip_rect_t))) return DRM_ERR(EFAULT); + orig_nbox = cmdbuf.nbox; + while ( cmdbuf.bufsz >= sizeof(header) ) { if (DRM_GET_USER_UNCHECKED( header.i, (int *)cmdbuf.buf )) { @@ -1812,7 +1820,7 @@ int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) break; case RADEON_CMD_PACKET3_CLIP: - if (radeon_emit_packet3_cliprect( dev, &cmdbuf )) { + if (radeon_emit_packet3_cliprect( dev, &cmdbuf, orig_nbox )) { DRM_ERROR("radeon_emit_packet3_clip failed\n"); return DRM_ERR(EINVAL); } |