diff options
author | Liam Mark <lmark@codeaurora.org> | 2018-09-06 16:15:41 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2018-10-10 00:01:08 -0700 |
commit | e8d9006612136f93811638c267d8375c55a88437 (patch) | |
tree | 69c22adf32c781e4ef31121cd5246a8a0eec19e9 | |
parent | cad6fc7c91ec8ad5ee87198ec059b9eceb6c0922 (diff) |
ion: Ensure non-HLOS memory cannot be mapped by CPU
Currently it is possible for an ION client to allocate non-HLOS memory
(ie memory which isn't assigned to the HLOS vmid), map this memory, and
then attempt to access this memory from the CPU.
Attempting to access non-HLOS memory from the CPU will cause a
stage-2 fault.
Fix ION so that non-HLOS memory cannot be mapped by the CPU.
Change-Id: Ifb51de2eabc076cddc744c13f01ef97b4a7c6874
Signed-off-by: Liam Mark <lmark@codeaurora.org>
-rw-r--r-- | drivers/staging/android/ion/ion_cma_heap.c | 29 | ||||
-rw-r--r-- | drivers/staging/android/ion/ion_system_heap.c | 12 | ||||
-rw-r--r-- | drivers/staging/android/ion/ion_system_secure_heap.c | 10 |
3 files changed, 44 insertions, 7 deletions
diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c index d991b024eda9d..831c334d7216f 100644 --- a/drivers/staging/android/ion/ion_cma_heap.c +++ b/drivers/staging/android/ion/ion_cma_heap.c @@ -4,7 +4,7 @@ * Copyright (C) Linaro 2012 * Author: <benjamin.gaignard@linaro.org> for ST-Ericsson. * - * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -386,14 +386,37 @@ out: return ret; } +static void *ion_secure_cma_map_kernel(struct ion_heap *heap, + struct ion_buffer *buffer) +{ + if (!is_buffer_hlos_assigned(buffer)) { + pr_info("%s: Mapping non-HLOS accessible buffer disallowed\n", + __func__); + return NULL; + } + return ion_cma_map_kernel(heap, buffer); +} + +static int ion_secure_cma_map_user(struct ion_heap *mapper, + struct ion_buffer *buffer, + struct vm_area_struct *vma) +{ + if (!is_buffer_hlos_assigned(buffer)) { + pr_info("%s: Mapping non-HLOS accessible buffer disallowed\n", + __func__); + return -EINVAL; + } + return ion_cma_mmap(mapper, buffer, vma); +} + static struct ion_heap_ops ion_secure_cma_ops = { .allocate = ion_secure_cma_allocate, .free = ion_secure_cma_free, .map_dma = ion_cma_heap_map_dma, .unmap_dma = ion_cma_heap_unmap_dma, .phys = ion_cma_phys, - .map_user = ion_cma_mmap, - .map_kernel = ion_cma_map_kernel, + .map_user = ion_secure_cma_map_user, + .map_kernel = ion_secure_cma_map_kernel, .unmap_kernel = ion_cma_unmap_kernel, .print_debug = ion_cma_print_debug, }; diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c index 3b2725237a257..f05471d3f4aa3 100644 --- a/drivers/staging/android/ion/ion_system_heap.c +++ b/drivers/staging/android/ion/ion_system_heap.c @@ -102,6 +102,11 @@ size_t ion_system_heap_secure_page_pool_total(struct ion_heap *heap, return total << PAGE_SHIFT; } +static int ion_heap_is_system_heap_type(enum ion_heap_type type) +{ + return type == ((enum ion_heap_type)ION_HEAP_TYPE_SYSTEM); +} + static struct page *alloc_buffer_page(struct ion_system_heap *heap, struct ion_buffer *buffer, unsigned long order, @@ -357,6 +362,13 @@ static int ion_system_heap_allocate(struct ion_heap *heap, int vmid = get_secure_vmid(buffer->flags); struct device *dev = heap->priv; + if (ion_heap_is_system_heap_type(buffer->heap->type) && + is_secure_vmid_valid(vmid)) { + pr_info("%s: System heap doesn't support secure allocations\n", + __func__); + return -EINVAL; + } + if (align > PAGE_SIZE) return -EINVAL; diff --git a/drivers/staging/android/ion/ion_system_secure_heap.c b/drivers/staging/android/ion/ion_system_secure_heap.c index 5bf484beed962..cf86ea21838a5 100644 --- a/drivers/staging/android/ion/ion_system_secure_heap.c +++ b/drivers/staging/android/ion/ion_system_secure_heap.c @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2016,2018 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -171,14 +171,15 @@ out: sys_heap->ops->free(&buffer); } -static void process_one_shrink(struct ion_heap *sys_heap, +static void process_one_shrink(struct ion_system_secure_heap *secure_heap, + struct ion_heap *sys_heap, struct prefetch_info *info) { struct ion_buffer buffer; size_t pool_size, size; int ret; - buffer.heap = sys_heap; + buffer.heap = &secure_heap->heap; buffer.flags = info->vmid; pool_size = ion_system_heap_secure_page_pool_total(sys_heap, @@ -193,6 +194,7 @@ static void process_one_shrink(struct ion_heap *sys_heap, } buffer.private_flags = ION_PRIV_FLAG_SHRINKER_FREE; + buffer.heap = sys_heap; sys_heap->ops->free(&buffer); } @@ -212,7 +214,7 @@ static void ion_system_secure_heap_prefetch_work(struct work_struct *work) spin_unlock_irqrestore(&secure_heap->work_lock, flags); if (info->shrink) - process_one_shrink(sys_heap, info); + process_one_shrink(secure_heap, sys_heap, info); else process_one_prefetch(sys_heap, info); |