From e017a62d01aa6c7d0253b15182669295f000fa03 Mon Sep 17 00:00:00 2001 From: Gary King Date: Fri, 5 Mar 2010 10:41:32 -0800 Subject: [nvmap] handle NULL return for pin multiple, fix infinite loop the handle alignment parameter query had an off-by-one bug in its loop initializer which caused any carveout handle to trigger an infinite loop. the only caller of this API was the debug EGL driver, which used it to verify that the allocation matched the requested alignment. also, if the user passes NULL as the address array when pinning multiple handles to ioctl_pinop, pin the handles and skip the output write, rather than returning a permission error. big thanks to antti for finding the infinite loop. bug 660526 Change-Id: I90f819a231b5a8bef5b473252122cdbefc744efb Reviewed-on: http://git-master/r/782 Reviewed-by: Gary King Tested-by: Gary King --- drivers/char/nvmap.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/char/nvmap.c b/drivers/char/nvmap.c index 8546061016b6..c7f1cc44c5b6 100644 --- a/drivers/char/nvmap.c +++ b/drivers/char/nvmap.c @@ -1630,7 +1630,8 @@ static int nvmap_ioctl_pinop(struct file *filp, size_t bytes = op.count * sizeof(unsigned long *); if (!access_ok(VERIFY_READ, (void *)op.handles, bytes)) return -EPERM; - if (is_pin && !access_ok(VERIFY_WRITE, (void *)op.addr, bytes)) + if (is_pin && op.addr && + !access_ok(VERIFY_WRITE, (void *)op.addr, bytes)) return -EPERM; if (op.count <= ARRAY_SIZE(on_stack)) refs = on_stack; @@ -1662,6 +1663,8 @@ static int nvmap_ioctl_pinop(struct file *filp, output = (unsigned long __user *)&(tmp->addr); } + if (!output) goto out; + for (i=0; iorig_size; else if (param==NVMEM_HANDLE_PARAM_ALIGNMENT) { - unsigned int i = 0; - if (!h->alloc) return 0; if (h->heap_pgalloc) return PAGE_SIZE; else { + unsigned int i=1; + if (!h->carveout.base) return SZ_4M; while (!(i & h->carveout.base)) i<<=1; + return i; } - return i; } else if (param==NVMEM_HANDLE_PARAM_BASE) { WARN_ON(!h->alloc || !atomic_read(&h->pin)); -- cgit v1.2.3