aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorColin Cross <ccross@android.com>2013-12-19 18:37:49 -0800
committerMitchel Humpherys <mitchelh@codeaurora.org>2013-12-19 21:03:30 -0800
commitc69de844c80884167bb42243b36498dde81eebf6 (patch)
tree0b86c2a873628d25bf6ff6c371a127124de4e0c6 /drivers
parent14f162cb64a8beca59f06cd94d5569bd550dc99d (diff)
downloadlinaro-lsk-c69de844c80884167bb42243b36498dde81eebf6.tar.gz
ion: fix overflow and list bugs in system heap
Fix a few bugs in ion_system_heap: Initialize the list node in the info block. Don't store size_remaining in a signed long, allocating >2GB could overflow, resulting in a call to sg_alloc_table with nents=0 which panics. alloc_largest_available will never return a block larger than size_remanining, so it can never go negative. Limit a single allocation to half of all memory. Prevents a large allocation from taking down the whole system. Change-Id: I7fcbd7e1d5b4d482d7612d80b6c9e8e24466f1d8 Signed-off-by: Colin Cross <ccross@android.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/staging/android/ion/ion_system_heap.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c
index a2c8968104f..a052418d2ef 100644
--- a/drivers/staging/android/ion/ion_system_heap.c
+++ b/drivers/staging/android/ion/ion_system_heap.c
@@ -124,6 +124,7 @@ static struct page_info *alloc_largest_available(struct ion_system_heap *heap,
info->page = page;
info->order = orders[i];
+ INIT_LIST_HEAD(&info->list);
return info;
}
kfree(info);
@@ -145,12 +146,15 @@ static int ion_system_heap_allocate(struct ion_heap *heap,
struct list_head pages;
struct page_info *info, *tmp_info;
int i = 0;
- long size_remaining = PAGE_ALIGN(size);
+ unsigned long size_remaining = PAGE_ALIGN(size);
unsigned int max_order = orders[0];
if (align > PAGE_SIZE)
return -EINVAL;
+ if (size / PAGE_SIZE > totalram_pages / 2)
+ return -ENOMEM;
+
INIT_LIST_HEAD(&pages);
while (size_remaining > 0) {
info = alloc_largest_available(sys_heap, buffer, size_remaining,