Fix mismatch between isSupported & allocate
isSupported failed to validate usage bits like allocate does,
meaning that isSupported can return true if a vendor is unaware
of a usage bit but then allocate will (correctly!) fail to allocate.
Fix this so that all buffer descriptions go through the same
validation path.
Bug: 216478685
Test: atest HardwareBufferTest#testInvalidUsage
Change-Id: Idc9a0837f555beceb604f27a06e4833f41e97261
diff --git a/libs/ui/Gralloc4.cpp b/libs/ui/Gralloc4.cpp
index 1f8a2f0..e026324 100644
--- a/libs/ui/Gralloc4.cpp
+++ b/libs/ui/Gralloc4.cpp
@@ -92,17 +92,6 @@
outRect.height = rect.height();
return outRect;
}
-static inline void sBufferDescriptorInfo(std::string name, uint32_t width, uint32_t height,
- PixelFormat format, uint32_t layerCount, uint64_t usage,
- IMapper::BufferDescriptorInfo* outDescriptorInfo) {
- outDescriptorInfo->name = name;
- outDescriptorInfo->width = width;
- outDescriptorInfo->height = height;
- outDescriptorInfo->layerCount = layerCount;
- outDescriptorInfo->format = static_cast<hardware::graphics::common::V1_2::PixelFormat>(format);
- outDescriptorInfo->usage = usage;
- outDescriptorInfo->reservedSize = 0;
-}
// See if gralloc "4.1" is available.
static bool hasIAllocatorAidl() {
@@ -119,6 +108,36 @@
return sHasIAllocatorAidl;
}
+// Determines whether the passed info is compatible with the mapper.
+static status_t validateBufferDescriptorInfo(IMapper::BufferDescriptorInfo* descriptorInfo) {
+ uint64_t validUsageBits = getValidUsageBits();
+ if (hasIAllocatorAidl()) {
+ validUsageBits |= getValidUsageBits41();
+ }
+
+ if (descriptorInfo->usage & ~validUsageBits) {
+ ALOGE("buffer descriptor contains invalid usage bits 0x%" PRIx64,
+ descriptorInfo->usage & ~validUsageBits);
+ return BAD_VALUE;
+ }
+ return NO_ERROR;
+}
+
+static inline status_t sBufferDescriptorInfo(std::string name, uint32_t width, uint32_t height,
+ PixelFormat format, uint32_t layerCount,
+ uint64_t usage,
+ IMapper::BufferDescriptorInfo* outDescriptorInfo) {
+ outDescriptorInfo->name = name;
+ outDescriptorInfo->width = width;
+ outDescriptorInfo->height = height;
+ outDescriptorInfo->layerCount = layerCount;
+ outDescriptorInfo->format = static_cast<hardware::graphics::common::V1_2::PixelFormat>(format);
+ outDescriptorInfo->usage = usage;
+ outDescriptorInfo->reservedSize = 0;
+
+ return validateBufferDescriptorInfo(outDescriptorInfo);
+}
+
} // anonymous namespace
void Gralloc4Mapper::preload() {
@@ -140,21 +159,6 @@
return mMapper != nullptr;
}
-status_t Gralloc4Mapper::validateBufferDescriptorInfo(
- IMapper::BufferDescriptorInfo* descriptorInfo) const {
- uint64_t validUsageBits = getValidUsageBits();
- if (hasIAllocatorAidl()) {
- validUsageBits |= getValidUsageBits41();
- }
-
- if (descriptorInfo->usage & ~validUsageBits) {
- ALOGE("buffer descriptor contains invalid usage bits 0x%" PRIx64,
- descriptorInfo->usage & ~validUsageBits);
- return BAD_VALUE;
- }
- return NO_ERROR;
-}
-
status_t Gralloc4Mapper::createDescriptor(void* bufferDescriptorInfo,
void* outBufferDescriptor) const {
IMapper::BufferDescriptorInfo* descriptorInfo =
@@ -207,8 +211,10 @@
uint32_t layerCount, uint64_t usage,
uint32_t stride) const {
IMapper::BufferDescriptorInfo descriptorInfo;
- sBufferDescriptorInfo("validateBufferSize", width, height, format, layerCount, usage,
- &descriptorInfo);
+ if (auto error = sBufferDescriptorInfo("validateBufferSize", width, height, format, layerCount,
+ usage, &descriptorInfo) != OK) {
+ return error;
+ }
auto buffer = const_cast<native_handle_t*>(bufferHandle);
auto ret = mMapper->validateBufferSize(buffer, descriptorInfo, stride);
@@ -427,7 +433,7 @@
if (fd >= 0) {
releaseFence = fd;
} else {
- ALOGD("failed to dup unlock release fence");
+ ALOGW("failed to dup unlock release fence");
sync_wait(fenceHandle->data[0], -1);
}
}
@@ -448,7 +454,12 @@
uint32_t layerCount, uint64_t usage,
bool* outSupported) const {
IMapper::BufferDescriptorInfo descriptorInfo;
- sBufferDescriptorInfo("isSupported", width, height, format, layerCount, usage, &descriptorInfo);
+ if (auto error = sBufferDescriptorInfo("isSupported", width, height, format, layerCount, usage,
+ &descriptorInfo) != OK) {
+ // Usage isn't known to the HAL or otherwise failed validation.
+ *outSupported = false;
+ return OK;
+ }
Error error;
auto ret = mMapper->isSupported(descriptorInfo,
@@ -691,7 +702,10 @@
}
IMapper::BufferDescriptorInfo descriptorInfo;
- sBufferDescriptorInfo("getDefault", width, height, format, layerCount, usage, &descriptorInfo);
+ if (auto error = sBufferDescriptorInfo("getDefault", width, height, format, layerCount, usage,
+ &descriptorInfo) != OK) {
+ return error;
+ }
hidl_vec<uint8_t> vec;
Error error;
@@ -1133,7 +1147,10 @@
uint64_t usage, uint32_t bufferCount, uint32_t* outStride,
buffer_handle_t* outBufferHandles, bool importBuffers) const {
IMapper::BufferDescriptorInfo descriptorInfo;
- sBufferDescriptorInfo(requestorName, width, height, format, layerCount, usage, &descriptorInfo);
+ if (auto error = sBufferDescriptorInfo(requestorName, width, height, format, layerCount, usage,
+ &descriptorInfo) != OK) {
+ return error;
+ }
BufferDescriptor descriptor;
status_t error = mMapper.createDescriptor(static_cast<void*>(&descriptorInfo),