summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuus Sliepen <gsliepen@google.com>2023-06-20 14:40:40 +0000
committerGuus Sliepen <gsliepen@google.com>2023-08-15 15:48:50 +0000
commitc8ee87ed1c1d1f0c520efdc2a9accae24862154f (patch)
tree6df6151d3e3c5d273744565f708f9bb598d618e5
parentc2fe926ba4157aba58d7b0bd1686b4bfe852146b (diff)
downloadgchips-c8ee87ed1c1d1f0c520efdc2a9accae24862154f.tar.gz
gralloc4: Only free allocated handles in error path
If we encounter an error while allocating handles, some error paths could end up trying to freeing more handles that we allocated so far. Also add some extra checks and logging in mali_grallic_ion_allocate() to catch incorrect calls to this function, and ensure the array of filedescriptors in handles is initialized. Bug: 241512108 Test: v2/android-platinum/health/unit/camera Change-Id: Idd2b09ed11424b110d485e10656771aafe0b20a9
-rw-r--r--gralloc4/src/allocator/mali_gralloc_ion.cpp76
-rw-r--r--gralloc4/src/mali_gralloc_buffer.h2
2 files changed, 39 insertions, 39 deletions
diff --git a/gralloc4/src/allocator/mali_gralloc_ion.cpp b/gralloc4/src/allocator/mali_gralloc_ion.cpp
index da9aba5..2d63a70 100644
--- a/gralloc4/src/allocator/mali_gralloc_ion.cpp
+++ b/gralloc4/src/allocator/mali_gralloc_ion.cpp
@@ -48,6 +48,7 @@
#include "mali_gralloc_ion.h"
#include <array>
+#include <cassert>
#include <string>
static const char kDmabufSensorDirectHeapName[] = "sensor_direct_heap";
@@ -369,61 +370,57 @@ int mali_gralloc_ion_allocate(const gralloc_buffer_descriptor_t *descriptors,
unsigned int priv_heap_flag = 0;
uint64_t usage;
uint32_t i;
- int fds[MAX_FDS];
- std::fill(fds, fds + MAX_FDS, -1);
for (i = 0; i < numDescriptors; i++)
{
- buffer_descriptor_t *bufDescriptor = (buffer_descriptor_t *)(descriptors[i]);
- usage = bufDescriptor->consumer_usage | bufDescriptor->producer_usage;
-
- for (int fidx = 0; fidx < bufDescriptor->fd_count; fidx++)
- {
- if (ion_fd >= 0 && fidx == 0) {
- fds[fidx] = ion_fd;
- } else {
- fds[fidx] = alloc_from_dmabuf_heap(usage, bufDescriptor->alloc_sizes[fidx], bufDescriptor->name);
- }
- if (fds[fidx] < 0)
- {
- MALI_GRALLOC_LOGE("ion_alloc failed");
-
- for (int cidx = 0; cidx < fidx; cidx++)
- {
- close(fds[cidx]);
- }
-
- /* need to free already allocated memory. not just this one */
- mali_gralloc_ion_free_internal(pHandle, numDescriptors);
-
- return -1;
- }
- }
+ buffer_descriptor_t *bufDescriptor = reinterpret_cast<buffer_descriptor_t *>(descriptors[i]);
+ assert(bufDescriptor);
+ assert(bufDescriptor->fd_count >= 0);
+ assert(bufDescriptor->fd_count <= MAX_FDS);
- private_handle_t *hnd = new private_handle_t(
+ auto hnd = new private_handle_t(
priv_heap_flag,
bufDescriptor->alloc_sizes,
bufDescriptor->consumer_usage, bufDescriptor->producer_usage,
- fds, bufDescriptor->fd_count,
+ nullptr, bufDescriptor->fd_count,
bufDescriptor->hal_format, bufDescriptor->alloc_format,
bufDescriptor->width, bufDescriptor->height, bufDescriptor->pixel_stride,
bufDescriptor->layer_count, bufDescriptor->plane_info);
- if (NULL == hnd)
+ /* Reset the number of valid filedescriptors, we will increment
+ * it each time a valid fd is added, so we can rely on the
+ * cleanup functions to close open fds. */
+ hnd->set_numfds(0);
+
+ if (nullptr == hnd)
{
MALI_GRALLOC_LOGE("Private handle could not be created for descriptor:%d in non-shared usecase", i);
+ mali_gralloc_ion_free_internal(pHandle, i);
+ return -1;
+ }
+
+ pHandle[i] = hnd;
+ usage = bufDescriptor->consumer_usage | bufDescriptor->producer_usage;
+
+ for (uint32_t fidx = 0; fidx < bufDescriptor->fd_count; fidx++)
+ {
+ int& fd = hnd->fds[fidx];
- /* Close the obtained shared file descriptor for the current handle */
- for (int j = 0; j < bufDescriptor->fd_count; j++)
+ if (ion_fd >= 0 && fidx == 0) {
+ fd = ion_fd;
+ } else {
+ fd = alloc_from_dmabuf_heap(usage, bufDescriptor->alloc_sizes[fidx], bufDescriptor->name);
+ }
+
+ if (fd < 0)
{
- close(fds[j]);
+ MALI_GRALLOC_LOGE("ion_alloc failed for fds[%u] = %d", fidx, fd);
+ mali_gralloc_ion_free_internal(pHandle, i + 1);
+ return -1;
}
- mali_gralloc_ion_free_internal(pHandle, numDescriptors);
- return -1;
+ hnd->incr_numfds(1);
}
-
- pHandle[i] = hnd;
}
#if defined(GRALLOC_INIT_AFBC) && (GRALLOC_INIT_AFBC == 1)
@@ -431,8 +428,8 @@ int mali_gralloc_ion_allocate(const gralloc_buffer_descriptor_t *descriptors,
unsigned char *cpu_ptr = NULL;
for (i = 0; i < numDescriptors; i++)
{
- buffer_descriptor_t *bufDescriptor = (buffer_descriptor_t *)(descriptors[i]);
- private_handle_t *hnd = (private_handle_t *)(pHandle[i]);
+ buffer_descriptor_t *bufDescriptor = reinterpret_cast<buffer_descriptor_t *>(descriptors[i]);
+ const private_handle_t *hnd = static_cast<const private_handle_t *>(pHandle[i]);
usage = bufDescriptor->consumer_usage | bufDescriptor->producer_usage;
@@ -459,6 +456,7 @@ int mali_gralloc_ion_allocate(const gralloc_buffer_descriptor_t *descriptors,
ATRACE_NAME("data init");
/* For separated plane YUV, there is a header to initialise per plane. */
const plane_info_t *plane_info = bufDescriptor->plane_info;
+ assert(plane_info);
const bool is_multi_plane = hnd->is_multi_plane();
for (int i = 0; i < MAX_PLANES && (i == 0 || plane_info[i].byte_stride != 0); i++)
{
diff --git a/gralloc4/src/mali_gralloc_buffer.h b/gralloc4/src/mali_gralloc_buffer.h
index 9cc7920..c4db9fc 100644
--- a/gralloc4/src/mali_gralloc_buffer.h
+++ b/gralloc4/src/mali_gralloc_buffer.h
@@ -286,6 +286,8 @@ struct private_handle_t
if (_fds)
memcpy(fds, _fds, sizeof(fds));
+ else
+ memset(fds, -1, sizeof(fds));
if (_alloc_sizes)
memcpy(alloc_sizes, _alloc_sizes, sizeof(alloc_sizes));