From eb3d0635d4830969d10d5fe8aef17cebb2f3fd15 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sat, 31 Jul 2004 07:26:52 +0000 Subject: [PATCH] fixes for using userspace pointers found by sparse utility From: Dave Airlie --- linux/gamma_old_dma.h | 62 +++++++++++++++++++++++++++++++++++++------------- shared-core/i915_dma.c | 2 +- shared-core/i915_mem.c | 4 ++-- shared/i915_dma.c | 2 +- shared/i915_mem.c | 4 ++-- 5 files changed, 52 insertions(+), 22 deletions(-) diff --git a/linux/gamma_old_dma.h b/linux/gamma_old_dma.h index 43be5c8..54bc11f 100644 --- a/linux/gamma_old_dma.h +++ b/linux/gamma_old_dma.h @@ -121,7 +121,10 @@ int DRM(dma_enqueue)(struct file *filp, drm_dma_t *d) drm_buf_t *buf; int idx; int while_locked = 0; + int retcode = 0; drm_device_dma_t *dma = dev->dma; + int *send_indices = NULL; + int *send_sizes = NULL; DECLARE_WAITQUEUE(entry, current); DRM_DEBUG("%d\n", d->send_count); @@ -168,45 +171,66 @@ int DRM(dma_enqueue)(struct file *filp, drm_dma_t *d) remove_wait_queue(&q->write_queue, &entry); } + send_indices = DRM(alloc)(d->send_count * sizeof(*send_indices), + DRM_MEM_DRIVER); + if (send_indices == NULL) + return -ENOMEM; + if (copy_from_user(send_indices, d->send_indices, + d->send_count * sizeof(*send_indices))) { + retcode = -EFAULT; + goto cleanup; + } + + send_sizes = DRM(alloc)(d->send_count * sizeof(*send_sizes), + DRM_MEM_DRIVER); + if (send_sizes == NULL) + return -ENOMEM; + if (copy_from_user(send_sizes, d->send_sizes, + d->send_count * sizeof(*send_sizes))) { + retcode = -EFAULT; + goto cleanup; + } + for (i = 0; i < d->send_count; i++) { - idx = d->send_indices[i]; + idx = send_indices[i]; if (idx < 0 || idx >= dma->buf_count) { - atomic_dec(&q->use_count); DRM_ERROR("Index %d (of %d max)\n", - d->send_indices[i], dma->buf_count - 1); - return -EINVAL; + send_indices[i], dma->buf_count - 1); + retcode = -EINVAL; + goto cleanup; } buf = dma->buflist[ idx ]; if (buf->filp != filp) { - atomic_dec(&q->use_count); DRM_ERROR("Process %d using buffer not owned\n", current->pid); - return -EINVAL; + retcode = -EINVAL; + goto cleanup; } if (buf->list != DRM_LIST_NONE) { - atomic_dec(&q->use_count); DRM_ERROR("Process %d using buffer %d on list %d\n", current->pid, buf->idx, buf->list); + retcode = -EINVAL; + goto cleanup; } - buf->used = d->send_sizes[i]; + buf->used = send_sizes[i]; buf->while_locked = while_locked; buf->context = d->context; if (!buf->used) { DRM_ERROR("Queueing 0 length buffer\n"); } if (buf->pending) { - atomic_dec(&q->use_count); DRM_ERROR("Queueing pending buffer:" " buffer %d, offset %d\n", - d->send_indices[i], i); - return -EINVAL; + send_indices[i], i); + retcode = -EINVAL; + goto cleanup; } if (buf->waiting) { - atomic_dec(&q->use_count); DRM_ERROR("Queueing waiting buffer:" " buffer %d, offset %d\n", - d->send_indices[i], i); - return -EINVAL; + send_indices[i], i); + retcode = -EINVAL; + goto cleanup; } buf->waiting = 1; if (atomic_read(&q->use_count) == 1 @@ -217,9 +241,15 @@ int DRM(dma_enqueue)(struct file *filp, drm_dma_t *d) atomic_inc(&q->total_queued); } } +cleanup: + if (send_indices) + DRM(free)(send_indices, d->send_count * sizeof(*send_indices), + DRM_MEM_DRIVER); + if (send_sizes) + DRM(free)(send_sizes, d->send_count * sizeof(*send_sizes), + DRM_MEM_DRIVER); atomic_dec(&q->use_count); - - return 0; + return retcode; } static int DRM(dma_get_buffers_of_order)(struct file *filp, drm_dma_t *d, diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index e7364ff..2882037 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -471,7 +471,7 @@ static int i915_dispatch_batchbuffer(drm_device_t *dev, drm_i915_batchbuffer_t *batch ) { drm_i915_private_t *dev_priv = dev->dev_private; - drm_clip_rect_t *boxes = batch->cliprects; + drm_clip_rect_t __user *boxes = batch->cliprects; int nbox = batch->num_cliprects; int i = 0, count; RING_LOCALS; diff --git a/shared-core/i915_mem.c b/shared-core/i915_mem.c index 2a2379d..4009851 100644 --- a/shared-core/i915_mem.c +++ b/shared-core/i915_mem.c @@ -237,7 +237,7 @@ void i915_mem_takedown( struct mem_block **heap ) } DRM_FREE( *heap, sizeof(**heap) ); - *heap = 0; + *heap = NULL; } @@ -249,7 +249,7 @@ static struct mem_block **get_heap( drm_i915_private_t *dev_priv, case I915_MEM_REGION_AGP: return &dev_priv->agp_heap; default: - return 0; + return NULL; } } diff --git a/shared/i915_dma.c b/shared/i915_dma.c index e7364ff..2882037 100644 --- a/shared/i915_dma.c +++ b/shared/i915_dma.c @@ -471,7 +471,7 @@ static int i915_dispatch_batchbuffer(drm_device_t *dev, drm_i915_batchbuffer_t *batch ) { drm_i915_private_t *dev_priv = dev->dev_private; - drm_clip_rect_t *boxes = batch->cliprects; + drm_clip_rect_t __user *boxes = batch->cliprects; int nbox = batch->num_cliprects; int i = 0, count; RING_LOCALS; diff --git a/shared/i915_mem.c b/shared/i915_mem.c index 2a2379d..4009851 100644 --- a/shared/i915_mem.c +++ b/shared/i915_mem.c @@ -237,7 +237,7 @@ void i915_mem_takedown( struct mem_block **heap ) } DRM_FREE( *heap, sizeof(**heap) ); - *heap = 0; + *heap = NULL; } @@ -249,7 +249,7 @@ static struct mem_block **get_heap( drm_i915_private_t *dev_priv, case I915_MEM_REGION_AGP: return &dev_priv->agp_heap; default: - return 0; + return NULL; } } -- 2.7.4