Merge "Refactor Config from a struct to a class."
diff --git a/android-changes-for-ndk-developers.md b/android-changes-for-ndk-developers.md
index ebdae83..5279118 100644
--- a/android-changes-for-ndk-developers.md
+++ b/android-changes-for-ndk-developers.md
@@ -145,6 +145,12 @@
 temporarily support these libraries; so if you see a warning that means
 your code will not work in a future release -- please fix it now!
 
+In O and later, the system property `debug.ld.greylist_disabled` can be
+used to deny access to the greylist even to an app that would normally
+be allowed it. This allows you to test compatibility without bumping the
+app's `targetSdkVersion`. Use `setprop debug.ld.greylist_disabled true`
+to turn this on (any other value leaves the greylist enabled).
+
 ```
 $ readelf --dynamic libBroken.so | grep NEEDED
  0x00000001 (NEEDED)                     Shared library: [libnativehelper.so]
diff --git a/libc/Android.bp b/libc/Android.bp
index 8c6f596..72699f5 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -2182,6 +2182,63 @@
     first_version: "9",
 }
 
+llndk_library {
+    name: "libc.llndk",
+    symbol_file: "libc.map.txt",
+    export_headers_as_system: true,
+    export_preprocessed_headers: ["include"],
+    arch: {
+        arm: {
+            export_include_dirs: [
+                "arch-arm/include",
+                "kernel/uapi",
+                "kernel/uapi/asm-arm",
+                "kernel/android/uapi",
+            ],
+        },
+        arm64: {
+            export_include_dirs: [
+                "arch-arm64/include",
+                "kernel/uapi",
+                "kernel/uapi/asm-arm64",
+                "kernel/android/uapi",
+            ],
+        },
+        mips: {
+            export_include_dirs: [
+                "arch-mips/include",
+                "kernel/uapi",
+                "kernel/uapi/asm-mips",
+                "kernel/android/uapi",
+            ],
+        },
+        mips64: {
+            export_include_dirs: [
+                "arch-mips64/include",
+                "kernel/uapi",
+                "kernel/uapi/asm-mips",
+                "kernel/android/uapi",
+            ],
+        },
+        x86: {
+            export_include_dirs: [
+                "arch-x86/include",
+                "kernel/uapi",
+                "kernel/uapi/asm-x86",
+                "kernel/android/uapi",
+            ],
+        },
+        x86_64: {
+            export_include_dirs: [
+                "arch-x86_64/include",
+                "kernel/uapi",
+                "kernel/uapi/asm-x86",
+                "kernel/android/uapi",
+            ],
+        },
+    },
+}
+
 ndk_library {
     name: "libstdc++.ndk",
     symbol_file: "libstdc++.map.txt",
diff --git a/libc/private/CachedProperty.h b/libc/private/CachedProperty.h
new file mode 100644
index 0000000..0a41abf
--- /dev/null
+++ b/libc/private/CachedProperty.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <string.h>
+
+#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
+#include <sys/_system_properties.h>
+
+#include "private/bionic_lock.h"
+
+class CachedProperty {
+ public:
+  CachedProperty(const char* property_name)
+    : property_name_(property_name),
+      prop_info_(nullptr),
+      cached_area_serial_(0),
+      cached_property_serial_(0) {
+    cached_value_[0] = '\0';
+  }
+
+  const char* Get() {
+    lock_.lock();
+
+    // Do we have a `struct prop_info` yet?
+    if (prop_info_ == nullptr) {
+      // `__system_property_find` is expensive, so only retry if a property
+      // has been created since last time we checked.
+      uint32_t property_area_serial = __system_property_area_serial();
+      if (property_area_serial != cached_area_serial_) {
+        prop_info_ = __system_property_find(property_name_);
+        cached_area_serial_ = property_area_serial;
+      }
+    }
+
+    if (prop_info_ != nullptr) {
+      // Only bother re-reading the property if it's actually changed since last time.
+      uint32_t property_serial = __system_property_serial(prop_info_);
+      if (property_serial != cached_property_serial_) {
+        __system_property_read_callback(prop_info_, &CachedProperty::Callback, this);
+      }
+    }
+
+    lock_.unlock();
+    return cached_value_;
+  }
+
+ private:
+  Lock lock_;
+  const char* property_name_;
+  const prop_info* prop_info_;
+  uint32_t cached_area_serial_;
+  uint32_t cached_property_serial_;
+  char cached_value_[PROP_VALUE_MAX];
+
+  static void Callback(void* data, const char*, const char* value, uint32_t serial) {
+    CachedProperty* instance = reinterpret_cast<CachedProperty*>(data);
+    instance->cached_property_serial_ = serial;
+    strcpy(instance->cached_value_, value);
+  }
+};
diff --git a/libc/private/ScopeGuard.h b/libc/private/ScopeGuard.h
deleted file mode 100644
index d5a9235..0000000
--- a/libc/private/ScopeGuard.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _SCOPE_GUARD_H
-#define _SCOPE_GUARD_H
-
-#include "private/bionic_macros.h"
-
-// TODO: include explicit std::move when it becomes available
-template<typename F>
-class ScopeGuard {
- public:
-  ScopeGuard(F f) : f_(f), active_(true) {}
-
-  ScopeGuard(ScopeGuard&& that) : f_(that.f_), active_(that.active_) {
-    that.active_ = false;
-  }
-
-  ~ScopeGuard() {
-    if (active_) {
-      f_();
-    }
-  }
-
-  void disable() {
-    active_ = false;
-  }
- private:
-  F f_;
-  bool active_;
-
-  DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeGuard);
-};
-
-template<typename T>
-ScopeGuard<T> make_scope_guard(T f) {
-  return ScopeGuard<T>(f);
-}
-
-#endif  // _SCOPE_GUARD_H
diff --git a/libdl/Android.bp b/libdl/Android.bp
index 5b67e38..8c6b47e 100644
--- a/libdl/Android.bp
+++ b/libdl/Android.bp
@@ -124,3 +124,8 @@
     symbol_file: "libdl.map.txt",
     first_version: "9",
 }
+
+llndk_library {
+    name: "libdl.llndk",
+    symbol_file: "libdl.map.txt",
+}
diff --git a/libm/Android.bp b/libm/Android.bp
index 7489bfe..24e641c 100644
--- a/libm/Android.bp
+++ b/libm/Android.bp
@@ -538,3 +538,8 @@
     symbol_file: "libm.map.txt",
     first_version: "9",
 }
+
+llndk_library {
+    name: "libm.llndk",
+    symbol_file: "libm.map.txt",
+}
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 1647db7..d31c652 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -43,8 +43,9 @@
 #include <unordered_map>
 #include <vector>
 
+#include <android-base/scopeguard.h>
+
 // Private C library headers.
-#include "private/ScopeGuard.h"
 
 #include "linker.h"
 #include "linker_block_allocator.h"
@@ -185,7 +186,7 @@
   };
 
   // If you're targeting N, you don't get the greylist.
-  if (get_application_target_sdk_version() >= __ANDROID_API_N__) {
+  if (g_greylist_disabled || get_application_target_sdk_version() >= __ANDROID_API_N__) {
     return false;
   }
 
@@ -1536,13 +1537,13 @@
   // list of libraries to link - see step 2.
   size_t soinfos_count = 0;
 
-  auto scope_guard = make_scope_guard([&]() {
+  auto scope_guard = android::base::make_scope_guard([&]() {
     for (LoadTask* t : load_tasks) {
       LoadTask::deleter(t);
     }
   });
 
-  auto failure_guard = make_scope_guard([&]() {
+  auto failure_guard = android::base::make_scope_guard([&]() {
     // Housekeeping
     soinfo_unload(soinfos, soinfos_count);
   });
@@ -1661,7 +1662,7 @@
       }
     });
 
-    failure_guard.disable();
+    failure_guard.Disable();
   }
 
   return linked;
@@ -1904,9 +1905,8 @@
          ns == nullptr ? "(null)" : ns->get_name(),
          ns);
 
-  auto failure_guard = make_scope_guard([&]() {
-    LD_LOG(kLogDlopen, "... dlopen failed: %s", linker_get_error_buffer());
-  });
+  auto failure_guard = android::base::make_scope_guard(
+      [&]() { LD_LOG(kLogDlopen, "... dlopen failed: %s", linker_get_error_buffer()); });
 
   if ((flags & ~(RTLD_NOW|RTLD_LAZY|RTLD_LOCAL|RTLD_GLOBAL|RTLD_NODELETE|RTLD_NOLOAD)) != 0) {
     DL_ERR("invalid flags to dlopen: %x", flags);
@@ -1966,7 +1966,7 @@
            "... dlopen calling constructors: realpath=\"%s\", soname=\"%s\", handle=%p",
            si->get_realpath(), si->get_soname(), handle);
     si->call_constructors();
-    failure_guard.disable();
+    failure_guard.Disable();
     LD_LOG(kLogDlopen,
            "... dlopen successful: realpath=\"%s\", soname=\"%s\", handle=%p",
            si->get_realpath(), si->get_soname(), handle);
@@ -2044,9 +2044,8 @@
          ns == nullptr ? "(null)" : ns->get_name(),
          ns);
 
-  auto failure_guard = make_scope_guard([&]() {
-    LD_LOG(kLogDlsym, "... dlsym failed: %s", linker_get_error_buffer());
-  });
+  auto failure_guard = android::base::make_scope_guard(
+      [&]() { LD_LOG(kLogDlsym, "... dlsym failed: %s", linker_get_error_buffer()); });
 
   if (sym_name == nullptr) {
     DL_ERR("dlsym failed: symbol name is null");
@@ -2077,7 +2076,7 @@
 
     if ((bind == STB_GLOBAL || bind == STB_WEAK) && sym->st_shndx != 0) {
       *symbol = reinterpret_cast<void*>(found->resolve_symbol_address(sym));
-      failure_guard.disable();
+      failure_guard.Disable();
       LD_LOG(kLogDlsym,
              "... dlsym successful: sym_name=\"%s\", sym_ver=\"%s\", found in=\"%s\", address=%p",
              sym_name, sym_ver, found->get_soname(), *symbol);
diff --git a/linker/linker_config.cpp b/linker/linker_config.cpp
index 33616f7..a12cfbe 100644
--- a/linker/linker_config.cpp
+++ b/linker/linker_config.cpp
@@ -33,10 +33,9 @@
 #include "linker_utils.h"
 
 #include <android-base/file.h>
+#include <android-base/scopeguard.h>
 #include <android-base/strings.h>
 
-#include <private/ScopeGuard.h>
-
 #include <stdlib.h>
 
 #include <string>
@@ -379,9 +378,7 @@
 
   Properties properties(std::move(property_map));
 
-  auto failure_guard = make_scope_guard([] {
-    g_config.clear();
-  });
+  auto failure_guard = android::base::make_scope_guard([] { g_config.clear(); });
 
   std::unordered_map<std::string, NamespaceConfig*> namespace_configs;
 
@@ -469,7 +466,7 @@
     ns_config->set_permitted_paths(properties.get_paths(property_name_prefix + ".permitted.paths"));
   }
 
-  failure_guard.disable();
+  failure_guard.Disable();
   *config = &g_config;
   return true;
 }
diff --git a/linker/linker_logger.cpp b/linker/linker_logger.cpp
index b2ea320..717667c 100644
--- a/linker/linker_logger.cpp
+++ b/linker/linker_logger.cpp
@@ -26,32 +26,21 @@
  * SUCH DAMAGE.
  */
 
+#include "linker_logger.h"
+
 #include <string.h>
 #include <sys/prctl.h>
-#include <sys/system_properties.h>
 #include <unistd.h>
 
 #include <string>
 #include <vector>
 
 #include "android-base/strings.h"
-#include "linker_logger.h"
+#include "private/CachedProperty.h"
 #include "private/libc_logging.h"
 
 LinkerLogger g_linker_logger;
-
-static const char* kSystemLdDebugProperty = "debug.ld.all";
-static const char* kLdDebugPropertyPrefix = "debug.ld.app.";
-
-static const char* kOptionErrors = "dlerror";
-static const char* kOptionDlopen = "dlopen";
-static const char* kOptionDlsym = "dlsym";
-
-static std::string property_get(const char* name) {
-  char value[PROP_VALUE_MAX] = {};
-  __system_property_get(name, value);
-  return value;
-}
+bool g_greylist_disabled = false;
 
 static uint32_t ParseProperty(const std::string& value) {
   if (value.empty()) {
@@ -63,38 +52,22 @@
   uint32_t flags = 0;
 
   for (const auto& o : options) {
-    if (o == kOptionErrors) {
+    if (o == "dlerror") {
       flags |= kLogErrors;
-    } else if (o == kOptionDlopen){
+    } else if (o == "dlopen") {
       flags |= kLogDlopen;
-    } else if (o == kOptionDlsym){
+    } else if (o == "dlsym") {
       flags |= kLogDlsym;
     } else {
-      __libc_format_log(ANDROID_LOG_WARN, "linker", "Unknown debug.ld option \"%s\", will ignore.", o.c_str());
+      __libc_format_log(ANDROID_LOG_WARN, "linker", "Ignoring unknown debug.ld option \"%s\"",
+                        o.c_str());
     }
   }
 
   return flags;
 }
 
-void LinkerLogger::ResetState() {
-  // the most likely scenario app is not debuggable and
-  // is running on user build - the logging is disabled.
-  if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) == 0) {
-    return;
-  }
-
-  flags_ = 0;
-
-  // Check flag applied to all processes first.
-  std::string value = property_get(kSystemLdDebugProperty);
-  flags_ |= ParseProperty(value);
-
-  // Ignore processes started without argv (http://b/33276926).
-  if (g_argv[0] == nullptr) {
-    return;
-  }
-
+static void GetAppSpecificProperty(char* buffer) {
   // Get process basename.
   const char* process_name_start = basename(g_argv[0]);
 
@@ -106,10 +79,42 @@
                              std::string(process_name_start, (process_name_end - process_name_start)) :
                              std::string(process_name_start);
 
-  std::string property_name = std::string(kLdDebugPropertyPrefix) + process_name;
+  std::string property_name = std::string("debug.ld.app.") + process_name;
+  __system_property_get(property_name.c_str(), buffer);
+}
 
-  value = property_get(property_name.c_str());
-  flags_ |= ParseProperty(value);
+void LinkerLogger::ResetState() {
+  // The most likely scenario app is not debuggable and
+  // is running on a user build, in which case logging is disabled.
+  if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) == 0) {
+    return;
+  }
+
+  // This is a convenient place to check whether the greylist should be disabled for testing.
+  static CachedProperty greylist_disabled("debug.ld.greylist_disabled");
+  bool old_value = g_greylist_disabled;
+  g_greylist_disabled = (strcmp(greylist_disabled.Get(), "true") == 0);
+  if (g_greylist_disabled != old_value) {
+    __libc_format_log(ANDROID_LOG_INFO, "linker", "%s greylist",
+                      g_greylist_disabled ? "Disabling" : "Enabling");
+  }
+
+  flags_ = 0;
+
+  // For logging, check the flag applied to all processes first.
+  static CachedProperty debug_ld_all("debug.ld.all");
+  flags_ |= ParseProperty(debug_ld_all.Get());
+
+  // Ignore processes started without argv (http://b/33276926).
+  if (g_argv[0] == nullptr) {
+    return;
+  }
+
+  // Otherwise check the app-specific property too.
+  // We can't easily cache the property here because argv[0] changes.
+  char debug_ld_app[PROP_VALUE_MAX] = {};
+  GetAppSpecificProperty(debug_ld_app);
+  flags_ |= ParseProperty(debug_ld_app);
 }
 
 void LinkerLogger::Log(uint32_t type, const char* format, ...) {
@@ -122,4 +127,3 @@
   __libc_format_log_va_list(ANDROID_LOG_DEBUG, "linker", format, ap);
   va_end(ap);
 }
-
diff --git a/linker/linker_logger.h b/linker/linker_logger.h
index f37b974..3e53f74 100644
--- a/linker/linker_logger.h
+++ b/linker/linker_logger.h
@@ -58,4 +58,8 @@
 extern LinkerLogger g_linker_logger;
 extern char** g_argv;
 
+// If the system property debug.ld.greylist_disabled is true, we'll not use the greylist
+// regardless of API level.
+extern bool g_greylist_disabled;
+
 #endif /* _LINKER_LOGGER_H_ */
diff --git a/linker/tests/linker_config_test.cpp b/linker/tests/linker_config_test.cpp
index 64ab00f..418cbda 100644
--- a/linker/tests/linker_config_test.cpp
+++ b/linker/tests/linker_config_test.cpp
@@ -36,12 +36,11 @@
 
 #include <unistd.h>
 
+#include <android-base/scopeguard.h>
 #include <android-base/stringprintf.h>
 #include <android-base/file.h>
 #include <android-base/test_utils.h>
 
-#include "private/ScopeGuard.h"
-
 
 static const char* config_str =
   "# comment \n"
@@ -116,9 +115,8 @@
   std::string executable_path = std::string(tmp_dir.path) + "/some-binary";
   std::string version_file = std::string(tmp_dir.path) + "/.version";
 
-  auto file_guard = make_scope_guard([&version_file] {
-    unlink(version_file.c_str());
-  });
+  auto file_guard =
+      android::base::make_scope_guard([&version_file] { unlink(version_file.c_str()); });
 
   ASSERT_TRUE(write_version(version_file, 113U)) << strerror(errno);
 
diff --git a/tests/bug_26110743_test.cpp b/tests/bug_26110743_test.cpp
index c49a9dc..ef474a0 100644
--- a/tests/bug_26110743_test.cpp
+++ b/tests/bug_26110743_test.cpp
@@ -22,7 +22,7 @@
 #include <sys/stat.h>
 #include <sys/prctl.h>
 
-#include "private/ScopeGuard.h"
+#include <android-base/scopeguard.h>
 
 extern "C" pid_t gettid();
 
@@ -56,7 +56,7 @@
 TEST(bug_26110743, ProcSelfReadlink_NotDumpable) {
   int dumpable = prctl(PR_GET_DUMPABLE, 0, 0, 0, 0);
   prctl(PR_SET_DUMPABLE, 0, 0, 0, 0);
-  auto guard = make_scope_guard([&]() {
+  auto guard = android::base::make_scope_guard([&]() {
     // restore dumpable
     prctl(PR_SET_DUMPABLE, dumpable, 0, 0, 0);
   });
@@ -100,7 +100,7 @@
 TEST(bug_26110743, ProcTaskFdReadlink_NotDumpable) {
   int dumpable = prctl(PR_GET_DUMPABLE, 0, 0, 0, 0);
   prctl(PR_SET_DUMPABLE, 0, 0, 0, 0);
-  auto guard = make_scope_guard([&]() {
+  auto guard = android::base::make_scope_guard([&]() {
     // restore dumpable
     prctl(PR_SET_DUMPABLE, dumpable, 0, 0, 0);
   });
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index ad8444e..4ff324e 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -22,11 +22,11 @@
 #include <stdint.h>
 #include <string.h>
 
-#include "private/ScopeGuard.h"
-
 #include <string>
 #include <thread>
 
+#include <android-base/scopeguard.h>
+
 #include "gtest_globals.h"
 #include "dlfcn_symlink_support.h"
 #include "utils.h"
@@ -330,9 +330,7 @@
   // in both dt_needed libraries, the correct relocation should
   // use the function defined in libtest_relo_check_dt_needed_order_1.so
   void* handle = nullptr;
-  auto guard = make_scope_guard([&]() {
-    dlclose(handle);
-  });
+  auto guard = android::base::make_scope_guard([&]() { dlclose(handle); });
 
   handle = dlopen("libtest_relo_check_dt_needed_order.so", RTLD_NOW);
   ASSERT_TRUE(handle != nullptr) << dlerror();
@@ -986,9 +984,7 @@
   dlerror(); // Clear any pending errors.
   void* handle = dlopen("libgnu-hash-table-library.so", RTLD_NOW);
   ASSERT_TRUE(handle != nullptr) << dlerror();
-  auto guard = make_scope_guard([&]() {
-    dlclose(handle);
-  });
+  auto guard = android::base::make_scope_guard([&]() { dlclose(handle); });
   void* sym = dlsym(handle, "getRandomNumber");
   ASSERT_TRUE(sym != nullptr) << dlerror();
   int (*fn)(void);
@@ -1009,9 +1005,7 @@
 TEST(dlfcn, dlopen_library_with_only_sysv_hash) {
   void* handle = dlopen("libsysv-hash-table-library.so", RTLD_NOW);
   ASSERT_TRUE(handle != nullptr) << dlerror();
-  auto guard = make_scope_guard([&]() {
-    dlclose(handle);
-  });
+  auto guard = android::base::make_scope_guard([&]() { dlclose(handle); });
   void* sym = dlsym(handle, "getRandomNumber");
   ASSERT_TRUE(sym != nullptr) << dlerror();
   int (*fn)(void);
diff --git a/tests/fortify_test.cpp b/tests/fortify_test.cpp
index c21c9da..67103e1 100644
--- a/tests/fortify_test.cpp
+++ b/tests/fortify_test.cpp
@@ -58,71 +58,44 @@
   char b[10];
 };
 
-#ifndef __clang__
-// This test is disabled in clang because clang doesn't properly detect
-// this buffer overflow. TODO: Fix clang.
 TEST_F(DEATHTEST, stpncpy_fortified2) {
   foo myfoo;
   int copy_amt = atoi("11");
   ASSERT_FORTIFY(stpncpy(myfoo.a, "01234567890", copy_amt));
 }
-#endif
 
-#ifndef __clang__
-// This test is disabled in clang because clang doesn't properly detect
-// this buffer overflow. TODO: Fix clang.
 TEST_F(DEATHTEST, stpncpy2_fortified2) {
   foo myfoo;
   memset(&myfoo, 0, sizeof(myfoo));
   myfoo.one[0] = 'A'; // not null terminated string
   ASSERT_FORTIFY(stpncpy(myfoo.b, myfoo.one, sizeof(myfoo.b)));
 }
-#endif
 
-#ifndef __clang__
-// This test is disabled in clang because clang doesn't properly detect
-// this buffer overflow. TODO: Fix clang.
 TEST_F(DEATHTEST, strncpy_fortified2) {
   foo myfoo;
   int copy_amt = atoi("11");
   ASSERT_FORTIFY(strncpy(myfoo.a, "01234567890", copy_amt));
 }
-#endif
 
-#ifndef __clang__
-// This test is disabled in clang because clang doesn't properly detect
-// this buffer overflow. TODO: Fix clang.
 TEST_F(DEATHTEST, strncpy2_fortified2) {
   foo myfoo;
   memset(&myfoo, 0, sizeof(myfoo));
   myfoo.one[0] = 'A'; // not null terminated string
   ASSERT_FORTIFY(strncpy(myfoo.b, myfoo.one, sizeof(myfoo.b)));
 }
-#endif
 
-#ifndef __clang__
-// This test is disabled in clang because clang doesn't properly detect
-// this buffer overflow. TODO: Fix clang.
 TEST_F(DEATHTEST, sprintf_fortified2) {
   foo myfoo;
   char source_buf[15];
   memcpy(source_buf, "12345678901234", 15);
   ASSERT_FORTIFY(sprintf(myfoo.a, "%s", source_buf));
 }
-#endif
 
-#ifndef __clang__
-// This test is disabled in clang because clang doesn't properly detect
-// this buffer overflow. TODO: Fix clang.
 TEST_F(DEATHTEST, sprintf2_fortified2) {
   foo myfoo;
   ASSERT_FORTIFY(sprintf(myfoo.a, "0123456789"));
 }
-#endif
 
-#ifndef __clang__
-// These tests are disabled in clang because clang doesn't properly detect
-// this buffer overflow. TODO: Fix clang.
 static int vsprintf_helper2(const char *fmt, ...) {
   foo myfoo;
   va_list va;
@@ -141,11 +114,7 @@
 TEST_F(DEATHTEST, vsprintf2_fortified2) {
   ASSERT_FORTIFY(vsprintf_helper2("0123456789"));
 }
-#endif
 
-#ifndef __clang__
-// These tests are disabled in clang because clang doesn't properly detect
-// this buffer overflow. TODO: Fix clang.
 static int vsnprintf_helper2(const char *fmt, ...) {
   foo myfoo;
   va_list va;
@@ -165,12 +134,8 @@
 TEST_F(DEATHTEST, vsnprintf2_fortified2) {
   ASSERT_FORTIFY(vsnprintf_helper2("0123456789"));
 }
-#endif
 
-#ifndef __clang__
 // zero sized target with "\0" source (should fail)
-// This test is disabled in clang because clang doesn't properly detect
-// this buffer overflow. TODO: Fix clang.
 TEST_F(DEATHTEST, stpcpy_fortified2) {
 #if defined(__BIONIC__)
   foo myfoo;
@@ -181,12 +146,8 @@
   GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif // __BIONIC__
 }
-#endif
 
-#ifndef __clang__
 // zero sized target with "\0" source (should fail)
-// This test is disabled in clang because clang doesn't properly detect
-// this buffer overflow. TODO: Fix clang.
 TEST_F(DEATHTEST, strcpy_fortified2) {
 #if defined(__BIONIC__)
   foo myfoo;
@@ -197,12 +158,8 @@
   GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif // __BIONIC__
 }
-#endif
 
-#ifndef __clang__
 // zero sized target with longer source (should fail)
-// This test is disabled in clang because clang doesn't properly detect
-// this buffer overflow. TODO: Fix clang.
 TEST_F(DEATHTEST, strcpy2_fortified2) {
 #if defined(__BIONIC__)
   foo myfoo;
@@ -213,12 +170,8 @@
   GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif // __BIONIC__
 }
-#endif
 
-#ifndef __clang__
 // one byte target with longer source (should fail)
-// This test is disabled in clang because clang doesn't properly detect
-// this buffer overflow. TODO: Fix clang.
 TEST_F(DEATHTEST, strcpy3_fortified2) {
 #if defined(__BIONIC__)
   foo myfoo;
@@ -229,7 +182,6 @@
   GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif // __BIONIC__
 }
-#endif
 
 TEST_F(DEATHTEST, strchr_fortified2) {
 #if defined(__BIONIC__)
@@ -267,8 +219,6 @@
 #endif // __BIONIC__
 }
 
-#ifndef __clang__
-// This test is disabled in clang because clang doesn't properly detect
 // this buffer overflow. TODO: Fix clang.
 TEST_F(DEATHTEST, strlcpy_fortified2) {
 #if defined(__BIONIC__)
@@ -280,10 +230,7 @@
   GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif // __BIONIC__
 }
-#endif
 
-#ifndef __clang__
-// This test is disabled in clang because clang doesn't properly detect
 // this buffer overflow. TODO: Fix clang.
 TEST_F(DEATHTEST, strlcat_fortified2) {
 #if defined(__BIONIC__)
@@ -296,29 +243,20 @@
   GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif // __BIONIC__
 }
-#endif
 
-#ifndef __clang__
-// This test is disabled in clang because clang doesn't properly detect
-// this buffer overflow. TODO: Fix clang.
 TEST_F(DEATHTEST, strncat_fortified2) {
   foo myfoo;
   size_t n = atoi("10"); // avoid compiler optimizations
   strncpy(myfoo.a, "012345678", n);
   ASSERT_FORTIFY(strncat(myfoo.a, "9", n));
 }
-#endif
 
-#ifndef __clang__
-// This test is disabled in clang because clang doesn't properly detect
-// this buffer overflow. TODO: Fix clang.
 TEST_F(DEATHTEST, strncat2_fortified2) {
   foo myfoo;
   myfoo.a[0] = '\0';
   size_t n = atoi("10"); // avoid compiler optimizations
   ASSERT_FORTIFY(strncat(myfoo.a, "0123456789", n));
 }
-#endif
 
 TEST_F(DEATHTEST, strncat3_fortified2) {
   foo myfoo;
@@ -328,9 +266,6 @@
   ASSERT_FORTIFY(strncat(myfoo.b, myfoo.a, n));
 }
 
-#ifndef __clang__
-// This test is disabled in clang because clang doesn't properly detect
-// this buffer overflow. TODO: Fix clang.
 TEST_F(DEATHTEST, strcat_fortified2) {
   char src[11];
   strcpy(src, "0123456789");
@@ -338,7 +273,6 @@
   myfoo.a[0] = '\0';
   ASSERT_FORTIFY(strcat(myfoo.a, src));
 }
-#endif
 
 TEST_F(DEATHTEST, strcat2_fortified2) {
   foo myfoo;
@@ -473,7 +407,12 @@
   ASSERT_FORTIFY(sprintf(buf, "%s", source_buf));
 }
 
-#ifndef __clang__
+#ifdef __clang__
+// Exists upstream, but hasn't been pulled in yet.
+#if __has_attribute(alloc_size)
+#error "Reenable this test"
+#endif
+#else
 // This test is disabled in clang because clang doesn't properly detect
 // this buffer overflow. TODO: Fix clang.
 TEST_F(DEATHTEST, sprintf_malloc_fortified) {
diff --git a/tests/math_test.cpp b/tests/math_test.cpp
index 6c7dffb..b960944 100644
--- a/tests/math_test.cpp
+++ b/tests/math_test.cpp
@@ -57,7 +57,7 @@
 #include <limits.h>
 #include <stdint.h>
 
-#include <private/ScopeGuard.h>
+#include <android-base/scopeguard.h>
 
 float float_subnormal() {
   union {
@@ -775,9 +775,7 @@
 }
 
 TEST(math, lrint) {
-  auto guard = make_scope_guard([]() {
-    fesetenv(FE_DFL_ENV);
-  });
+  auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
 
   fesetround(FE_UPWARD); // lrint/lrintf/lrintl obey the rounding mode.
   ASSERT_EQ(1235, lrint(1234.01));
@@ -799,9 +797,7 @@
 }
 
 TEST(math, rint) {
-  auto guard = make_scope_guard([]() {
-    fesetenv(FE_DFL_ENV);
-  });
+  auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
 
   fesetround(FE_UPWARD); // rint/rintf/rintl obey the rounding mode.
   feclearexcept(FE_ALL_EXCEPT); // rint/rintf/rintl do set the FE_INEXACT flag.
@@ -829,9 +825,7 @@
 }
 
 TEST(math, nearbyint) {
-  auto guard = make_scope_guard([]() {
-    fesetenv(FE_DFL_ENV);
-  });
+  auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
   fesetround(FE_UPWARD); // nearbyint/nearbyintf/nearbyintl obey the rounding mode.
   feclearexcept(FE_ALL_EXCEPT); // nearbyint/nearbyintf/nearbyintl don't set the FE_INEXACT flag.
   ASSERT_EQ(1234.0, nearbyint(1234.0));
@@ -858,9 +852,7 @@
 }
 
 TEST(math, lround) {
-  auto guard = make_scope_guard([]() {
-    fesetenv(FE_DFL_ENV);
-  });
+  auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
   fesetround(FE_UPWARD); // lround ignores the rounding mode.
   ASSERT_EQ(1234, lround(1234.01));
   ASSERT_EQ(1234, lroundf(1234.01f));
@@ -868,9 +860,7 @@
 }
 
 TEST(math, llround) {
-  auto guard = make_scope_guard([]() {
-    fesetenv(FE_DFL_ENV);
-  });
+  auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
   fesetround(FE_UPWARD); // llround ignores the rounding mode.
   ASSERT_EQ(1234L, llround(1234.01));
   ASSERT_EQ(1234L, llroundf(1234.01f));
@@ -965,9 +955,7 @@
 }
 
 TEST(math, round) {
-  auto guard = make_scope_guard([]() {
-    fesetenv(FE_DFL_ENV);
-  });
+  auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
   fesetround(FE_TOWARDZERO); // round ignores the rounding mode and always rounds away from zero.
   ASSERT_DOUBLE_EQ(1.0, round(0.5));
   ASSERT_DOUBLE_EQ(-1.0, round(-0.5));
@@ -978,9 +966,7 @@
 }
 
 TEST(math, roundf) {
-  auto guard = make_scope_guard([]() {
-    fesetenv(FE_DFL_ENV);
-  });
+  auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
   fesetround(FE_TOWARDZERO); // roundf ignores the rounding mode and always rounds away from zero.
   ASSERT_FLOAT_EQ(1.0f, roundf(0.5f));
   ASSERT_FLOAT_EQ(-1.0f, roundf(-0.5f));
@@ -991,9 +977,7 @@
 }
 
 TEST(math, roundl) {
-  auto guard = make_scope_guard([]() {
-    fesetenv(FE_DFL_ENV);
-  });
+  auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
   fesetround(FE_TOWARDZERO); // roundl ignores the rounding mode and always rounds away from zero.
   ASSERT_DOUBLE_EQ(1.0L, roundl(0.5L));
   ASSERT_DOUBLE_EQ(-1.0L, roundl(-0.5L));
@@ -1004,9 +988,7 @@
 }
 
 TEST(math, trunc) {
-  auto guard = make_scope_guard([]() {
-    fesetenv(FE_DFL_ENV);
-  });
+  auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
   fesetround(FE_UPWARD); // trunc ignores the rounding mode and always rounds toward zero.
   ASSERT_DOUBLE_EQ(1.0, trunc(1.5));
   ASSERT_DOUBLE_EQ(-1.0, trunc(-1.5));
@@ -1017,9 +999,7 @@
 }
 
 TEST(math, truncf) {
-  auto guard = make_scope_guard([]() {
-    fesetenv(FE_DFL_ENV);
-  });
+  auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
   fesetround(FE_UPWARD); // truncf ignores the rounding mode and always rounds toward zero.
   ASSERT_FLOAT_EQ(1.0f, truncf(1.5f));
   ASSERT_FLOAT_EQ(-1.0f, truncf(-1.5f));
@@ -1030,9 +1010,7 @@
 }
 
 TEST(math, truncl) {
-  auto guard = make_scope_guard([]() {
-    fesetenv(FE_DFL_ENV);
-  });
+  auto guard = android::base::make_scope_guard([]() { fesetenv(FE_DFL_ENV); });
   fesetround(FE_UPWARD); // truncl ignores the rounding mode and always rounds toward zero.
   ASSERT_DOUBLE_EQ(1.0L, truncl(1.5L));
   ASSERT_DOUBLE_EQ(-1.0L, truncl(-1.5L));
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index 60fe294..87b4c81 100755
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -33,9 +33,10 @@
 #include <atomic>
 #include <vector>
 
+#include <android-base/scopeguard.h>
+
 #include "private/bionic_constants.h"
 #include "private/bionic_macros.h"
-#include "private/ScopeGuard.h"
 #include "BionicDeathTest.h"
 #include "ScopedSignalHandler.h"
 #include "utils.h"
@@ -64,7 +65,7 @@
   int nkeys = PTHREAD_KEYS_MAX / 2;
   std::vector<pthread_key_t> keys;
 
-  auto scope_guard = make_scope_guard([&keys]{
+  auto scope_guard = android::base::make_scope_guard([&keys] {
     for (const auto& key : keys) {
       EXPECT_EQ(0, pthread_key_delete(key));
     }
@@ -1362,7 +1363,7 @@
   }
   EXPECT_EQ(rl.rlim_cur, stack_size);
 
-  auto guard = make_scope_guard([&rl, original_rlim_cur]() {
+  auto guard = android::base::make_scope_guard([&rl, original_rlim_cur]() {
     rl.rlim_cur = original_rlim_cur;
     ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl));
   });
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index d90b01e..9eae06e 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -996,7 +996,7 @@
   if (rl.rlim_cur == RLIM_INFINITY) {
     rl.rlim_cur = 8 * 1024 * 1024; // Bionic reports unlimited stacks as 8MiB.
   }
-  auto guard = make_scope_guard([&rl, original_rlim_cur]() {
+  auto guard = android::base::make_scope_guard([&rl, original_rlim_cur]() {
     rl.rlim_cur = original_rlim_cur;
     ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl));
   });
diff --git a/tests/utils.h b/tests/utils.h
index fa85545..2e9b994 100644
--- a/tests/utils.h
+++ b/tests/utils.h
@@ -28,10 +28,9 @@
 #include <regex>
 
 #include <android-base/file.h>
+#include <android-base/scopeguard.h>
 #include <android-base/stringprintf.h>
 
-#include "private/ScopeGuard.h"
-
 #if defined(__LP64__)
 #define PATH_TO_SYSTEM_LIB "/system/lib64/"
 #else
@@ -68,9 +67,7 @@
       return false;
     }
 
-    auto fp_guard = make_scope_guard([&]() {
-      fclose(fp);
-    });
+    auto fp_guard = android::base::make_scope_guard([&]() { fclose(fp); });
 
     char line[BUFSIZ];
     while (fgets(line, sizeof(line), fp) != nullptr) {
diff --git a/tools/versioner/src/VFS.cpp b/tools/versioner/src/VFS.cpp
index cdf232f..8f9de88 100644
--- a/tools/versioner/src/VFS.cpp
+++ b/tools/versioner/src/VFS.cpp
@@ -54,7 +54,7 @@
       err(1, "failed to open header '%s'", file_path);
     }
 
-    auto buffer_opt = llvm::MemoryBuffer::getOpenFileSlice(fd, file_path, -1, 0);
+    auto buffer_opt = llvm::MemoryBuffer::getOpenFile(fd, file_path, -1, false, false);
     if (!buffer_opt) {
       errx(1, "failed to map header '%s'", file_path);
     }