Make hidl_vec/hidl_string safe for 32<->64 IPC.
Pointers going over IPC always need to be 64-bit.
This change introduces a hidl_pointer class that
wraps a pointer (without taking ownership), and
stuffs it in a union with a uint64_t to ensure we
always have 64-bits.
We can map size_t to either a fixed 32-bit or fixed
64-bit type. Since sending objects of more than
2^32 bytes seems a while out, we can save ourselves
4 bytes by allowing a maximum of 2^32 elements in
hidl_vec, and 2^32 characters in a string.
Bug: 32089785
Test: hidl_test, hidl_string 32->64->32
Change-Id: Ife77f7362013226aada51c7686e33494390824d7
diff --git a/HidlSupport.cpp b/HidlSupport.cpp
index 8c5ac17..1d87d4c 100644
--- a/HidlSupport.cpp
+++ b/HidlSupport.cpp
@@ -18,8 +18,8 @@
#include <hidl/HidlSupport.h>
-#ifdef LIBHIDL_TARGET_DEBUGGABLE
#include <android-base/logging.h>
+#ifdef LIBHIDL_TARGET_DEBUGGABLE
#include <cutils/properties.h>
#include <regex>
#include <utility>
@@ -28,6 +28,14 @@
namespace android {
namespace hardware {
+namespace details {
+
+void hidl_log_base::logAlwaysFatal(const char *message) {
+ LOG(FATAL) << message;
+}
+
+} // namespace details
+
static const char *const kEmptyString = "";
hidl_string::hidl_string()
@@ -96,12 +104,15 @@
void hidl_string::copyFrom(const char *data, size_t size) {
// assume my resources are freed.
+ if (size > UINT32_MAX) {
+ LOG(FATAL) << "string size can't exceed 2^32 bytes.";
+ }
char *buf = (char *)malloc(size + 1);
memcpy(buf, data, size);
buf[size] = '\0';
mBuffer = buf;
- mSize = size;
+ mSize = static_cast<uint32_t>(size);
mOwnsBuffer = true;
}
@@ -117,7 +128,7 @@
void hidl_string::clear() {
if (mOwnsBuffer && (mBuffer != kEmptyString)) {
- free(const_cast<char *>(mBuffer));
+ free(const_cast<char *>(static_cast<const char *>(mBuffer)));
}
mBuffer = kEmptyString;
@@ -126,10 +137,13 @@
}
void hidl_string::setToExternal(const char *data, size_t size) {
+ if (size > UINT32_MAX) {
+ LOG(FATAL) << "string size can't exceed 2^32 bytes.";
+ }
clear();
mBuffer = data;
- mSize = size;
+ mSize = static_cast<uint32_t>(size);
mOwnsBuffer = false;
}