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);  			} | 
