libhidlbase: work w/ cfi
In a couple of places, in order to reduce templated code, HIDL relies on
auto-generated classes being exactly the same.
- one of these places, this reliance is unnecessary, so it's removed
- one of these places, explicitly documenting assumptions and turning
off cfi
Fixes: 151006394
Test: hidl_test (w/ libhidlbase cfi on)
Test: atest MediaDrmClearkeyTest (no more cfi error)
Change-Id: I4834d38bcdaa2bb94e014f4c749251ee2025af15
diff --git a/transport/HidlBinderSupport.cpp b/transport/HidlBinderSupport.cpp
index 89b3a24..b48b460 100644
--- a/transport/HidlBinderSupport.cpp
+++ b/transport/HidlBinderSupport.cpp
@@ -19,6 +19,9 @@
#include <hidl/HidlBinderSupport.h>
#include <android/hidl/base/1.0/BpHwBase.h>
+#include <android/hidl/manager/1.0/BpHwServiceManager.h>
+#include <android/hidl/manager/1.1/BpHwServiceManager.h>
+#include <android/hidl/manager/1.2/BpHwServiceManager.h>
#include <hwbinder/IPCThreadState.h>
#include "InternalStatic.h" // TODO(b/69122224): remove this include, for getOrCreateCachedBinder
@@ -206,16 +209,34 @@
return status;
}
+// assume: iface != nullptr, iface isRemote
+// This function is to sandbox a cast through a BpHw* class into a function, so
+// that we can remove cfi sanitization from it. Do not add additional
+// functionality here.
+__attribute__((no_sanitize("cfi"))) static inline BpHwRefBase* forceGetRefBase(
+ ::android::hidl::base::V1_0::IBase* ifacePtr) {
+ using ::android::hidl::base::V1_0::BpHwBase;
+
+ // canary only
+ static_assert(sizeof(BpHwBase) == sizeof(hidl::manager::V1_0::BpHwServiceManager));
+ static_assert(sizeof(BpHwBase) == sizeof(hidl::manager::V1_1::BpHwServiceManager));
+ static_assert(sizeof(BpHwBase) == sizeof(hidl::manager::V1_2::BpHwServiceManager));
+
+ // All BpHw* are generated the same. This may be BpHwServiceManager,
+ // BpHwFoo, or any other class. For ABI compatibility, we can't modify the
+ // class hierarchy of these, so we have no way to get BpHwRefBase from a
+ // remote ifacePtr.
+ BpHwBase* bpBase = static_cast<BpHwBase*>(ifacePtr);
+ return static_cast<BpHwRefBase*>(bpBase);
+}
+
sp<IBinder> getOrCreateCachedBinder(::android::hidl::base::V1_0::IBase* ifacePtr) {
if (ifacePtr == nullptr) {
return nullptr;
}
if (ifacePtr->isRemote()) {
- using ::android::hidl::base::V1_0::BpHwBase;
-
- BpHwBase* bpBase = static_cast<BpHwBase*>(ifacePtr);
- BpHwRefBase* bpRefBase = static_cast<BpHwRefBase*>(bpBase);
+ BpHwRefBase* bpRefBase = forceGetRefBase(ifacePtr);
return sp<IBinder>(bpRefBase->remote());
}