libui: harden GraphicBufferMapper::importBuffer
Add support for validateBufferSize and getTransportSize from IMapper
2.1. Update GraphicBufferMapper::importBuffer to validate buffer
size, and update GraphicBuffer::flatten to use the handle transport
size.
This fixes two issues with GraphicBuffer. Pointers returned by
lock/lockYCbCr can now be accessed without potential OOB. flatten
no longer includes process-local runtime data.
Bug: 62535446
Bug: 62084097
Bug: 32587089
Test: manual
Change-Id: Ice13af26b84f25e43089637e9d67e3ad820e22ed
diff --git a/libs/ui/Gralloc2.cpp b/libs/ui/Gralloc2.cpp
index 0eb08e5..1f746a2 100644
--- a/libs/ui/Gralloc2.cpp
+++ b/libs/ui/Gralloc2.cpp
@@ -39,9 +39,15 @@
Mapper::Mapper()
{
mMapper = IMapper::getService();
- if (mMapper == nullptr || mMapper->isRemote()) {
+ if (mMapper == nullptr) {
+ LOG_ALWAYS_FATAL("gralloc-mapper is missing");
+ }
+ if (mMapper->isRemote()) {
LOG_ALWAYS_FATAL("gralloc-mapper must be in passthrough mode");
}
+
+ // IMapper 2.1 is optional
+ mMapperV2_1 = hardware::graphics::mapper::V2_1::IMapper::castFrom(mMapper);
}
Error Mapper::createDescriptor(
@@ -91,6 +97,50 @@
buffer, error);
}
+Error Mapper::validateBufferSize(buffer_handle_t bufferHandle,
+ const IMapper::BufferDescriptorInfo& descriptorInfo,
+ uint32_t stride) const
+{
+ if (mMapperV2_1 == nullptr) {
+ return Error::NONE;
+ }
+
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+ auto ret = mMapperV2_1->validateBufferSize(buffer, descriptorInfo, stride);
+
+ return (ret.isOk()) ? static_cast<Error>(ret) : kTransactionError;
+}
+
+void Mapper::getTransportSize(buffer_handle_t bufferHandle,
+ uint32_t* outNumFds, uint32_t* outNumInts) const
+{
+ *outNumFds = uint32_t(bufferHandle->numFds);
+ *outNumInts = uint32_t(bufferHandle->numInts);
+
+ if (mMapperV2_1 == nullptr) {
+ return;
+ }
+
+ Error error;
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+ auto ret = mMapperV2_1->getTransportSize(buffer,
+ [&](const auto& tmpError, const auto& tmpNumFds, const auto& tmpNumInts) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ *outNumFds = tmpNumFds;
+ *outNumInts = tmpNumInts;
+ });
+
+ if (!ret.isOk()) {
+ error = kTransactionError;
+ }
+ ALOGE_IF(error != Error::NONE, "getTransportSize(%p) failed with %d",
+ buffer, error);
+}
+
Error Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage,
const IMapper::Rect& accessRegion,
int acquireFence, void** outData) const