summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--shared-core/radeon_state.c12
-rw-r--r--shared/radeon_state.c12
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);
}