Runtime support for CFI
Control Flow Integrity support in bionic.
General design:
http://clang.llvm.org/docs/ControlFlowIntegrityDesign.html#shared-library-support
This CL implements subsections "CFI Shadow" and "CFI_SlowPath" in the above document.
Bug: 22033465
Test: bionic device tests
Change-Id: I14dfea630de468eb5620e7f55f92b1397ba06217
diff --git a/linker/linker.cpp b/linker/linker.cpp
index fc8d1ef..83bd9f3 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -48,6 +48,7 @@
#include "linker.h"
#include "linker_block_allocator.h"
+#include "linker_cfi.h"
#include "linker_gdb_support.h"
#include "linker_globals.h"
#include "linker_debug.h"
@@ -105,6 +106,12 @@
// Is ASAN enabled?
static bool g_is_asan = false;
+static CFIShadowWriter g_cfi_shadow;
+
+CFIShadowWriter* get_cfi_shadow() {
+ return &g_cfi_shadow;
+}
+
static bool is_system_library(const std::string& realpath) {
for (const auto& dir : g_default_namespace.get_default_library_paths()) {
if (file_is_in_dir(realpath, dir)) {
@@ -1226,7 +1233,7 @@
// target_sdk_version (*candidate != nullptr)
// 2. The library was not found by soname (*candidate is nullptr)
static bool find_loaded_library_by_soname(android_namespace_t* ns,
- const char* name, soinfo** candidate) {
+ const char* name, soinfo** candidate) {
*candidate = nullptr;
// Ignore filename with path.
@@ -1504,7 +1511,8 @@
bool linked = local_group.visit([&](soinfo* si) {
if (!si->is_linked()) {
- if (!si->link_image(global_group, local_group, extinfo)) {
+ if (!si->link_image(global_group, local_group, extinfo) ||
+ !get_cfi_shadow()->AfterLoad(si, solist_get_head())) {
return false;
}
}
@@ -1656,6 +1664,7 @@
while ((si = local_unload_list.pop_front()) != nullptr) {
notify_gdb_of_unload(si);
+ get_cfi_shadow()->BeforeUnload(si);
soinfo_free(si);
}