summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@linux.ie>2004-07-31 07:26:52 +0000
committerDave Airlie <airlied@linux.ie>2004-07-31 07:26:52 +0000
commiteb3d0635d4830969d10d5fe8aef17cebb2f3fd15 (patch)
treed48d455b9c8d04aa8b8a76992c2449a4208e64f8
parentdc4508c33845602e4c94c3e125536d01fe9110b1 (diff)
fixes for using userspace pointers found by sparse utility
From: Dave Airlie
-rw-r--r--linux/gamma_old_dma.h62
-rw-r--r--shared-core/i915_dma.c2
-rw-r--r--shared-core/i915_mem.c4
-rw-r--r--shared/i915_dma.c2
-rw-r--r--shared/i915_mem.c4
5 files changed, 52 insertions, 22 deletions
diff --git a/linux/gamma_old_dma.h b/linux/gamma_old_dma.h
index 43be5c80..54bc11f9 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 e7364ffe..28820378 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 2a2379d0..40098514 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 e7364ffe..28820378 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 2a2379d0..40098514 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;
}
}