Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <gtest/gtest.h>
     18 
     19 #include <dlfcn.h>
     20 #include <elf.h>
     21 #include <errno.h>
     22 #include <fcntl.h>
     23 #include <inttypes.h>
     24 #include <stdio.h>
     25 #include <string.h>
     26 #include <unistd.h>
     27 
     28 #include <android/dlext.h>
     29 #include <android-base/file.h>
     30 #include <android-base/strings.h>
     31 
     32 #include <linux/memfd.h>
     33 #include <sys/mman.h>
     34 #include <sys/syscall.h>
     35 #include <sys/types.h>
     36 #include <sys/vfs.h>
     37 #include <sys/wait.h>
     38 
     39 #include <meminfo/procmeminfo.h>
     40 #include <procinfo/process_map.h>
     41 #include <ziparchive/zip_archive.h>
     42 
     43 #include "gtest_globals.h"
     44 #include "utils.h"
     45 #include "dlext_private.h"
     46 #include "dlfcn_symlink_support.h"
     47 
     48 #define ASSERT_DL_NOTNULL(ptr) \
     49     ASSERT_TRUE((ptr) != nullptr) << "dlerror: " << dlerror()
     50 
     51 #define ASSERT_DL_ZERO(i) \
     52     ASSERT_EQ(0, i) << "dlerror: " << dlerror()
     53 
     54 #define ASSERT_NOERROR(i) \
     55     ASSERT_NE(-1, i) << "errno: " << strerror(errno)
     56 
     57 #define ASSERT_SUBSTR(needle, haystack) \
     58     ASSERT_PRED_FORMAT2(::testing::IsSubstring, needle, haystack)
     59 
     60 
     61 typedef int (*fn)(void);
     62 constexpr const char* kLibName = "libdlext_test.so";
     63 constexpr const char* kLibNameRecursive = "libdlext_test_recursive.so";
     64 constexpr const char* kLibNameNoRelro = "libdlext_test_norelro.so";
     65 constexpr const char* kLibZipSimpleZip = "libdir/libatest_simple_zip.so";
     66 constexpr auto kLibSize = 1024 * 1024; // how much address space to reserve for it
     67 
     68 class DlExtTest : public ::testing::Test {
     69 protected:
     70   void SetUp() override {
     71     handle_ = nullptr;
     72     // verify that we don't have the library loaded already
     73     void* h = dlopen(kLibName, RTLD_NOW | RTLD_NOLOAD);
     74     ASSERT_TRUE(h == nullptr);
     75     h = dlopen(kLibNameNoRelro, RTLD_NOW | RTLD_NOLOAD);
     76     ASSERT_TRUE(h == nullptr);
     77     // call dlerror() to swallow the error, and check it was the one we wanted
     78     ASSERT_EQ(std::string("dlopen failed: library \"") + kLibNameNoRelro + "\" wasn't loaded and RTLD_NOLOAD prevented it", dlerror());
     79   }
     80 
     81   void TearDown() override {
     82     if (handle_ != nullptr) {
     83       ASSERT_DL_ZERO(dlclose(handle_));
     84     }
     85   }
     86 
     87   void* handle_;
     88 };
     89 
     90 TEST_F(DlExtTest, ExtInfoNull) {
     91   handle_ = android_dlopen_ext(kLibName, RTLD_NOW, nullptr);
     92   ASSERT_DL_NOTNULL(handle_);
     93   fn f = reinterpret_cast<fn>(dlsym(handle_, "getRandomNumber"));
     94   ASSERT_DL_NOTNULL(f);
     95   EXPECT_EQ(4, f());
     96 }
     97 
     98 TEST_F(DlExtTest, ExtInfoNoFlags) {
     99   android_dlextinfo extinfo;
    100   extinfo.flags = 0;
    101   handle_ = android_dlopen_ext(kLibName, RTLD_NOW, &extinfo);
    102   ASSERT_DL_NOTNULL(handle_);
    103   fn f = reinterpret_cast<fn>(dlsym(handle_, "getRandomNumber"));
    104   ASSERT_DL_NOTNULL(f);
    105   EXPECT_EQ(4, f());
    106 }
    107 
    108 TEST_F(DlExtTest, ExtInfoUseFd) {
    109   const std::string lib_path = GetTestlibRoot() + "/libdlext_test_fd/libdlext_test_fd.so";
    110 
    111   android_dlextinfo extinfo;
    112   extinfo.flags = ANDROID_DLEXT_USE_LIBRARY_FD;
    113   extinfo.library_fd = TEMP_FAILURE_RETRY(open(lib_path.c_str(), O_RDONLY | O_CLOEXEC));
    114   ASSERT_TRUE(extinfo.library_fd != -1);
    115   handle_ = android_dlopen_ext(lib_path.c_str(), RTLD_NOW, &extinfo);
    116   ASSERT_DL_NOTNULL(handle_);
    117   fn f = reinterpret_cast<fn>(dlsym(handle_, "getRandomNumber"));
    118   ASSERT_DL_NOTNULL(f);
    119   EXPECT_EQ(4, f());
    120 
    121   uint32_t* taxicab_number = reinterpret_cast<uint32_t*>(dlsym(handle_, "dlopen_testlib_taxicab_number"));
    122   ASSERT_DL_NOTNULL(taxicab_number);
    123   EXPECT_EQ(1729U, *taxicab_number);
    124 }
    125 
    126 TEST_F(DlExtTest, ExtInfoUseFdWithOffset) {
    127   const std::string lib_path = GetTestlibRoot() + "/libdlext_test_zip/libdlext_test_zip_zipaligned.zip";
    128 
    129   android_dlextinfo extinfo;
    130   extinfo.flags = ANDROID_DLEXT_USE_LIBRARY_FD | ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET;
    131   extinfo.library_fd = TEMP_FAILURE_RETRY(open(lib_path.c_str(), O_RDONLY | O_CLOEXEC));
    132 
    133   // Find the offset of the shared library in the zip.
    134   ZipArchiveHandle handle;
    135   ASSERT_EQ(0, OpenArchive(lib_path.c_str(), &handle));
    136   ZipEntry zip_entry;
    137   ZipString zip_name;
    138   zip_name.name = reinterpret_cast<const uint8_t*>(kLibZipSimpleZip);
    139   zip_name.name_length = strlen(kLibZipSimpleZip);
    140   ASSERT_EQ(0, FindEntry(handle, zip_name, &zip_entry));
    141   extinfo.library_fd_offset = zip_entry.offset;
    142   CloseArchive(handle);
    143 
    144   handle_ = android_dlopen_ext(lib_path.c_str(), RTLD_NOW, &extinfo);
    145   ASSERT_DL_NOTNULL(handle_);
    146 
    147   uint32_t* taxicab_number = reinterpret_cast<uint32_t*>(dlsym(handle_, "dlopen_testlib_taxicab_number"));
    148   ASSERT_DL_NOTNULL(taxicab_number);
    149   EXPECT_EQ(1729U, *taxicab_number);
    150 }
    151 
    152 TEST_F(DlExtTest, ExtInfoUseFdWithInvalidOffset) {
    153   const std::string lib_path = GetTestlibRoot() + "/libdlext_test_zip/libdlext_test_zip_zipaligned.zip";
    154 
    155   android_dlextinfo extinfo;
    156   extinfo.flags = ANDROID_DLEXT_USE_LIBRARY_FD | ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET;
    157   extinfo.library_fd = TEMP_FAILURE_RETRY(open(lib_path.c_str(), O_RDONLY | O_CLOEXEC));
    158   extinfo.library_fd_offset = 17;
    159 
    160   handle_ = android_dlopen_ext("libname_placeholder", RTLD_NOW, &extinfo);
    161   ASSERT_TRUE(handle_ == nullptr);
    162   ASSERT_STREQ("dlopen failed: file offset for the library \"libname_placeholder\" is not page-aligned: 17", dlerror());
    163 
    164   // Test an address above 2^44, for http://b/18178121 .
    165   extinfo.library_fd_offset = (5LL<<48) + PAGE_SIZE;
    166   handle_ = android_dlopen_ext("libname_placeholder", RTLD_NOW, &extinfo);
    167   ASSERT_TRUE(handle_ == nullptr);
    168   ASSERT_SUBSTR("dlopen failed: file offset for the library \"libname_placeholder\" >= file size", dlerror());
    169 
    170   extinfo.library_fd_offset = 0LL - PAGE_SIZE;
    171   handle_ = android_dlopen_ext("libname_placeholder", RTLD_NOW, &extinfo);
    172   ASSERT_TRUE(handle_ == nullptr);
    173   ASSERT_SUBSTR("dlopen failed: file offset for the library \"libname_placeholder\" is negative", dlerror());
    174 
    175   extinfo.library_fd_offset = 0;
    176   handle_ = android_dlopen_ext("libname_ignored", RTLD_NOW, &extinfo);
    177   ASSERT_TRUE(handle_ == nullptr);
    178   ASSERT_EQ("dlopen failed: \"" + lib_path + "\" has bad ELF magic: 504b0304", dlerror());
    179 
    180   // Check if dlsym works after unsuccessful dlopen().
    181   // Supply non-exiting one to make linker visit every soinfo.
    182   void* sym = dlsym(RTLD_DEFAULT, "this_symbol_does_not_exist___");
    183   ASSERT_TRUE(sym == nullptr);
    184 
    185   close(extinfo.library_fd);
    186 }
    187 
    188 TEST_F(DlExtTest, ExtInfoUseOffsetWithoutFd) {
    189   android_dlextinfo extinfo;
    190   extinfo.flags = ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET;
    191   // This offset will not be used, so it doesn't matter.
    192   extinfo.library_fd_offset = 0;
    193 
    194   handle_ = android_dlopen_ext("/some/lib/that/does_not_exist", RTLD_NOW, &extinfo);
    195   ASSERT_TRUE(handle_ == nullptr);
    196   ASSERT_STREQ("dlopen failed: invalid extended flag combination (ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET without ANDROID_DLEXT_USE_LIBRARY_FD): 0x20", dlerror());
    197 }
    198 
    199 TEST(dlext, android_dlopen_ext_force_load_smoke) {
    200   DlfcnSymlink symlink("android_dlopen_ext_force_load_smoke");
    201   const std::string symlink_name = basename(symlink.get_symlink_path().c_str());
    202   // 1. Open actual file
    203   void* handle = dlopen("libdlext_test.so", RTLD_NOW);
    204   ASSERT_DL_NOTNULL(handle);
    205   // 2. Open link with force_load flag set
    206   android_dlextinfo extinfo;
    207   extinfo.flags = ANDROID_DLEXT_FORCE_LOAD;
    208   void* handle2 = android_dlopen_ext(symlink_name.c_str(), RTLD_NOW, &extinfo);
    209   ASSERT_DL_NOTNULL(handle2);
    210   ASSERT_TRUE(handle != handle2);
    211 
    212   dlclose(handle2);
    213   dlclose(handle);
    214 }
    215 
    216 TEST(dlext, android_dlopen_ext_force_load_soname_exception) {
    217   DlfcnSymlink symlink("android_dlopen_ext_force_load_soname_exception");
    218   const std::string symlink_name = basename(symlink.get_symlink_path().c_str());
    219   // Check if soname lookup still returns already loaded library
    220   // when ANDROID_DLEXT_FORCE_LOAD flag is specified.
    221   void* handle = dlopen(symlink_name.c_str(), RTLD_NOW);
    222   ASSERT_DL_NOTNULL(handle);
    223 
    224   android_dlextinfo extinfo;
    225   extinfo.flags = ANDROID_DLEXT_FORCE_LOAD;
    226 
    227   // Note that 'libdlext_test.so' is dt_soname for the symlink_name
    228   void* handle2 = android_dlopen_ext("libdlext_test.so", RTLD_NOW, &extinfo);
    229 
    230   ASSERT_DL_NOTNULL(handle2);
    231   ASSERT_TRUE(handle == handle2);
    232 
    233   dlclose(handle2);
    234   dlclose(handle);
    235 }
    236 
    237 TEST(dlfcn, dlopen_from_nullptr_android_api_level) {
    238   // Regression test for http://b/123972211. Testing dlopen(nullptr) when target sdk is P
    239   android_set_application_target_sdk_version(__ANDROID_API_P__);
    240   ASSERT_TRUE(dlopen(nullptr, RTLD_NOW) != nullptr);
    241 }
    242 
    243 TEST(dlfcn, dlopen_from_zip_absolute_path) {
    244   const std::string lib_zip_path = "/libdlext_test_zip/libdlext_test_zip_zipaligned.zip";
    245   const std::string lib_path = GetTestlibRoot() + lib_zip_path;
    246 
    247   void* handle = dlopen((lib_path + "!/libdir/libatest_simple_zip.so").c_str(), RTLD_NOW);
    248   ASSERT_TRUE(handle != nullptr) << dlerror();
    249 
    250   uint32_t* taxicab_number = reinterpret_cast<uint32_t*>(dlsym(handle, "dlopen_testlib_taxicab_number"));
    251   ASSERT_DL_NOTNULL(taxicab_number);
    252   EXPECT_EQ(1729U, *taxicab_number);
    253 
    254   dlclose(handle);
    255 }
    256 
    257 TEST(dlfcn, dlopen_from_zip_with_dt_runpath) {
    258   const std::string lib_zip_path = "/libdlext_test_runpath_zip/libdlext_test_runpath_zip_zipaligned.zip";
    259   const std::string lib_path = GetTestlibRoot() + lib_zip_path;
    260 
    261   void* handle = dlopen((lib_path + "!/libdir/libtest_dt_runpath_d_zip.so").c_str(), RTLD_NOW);
    262 
    263   ASSERT_TRUE(handle != nullptr) << dlerror();
    264 
    265   typedef void *(* dlopen_b_fn)();
    266   dlopen_b_fn fn = (dlopen_b_fn)dlsym(handle, "dlopen_b");
    267   ASSERT_TRUE(fn != nullptr) << dlerror();
    268 
    269   void *p = fn();
    270   ASSERT_TRUE(p != nullptr) << dlerror();
    271 
    272   dlclose(p);
    273   dlclose(handle);
    274 }
    275 
    276 TEST(dlfcn, dlopen_from_zip_ld_library_path) {
    277   const std::string lib_zip_path = "/libdlext_test_zip/libdlext_test_zip_zipaligned.zip";
    278   const std::string lib_path = GetTestlibRoot() + lib_zip_path + "!/libdir";
    279 
    280   typedef void (*fn_t)(const char*);
    281   fn_t android_update_LD_LIBRARY_PATH =
    282       reinterpret_cast<fn_t>(dlsym(RTLD_DEFAULT, "android_update_LD_LIBRARY_PATH"));
    283 
    284   ASSERT_TRUE(android_update_LD_LIBRARY_PATH != nullptr) << dlerror();
    285 
    286   void* handle = dlopen("libdlext_test_zip.so", RTLD_NOW);
    287   ASSERT_TRUE(handle == nullptr);
    288 
    289   android_update_LD_LIBRARY_PATH(lib_path.c_str());
    290 
    291   handle = dlopen("libdlext_test_zip.so", RTLD_NOW);
    292   ASSERT_TRUE(handle != nullptr) << dlerror();
    293 
    294   int (*fn)(void);
    295   fn = reinterpret_cast<int (*)(void)>(dlsym(handle, "getRandomNumber"));
    296   ASSERT_TRUE(fn != nullptr);
    297   EXPECT_EQ(4, fn());
    298 
    299   uint32_t* taxicab_number =
    300           reinterpret_cast<uint32_t*>(dlsym(handle, "dlopen_testlib_taxicab_number"));
    301   ASSERT_DL_NOTNULL(taxicab_number);
    302   EXPECT_EQ(1729U, *taxicab_number);
    303 
    304   dlclose(handle);
    305 }
    306 
    307 
    308 TEST_F(DlExtTest, Reserved) {
    309   void* start = mmap(nullptr, kLibSize, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    310   ASSERT_TRUE(start != MAP_FAILED);
    311   android_dlextinfo extinfo;
    312   extinfo.flags = ANDROID_DLEXT_RESERVED_ADDRESS;
    313   extinfo.reserved_addr = start;
    314   extinfo.reserved_size = kLibSize;
    315   handle_ = android_dlopen_ext(kLibName, RTLD_NOW, &extinfo);
    316   ASSERT_DL_NOTNULL(handle_);
    317   fn f = reinterpret_cast<fn>(dlsym(handle_, "getRandomNumber"));
    318   ASSERT_DL_NOTNULL(f);
    319   EXPECT_GE(reinterpret_cast<void*>(f), start);
    320   EXPECT_LT(reinterpret_cast<void*>(f),
    321             reinterpret_cast<char*>(start) + kLibSize);
    322   EXPECT_EQ(4, f());
    323 
    324   // Check that after dlclose reserved address space is unmapped (and can be reused)
    325   dlclose(handle_);
    326   handle_ = nullptr;
    327 
    328   void* new_start = mmap(start, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    329   ASSERT_NE(start, new_start) << "dlclose unmapped reserved space";
    330 }
    331 
    332 TEST_F(DlExtTest, ReservedTooSmall) {
    333   void* start = mmap(nullptr, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    334   ASSERT_TRUE(start != MAP_FAILED);
    335   android_dlextinfo extinfo;
    336   extinfo.flags = ANDROID_DLEXT_RESERVED_ADDRESS;
    337   extinfo.reserved_addr = start;
    338   extinfo.reserved_size = PAGE_SIZE;
    339   handle_ = android_dlopen_ext(kLibName, RTLD_NOW, &extinfo);
    340   EXPECT_EQ(nullptr, handle_);
    341 }
    342 
    343 TEST_F(DlExtTest, ReservedRecursive) {
    344   void* start = mmap(nullptr, kLibSize, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    345   ASSERT_TRUE(start != MAP_FAILED);
    346   android_dlextinfo extinfo;
    347   extinfo.flags = ANDROID_DLEXT_RESERVED_ADDRESS | ANDROID_DLEXT_RESERVED_ADDRESS_RECURSIVE;
    348   extinfo.reserved_addr = start;
    349   extinfo.reserved_size = kLibSize;
    350   handle_ = android_dlopen_ext(kLibNameRecursive, RTLD_NOW, &extinfo);
    351   ASSERT_DL_NOTNULL(handle_);
    352 
    353   fn f = reinterpret_cast<fn>(dlsym(handle_, "getRandomNumber"));
    354   ASSERT_DL_NOTNULL(f);
    355   EXPECT_GE(reinterpret_cast<void*>(f), start);
    356   EXPECT_LT(reinterpret_cast<void*>(f),
    357             reinterpret_cast<char*>(start) + kLibSize);
    358   EXPECT_EQ(4, f());
    359 
    360   f = reinterpret_cast<fn>(dlsym(handle_, "getBiggerRandomNumber"));
    361   ASSERT_DL_NOTNULL(f);
    362   EXPECT_GE(reinterpret_cast<void*>(f), start);
    363   EXPECT_LT(reinterpret_cast<void*>(f),
    364             reinterpret_cast<char*>(start) + kLibSize);
    365   EXPECT_EQ(8, f());
    366 
    367   uint32_t* taxicab_number = reinterpret_cast<uint32_t*>(dlsym(handle_, "dlopen_testlib_taxicab_number"));
    368   ASSERT_DL_NOTNULL(taxicab_number);
    369   EXPECT_GE(reinterpret_cast<void*>(taxicab_number), start);
    370   EXPECT_LT(reinterpret_cast<void*>(taxicab_number), reinterpret_cast<char*>(start) + kLibSize);
    371   EXPECT_EQ(1729U, *taxicab_number);
    372 }
    373 
    374 TEST_F(DlExtTest, ReservedRecursiveTooSmall) {
    375   void* start = mmap(nullptr, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    376   ASSERT_TRUE(start != MAP_FAILED);
    377   android_dlextinfo extinfo;
    378   extinfo.flags = ANDROID_DLEXT_RESERVED_ADDRESS | ANDROID_DLEXT_RESERVED_ADDRESS_RECURSIVE;
    379   extinfo.reserved_addr = start;
    380   extinfo.reserved_size = PAGE_SIZE;
    381   handle_ = android_dlopen_ext(kLibNameRecursive, RTLD_NOW, &extinfo);
    382   EXPECT_EQ(nullptr, handle_);
    383 }
    384 
    385 TEST_F(DlExtTest, ReservedHint) {
    386   void* start = mmap(nullptr, kLibSize, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    387   ASSERT_TRUE(start != MAP_FAILED);
    388   android_dlextinfo extinfo;
    389   extinfo.flags = ANDROID_DLEXT_RESERVED_ADDRESS_HINT;
    390   extinfo.reserved_addr = start;
    391   extinfo.reserved_size = kLibSize;
    392   handle_ = android_dlopen_ext(kLibName, RTLD_NOW, &extinfo);
    393   ASSERT_DL_NOTNULL(handle_);
    394   fn f = reinterpret_cast<fn>(dlsym(handle_, "getRandomNumber"));
    395   ASSERT_DL_NOTNULL(f);
    396   EXPECT_GE(reinterpret_cast<void*>(f), start);
    397   EXPECT_LT(reinterpret_cast<void*>(f),
    398             reinterpret_cast<char*>(start) + kLibSize);
    399   EXPECT_EQ(4, f());
    400 }
    401 
    402 TEST_F(DlExtTest, ReservedHintTooSmall) {
    403   void* start = mmap(nullptr, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    404   ASSERT_TRUE(start != MAP_FAILED);
    405   android_dlextinfo extinfo;
    406   extinfo.flags = ANDROID_DLEXT_RESERVED_ADDRESS_HINT;
    407   extinfo.reserved_addr = start;
    408   extinfo.reserved_size = PAGE_SIZE;
    409   handle_ = android_dlopen_ext(kLibName, RTLD_NOW, &extinfo);
    410   ASSERT_DL_NOTNULL(handle_);
    411   fn f = reinterpret_cast<fn>(dlsym(handle_, "getRandomNumber"));
    412   ASSERT_DL_NOTNULL(f);
    413   EXPECT_TRUE(reinterpret_cast<void*>(f) < start ||
    414               (reinterpret_cast<void*>(f) >=
    415                reinterpret_cast<char*>(start) + PAGE_SIZE));
    416   EXPECT_EQ(4, f());
    417 }
    418 
    419 class DlExtRelroSharingTest : public DlExtTest {
    420 protected:
    421   void SetUp() override {
    422     DlExtTest::SetUp();
    423     void* start = mmap(nullptr, kLibSize, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    424     ASSERT_TRUE(start != MAP_FAILED);
    425     extinfo_.flags = ANDROID_DLEXT_RESERVED_ADDRESS;
    426     extinfo_.reserved_addr = start;
    427     extinfo_.reserved_size = kLibSize;
    428     extinfo_.relro_fd = -1;
    429   }
    430 
    431   void TearDown() override {
    432     DlExtTest::TearDown();
    433   }
    434 
    435   void CreateRelroFile(const char* lib, const char* relro_file, bool recursive) {
    436     int relro_fd = open(relro_file, O_RDWR | O_TRUNC | O_CLOEXEC);
    437     ASSERT_NOERROR(relro_fd);
    438 
    439     if (recursive) {
    440       extinfo_.flags |= ANDROID_DLEXT_RESERVED_ADDRESS_RECURSIVE;
    441     }
    442 
    443     pid_t pid = fork();
    444     if (pid == 0) {
    445       // child process
    446       extinfo_.flags |= ANDROID_DLEXT_WRITE_RELRO;
    447       extinfo_.relro_fd = relro_fd;
    448       void* handle = android_dlopen_ext(lib, RTLD_NOW, &extinfo_);
    449       if (handle == nullptr) {
    450         fprintf(stderr, "in child: %s\n", dlerror());
    451         exit(1);
    452       }
    453       fn f = reinterpret_cast<fn>(dlsym(handle, "getRandomNumber"));
    454       ASSERT_DL_NOTNULL(f);
    455       EXPECT_EQ(4, f());
    456 
    457       if (recursive) {
    458         fn f = reinterpret_cast<fn>(dlsym(handle, "getBiggerRandomNumber"));
    459         ASSERT_DL_NOTNULL(f);
    460         EXPECT_EQ(8, f());
    461       }
    462 
    463       uint32_t* taxicab_number =
    464               reinterpret_cast<uint32_t*>(dlsym(handle, "dlopen_testlib_taxicab_number"));
    465       ASSERT_DL_NOTNULL(taxicab_number);
    466       EXPECT_EQ(1729U, *taxicab_number);
    467       exit(testing::Test::HasFailure());
    468     }
    469 
    470     // continuing in parent
    471     ASSERT_NOERROR(close(relro_fd));
    472     ASSERT_NOERROR(pid);
    473     AssertChildExited(pid, 0);
    474 
    475     // reopen file for reading so it can be used
    476     relro_fd = open(relro_file, O_RDONLY | O_CLOEXEC);
    477     ASSERT_NOERROR(relro_fd);
    478     extinfo_.flags |= ANDROID_DLEXT_USE_RELRO;
    479     extinfo_.relro_fd = relro_fd;
    480   }
    481 
    482   void TryUsingRelro(const char* lib, bool recursive) {
    483     handle_ = android_dlopen_ext(lib, RTLD_NOW, &extinfo_);
    484     ASSERT_DL_NOTNULL(handle_);
    485     fn f = reinterpret_cast<fn>(dlsym(handle_, "getRandomNumber"));
    486     ASSERT_DL_NOTNULL(f);
    487     EXPECT_EQ(4, f());
    488 
    489     if (recursive) {
    490       fn f = reinterpret_cast<fn>(dlsym(handle_, "getBiggerRandomNumber"));
    491       ASSERT_DL_NOTNULL(f);
    492       EXPECT_EQ(8, f());
    493     }
    494 
    495     uint32_t* taxicab_number =
    496             reinterpret_cast<uint32_t*>(dlsym(handle_, "dlopen_testlib_taxicab_number"));
    497     ASSERT_DL_NOTNULL(taxicab_number);
    498     EXPECT_EQ(1729U, *taxicab_number);
    499   }
    500 
    501   void SpawnChildrenAndMeasurePss(const char* lib, const char* relro_file, bool share_relro,
    502                                   size_t* pss_out);
    503 
    504   std::string FindMappingName(void* ptr);
    505 
    506   android_dlextinfo extinfo_;
    507 };
    508 
    509 TEST_F(DlExtRelroSharingTest, ChildWritesGoodData) {
    510   TemporaryFile tf; // Use tf to get an unique filename.
    511   ASSERT_NOERROR(close(tf.fd));
    512 
    513   ASSERT_NO_FATAL_FAILURE(CreateRelroFile(kLibName, tf.path, false));
    514   ASSERT_NO_FATAL_FAILURE(TryUsingRelro(kLibName, false));
    515   void* relro_data = dlsym(handle_, "lots_of_relro");
    516   ASSERT_DL_NOTNULL(relro_data);
    517   EXPECT_EQ(tf.path, FindMappingName(relro_data));
    518 
    519   // Use destructor of tf to close and unlink the file.
    520   tf.fd = extinfo_.relro_fd;
    521 }
    522 
    523 TEST_F(DlExtRelroSharingTest, ChildWritesGoodDataRecursive) {
    524   TemporaryFile tf; // Use tf to get an unique filename.
    525   ASSERT_NOERROR(close(tf.fd));
    526 
    527   ASSERT_NO_FATAL_FAILURE(CreateRelroFile(kLibNameRecursive, tf.path, true));
    528   ASSERT_NO_FATAL_FAILURE(TryUsingRelro(kLibNameRecursive, true));
    529   void* relro_data = dlsym(handle_, "lots_of_relro");
    530   ASSERT_DL_NOTNULL(relro_data);
    531   EXPECT_EQ(tf.path, FindMappingName(relro_data));
    532   void* recursive_relro_data = dlsym(handle_, "lots_more_relro");
    533   ASSERT_DL_NOTNULL(recursive_relro_data);
    534   EXPECT_EQ(tf.path, FindMappingName(recursive_relro_data));
    535 
    536 
    537   // Use destructor of tf to close and unlink the file.
    538   tf.fd = extinfo_.relro_fd;
    539 }
    540 
    541 TEST_F(DlExtRelroSharingTest, CheckRelroSizes) {
    542   TemporaryFile tf1, tf2;
    543   ASSERT_NOERROR(close(tf1.fd));
    544   ASSERT_NOERROR(close(tf2.fd));
    545 
    546   ASSERT_NO_FATAL_FAILURE(CreateRelroFile(kLibNameRecursive, tf1.path, false));
    547   struct stat no_recursive;
    548   ASSERT_NOERROR(fstat(extinfo_.relro_fd, &no_recursive));
    549   tf1.fd = extinfo_.relro_fd;
    550 
    551   ASSERT_NO_FATAL_FAILURE(CreateRelroFile(kLibNameRecursive, tf2.path, true));
    552   struct stat with_recursive;
    553   ASSERT_NOERROR(fstat(extinfo_.relro_fd, &with_recursive));
    554   tf2.fd = extinfo_.relro_fd;
    555 
    556   // RELRO file should end up bigger when we use the recursive flag, since it
    557   // includes data for more than one library.
    558   ASSERT_GT(with_recursive.st_size, no_recursive.st_size);
    559 }
    560 
    561 TEST_F(DlExtRelroSharingTest, ChildWritesNoRelro) {
    562   TemporaryFile tf; // // Use tf to get an unique filename.
    563   ASSERT_NOERROR(close(tf.fd));
    564 
    565   ASSERT_NO_FATAL_FAILURE(CreateRelroFile(kLibNameNoRelro, tf.path, false));
    566   ASSERT_NO_FATAL_FAILURE(TryUsingRelro(kLibNameNoRelro, false));
    567 
    568   // Use destructor of tf to close and unlink the file.
    569   tf.fd = extinfo_.relro_fd;
    570 }
    571 
    572 TEST_F(DlExtRelroSharingTest, RelroFileEmpty) {
    573   ASSERT_NO_FATAL_FAILURE(TryUsingRelro(kLibName, false));
    574 }
    575 
    576 TEST_F(DlExtRelroSharingTest, VerifyMemorySaving) {
    577   if (geteuid() != 0) GTEST_SKIP() << "This test must be run as root";
    578 
    579   TemporaryFile tf; // Use tf to get an unique filename.
    580   ASSERT_NOERROR(close(tf.fd));
    581 
    582   ASSERT_NO_FATAL_FAILURE(CreateRelroFile(kLibName, tf.path, false));
    583 
    584   int pipefd[2];
    585   ASSERT_NOERROR(pipe(pipefd));
    586 
    587   size_t without_sharing, with_sharing;
    588   ASSERT_NO_FATAL_FAILURE(SpawnChildrenAndMeasurePss(kLibName, tf.path, false, &without_sharing));
    589   ASSERT_NO_FATAL_FAILURE(SpawnChildrenAndMeasurePss(kLibName, tf.path, true, &with_sharing));
    590   ASSERT_LT(with_sharing, without_sharing);
    591 
    592   // We expect the sharing to save at least 50% of the library's total PSS.
    593   // In practice it saves 80%+ for this library in the test.
    594   size_t pss_saved = without_sharing - with_sharing;
    595   size_t expected_min_saved = without_sharing / 2;
    596 
    597   EXPECT_LT(expected_min_saved, pss_saved);
    598 
    599   // Use destructor of tf to close and unlink the file.
    600   tf.fd = extinfo_.relro_fd;
    601 }
    602 
    603 void GetPss(bool shared_relro, const char* lib, const char* relro_file, pid_t pid,
    604             size_t* total_pss) {
    605   android::meminfo::ProcMemInfo proc_mem(pid);
    606   const std::vector<android::meminfo::Vma>& maps = proc_mem.Maps();
    607   ASSERT_GT(maps.size(), 0UL);
    608 
    609   // Calculate total PSS of the library.
    610   *total_pss = 0;
    611   bool saw_relro_file = false;
    612   for (auto& vma : maps) {
    613     if (android::base::EndsWith(vma.name, lib) || (vma.name == relro_file)) {
    614       if (vma.name == relro_file) {
    615           saw_relro_file = true;
    616       }
    617 
    618       *total_pss += vma.usage.pss;
    619     }
    620   }
    621 
    622   if (shared_relro) ASSERT_TRUE(saw_relro_file);
    623 }
    624 
    625 void DlExtRelroSharingTest::SpawnChildrenAndMeasurePss(const char* lib, const char* relro_file,
    626                                                        bool share_relro, size_t* pss_out) {
    627   const int CHILDREN = 20;
    628 
    629   // Create children
    630   pid_t child_pids[CHILDREN];
    631   int childpipe[CHILDREN];
    632   for (int i=0; i<CHILDREN; ++i) {
    633     char read_buf;
    634     int child_done_pipe[2], parent_done_pipe[2];
    635     ASSERT_NOERROR(pipe(child_done_pipe));
    636     ASSERT_NOERROR(pipe(parent_done_pipe));
    637 
    638     pid_t child = fork();
    639     if (child == 0) {
    640       // close the 'wrong' ends of the pipes in the child
    641       close(child_done_pipe[0]);
    642       close(parent_done_pipe[1]);
    643 
    644       // open the library
    645       void* handle;
    646       if (share_relro) {
    647         handle = android_dlopen_ext(lib, RTLD_NOW, &extinfo_);
    648       } else {
    649         handle = dlopen(lib, RTLD_NOW);
    650       }
    651       if (handle == nullptr) {
    652         fprintf(stderr, "in child: %s\n", dlerror());
    653         exit(1);
    654       }
    655 
    656       // close write end of child_done_pipe to signal the parent that we're done.
    657       close(child_done_pipe[1]);
    658 
    659       // wait for the parent to close parent_done_pipe, then exit
    660       read(parent_done_pipe[0], &read_buf, 1);
    661       exit(0);
    662     }
    663 
    664     ASSERT_NOERROR(child);
    665 
    666     // close the 'wrong' ends of the pipes in the parent
    667     close(child_done_pipe[1]);
    668     close(parent_done_pipe[0]);
    669 
    670     // wait for the child to be done
    671     read(child_done_pipe[0], &read_buf, 1);
    672     close(child_done_pipe[0]);
    673 
    674     // save the child's pid and the parent_done_pipe
    675     child_pids[i] = child;
    676     childpipe[i] = parent_done_pipe[1];
    677   }
    678 
    679   // Sum the PSS of tested library of all the children
    680   size_t total_pss = 0;
    681   for (int i=0; i<CHILDREN; ++i) {
    682     size_t child_pss;
    683     ASSERT_NO_FATAL_FAILURE(GetPss(share_relro, lib, relro_file, child_pids[i], &child_pss));
    684     total_pss += child_pss;
    685   }
    686   *pss_out = total_pss;
    687 
    688   // Close pipes and wait for children to exit
    689   for (int i=0; i<CHILDREN; ++i) {
    690     ASSERT_NOERROR(close(childpipe[i]));
    691   }
    692   for (int i = 0; i < CHILDREN; ++i) {
    693     AssertChildExited(child_pids[i], 0);
    694   }
    695 }
    696 
    697 std::string DlExtRelroSharingTest::FindMappingName(void* ptr) {
    698   uint64_t addr = reinterpret_cast<uint64_t>(ptr);
    699   std::string found_name = "<not found>";
    700 
    701   EXPECT_TRUE(android::procinfo::ReadMapFile(
    702       "/proc/self/maps",
    703       [&](uint64_t start, uint64_t end, uint16_t, uint16_t, ino_t, const char* name) {
    704         if (addr >= start && addr < end) {
    705           found_name = name;
    706         }
    707       }));
    708 
    709   return found_name;
    710 }
    711 
    712 // Testing namespaces
    713 static const char* g_public_lib = "libnstest_public.so";
    714 
    715 // These are libs shared with default namespace
    716 static const std::string g_core_shared_libs = "libc.so:libc++.so:libdl.so:libm.so";
    717 
    718 TEST(dlext, ns_smoke) {
    719   static const char* root_lib = "libnstest_root.so";
    720   std::string shared_libs = g_core_shared_libs + ":" + g_public_lib;
    721 
    722   ASSERT_FALSE(android_init_anonymous_namespace("", nullptr));
    723   ASSERT_STREQ("android_init_anonymous_namespace failed: error linking namespaces"
    724                " \"(anonymous)\"->\"(default)\": the list of shared libraries is empty.",
    725                dlerror());
    726 
    727   const std::string lib_public_path = GetTestlibRoot() + "/public_namespace_libs/" + g_public_lib;
    728   void* handle_public = dlopen(lib_public_path.c_str(), RTLD_NOW);
    729   ASSERT_TRUE(handle_public != nullptr) << dlerror();
    730 
    731   ASSERT_TRUE(android_init_anonymous_namespace(shared_libs.c_str(), nullptr)) << dlerror();
    732 
    733   // Check that libraries added to public namespace are not NODELETE
    734   dlclose(handle_public);
    735   handle_public = dlopen(lib_public_path.c_str(), RTLD_NOW | RTLD_NOLOAD);
    736   ASSERT_TRUE(handle_public == nullptr);
    737   ASSERT_EQ(std::string("dlopen failed: library \"") + lib_public_path +
    738                "\" wasn't loaded and RTLD_NOLOAD prevented it", dlerror());
    739 
    740   handle_public = dlopen(lib_public_path.c_str(), RTLD_NOW);
    741 
    742   // create "public namespace", share limited set of public libraries with
    743 
    744   android_namespace_t* ns1 =
    745           android_create_namespace("private",
    746                                    nullptr,
    747                                    (GetTestlibRoot() + "/private_namespace_libs").c_str(),
    748                                    ANDROID_NAMESPACE_TYPE_REGULAR,
    749                                    nullptr,
    750                                    nullptr);
    751   ASSERT_TRUE(ns1 != nullptr) << dlerror();
    752   ASSERT_TRUE(android_link_namespaces(ns1, nullptr, shared_libs.c_str())) << dlerror();
    753 
    754   android_namespace_t* ns2 =
    755           android_create_namespace("private_isolated",
    756                                    nullptr,
    757                                    (GetTestlibRoot() + "/private_namespace_libs").c_str(),
    758                                    ANDROID_NAMESPACE_TYPE_ISOLATED,
    759                                    nullptr,
    760                                    nullptr);
    761   ASSERT_TRUE(ns2 != nullptr) << dlerror();
    762   ASSERT_TRUE(android_link_namespaces(ns2, nullptr, shared_libs.c_str())) << dlerror();
    763 
    764   // This should not have affect search path for default namespace:
    765   ASSERT_TRUE(dlopen(root_lib, RTLD_NOW) == nullptr);
    766   void* handle = dlopen(g_public_lib, RTLD_NOW);
    767   ASSERT_TRUE(handle != nullptr) << dlerror();
    768   dlclose(handle);
    769 
    770   // dlopen for a public library using an absolute path should work
    771   // 1. For isolated namespaces
    772   android_dlextinfo extinfo;
    773   extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
    774   extinfo.library_namespace = ns2;
    775   handle = android_dlopen_ext(lib_public_path.c_str(), RTLD_NOW, &extinfo);
    776   ASSERT_TRUE(handle != nullptr) << dlerror();
    777   ASSERT_TRUE(handle == handle_public);
    778 
    779   dlclose(handle);
    780 
    781   // 1.1 even if it wasn't loaded before
    782   dlclose(handle_public);
    783 
    784   handle_public = dlopen(lib_public_path.c_str(), RTLD_NOW | RTLD_NOLOAD);
    785   ASSERT_TRUE(handle_public == nullptr);
    786   ASSERT_EQ(std::string("dlopen failed: library \"") + lib_public_path +
    787                "\" wasn't loaded and RTLD_NOLOAD prevented it", dlerror());
    788 
    789   handle = android_dlopen_ext(lib_public_path.c_str(), RTLD_NOW, &extinfo);
    790   ASSERT_TRUE(handle != nullptr) << dlerror();
    791 
    792   handle_public = dlopen(lib_public_path.c_str(), RTLD_NOW);
    793   ASSERT_TRUE(handle == handle_public);
    794 
    795   dlclose(handle);
    796 
    797   // 2. And for regular namespaces (make sure it does not load second copy of the library)
    798   extinfo.library_namespace = ns1;
    799   handle = android_dlopen_ext(lib_public_path.c_str(), RTLD_NOW, &extinfo);
    800   ASSERT_TRUE(handle != nullptr) << dlerror();
    801   ASSERT_TRUE(handle == handle_public);
    802 
    803   dlclose(handle);
    804 
    805   // 2.1 Unless it was not loaded before - in which case it will load a duplicate.
    806   // TODO(dimitry): This is broken. Maybe we need to deprecate non-isolated namespaces?
    807   dlclose(handle_public);
    808 
    809   handle_public = dlopen(lib_public_path.c_str(), RTLD_NOW | RTLD_NOLOAD);
    810   ASSERT_TRUE(handle_public == nullptr);
    811   ASSERT_EQ(std::string("dlopen failed: library \"") + lib_public_path +
    812                "\" wasn't loaded and RTLD_NOLOAD prevented it", dlerror());
    813 
    814   handle = android_dlopen_ext(lib_public_path.c_str(), RTLD_NOW, &extinfo);
    815   ASSERT_TRUE(handle != nullptr) << dlerror();
    816 
    817   handle_public = dlopen(lib_public_path.c_str(), RTLD_NOW);
    818 
    819   ASSERT_TRUE(handle != handle_public);
    820 
    821   dlclose(handle);
    822 
    823   extinfo.library_namespace = ns1;
    824 
    825   void* handle1 = android_dlopen_ext(root_lib, RTLD_NOW, &extinfo);
    826   ASSERT_TRUE(handle1 != nullptr) << dlerror();
    827 
    828   extinfo.library_namespace = ns2;
    829   void* handle2 = android_dlopen_ext(root_lib, RTLD_NOW, &extinfo);
    830   ASSERT_TRUE(handle2 != nullptr) << dlerror();
    831 
    832   ASSERT_TRUE(handle1 != handle2);
    833 
    834   typedef const char* (*fn_t)();
    835 
    836   fn_t ns_get_local_string1 = reinterpret_cast<fn_t>(dlsym(handle1, "ns_get_local_string"));
    837   ASSERT_TRUE(ns_get_local_string1 != nullptr) << dlerror();
    838   fn_t ns_get_local_string2 = reinterpret_cast<fn_t>(dlsym(handle2, "ns_get_local_string"));
    839   ASSERT_TRUE(ns_get_local_string2 != nullptr) << dlerror();
    840 
    841   EXPECT_STREQ("This string is local to root library", ns_get_local_string1());
    842   EXPECT_STREQ("This string is local to root library", ns_get_local_string2());
    843 
    844   ASSERT_TRUE(ns_get_local_string1() != ns_get_local_string2());
    845 
    846   fn_t ns_get_private_extern_string1 =
    847           reinterpret_cast<fn_t>(dlsym(handle1, "ns_get_private_extern_string"));
    848   ASSERT_TRUE(ns_get_private_extern_string1 != nullptr) << dlerror();
    849   fn_t ns_get_private_extern_string2 =
    850           reinterpret_cast<fn_t>(dlsym(handle2, "ns_get_private_extern_string"));
    851   ASSERT_TRUE(ns_get_private_extern_string2 != nullptr) << dlerror();
    852 
    853   EXPECT_STREQ("This string is from private namespace", ns_get_private_extern_string1());
    854   EXPECT_STREQ("This string is from private namespace", ns_get_private_extern_string2());
    855 
    856   ASSERT_TRUE(ns_get_private_extern_string1() != ns_get_private_extern_string2());
    857 
    858   fn_t ns_get_public_extern_string1 =
    859           reinterpret_cast<fn_t>(dlsym(handle1, "ns_get_public_extern_string"));
    860   ASSERT_TRUE(ns_get_public_extern_string1 != nullptr) << dlerror();
    861   fn_t ns_get_public_extern_string2 =
    862           reinterpret_cast<fn_t>(dlsym(handle2, "ns_get_public_extern_string"));
    863   ASSERT_TRUE(ns_get_public_extern_string2 != nullptr) << dlerror();
    864 
    865   EXPECT_STREQ("This string is from public namespace", ns_get_public_extern_string1());
    866   ASSERT_TRUE(ns_get_public_extern_string1() == ns_get_public_extern_string2());
    867 
    868   // and now check that dlopen() does the right thing in terms of preserving namespace
    869   fn_t ns_get_dlopened_string1 = reinterpret_cast<fn_t>(dlsym(handle1, "ns_get_dlopened_string"));
    870   ASSERT_TRUE(ns_get_dlopened_string1 != nullptr) << dlerror();
    871   fn_t ns_get_dlopened_string2 = reinterpret_cast<fn_t>(dlsym(handle2, "ns_get_dlopened_string"));
    872   ASSERT_TRUE(ns_get_dlopened_string2 != nullptr) << dlerror();
    873 
    874   EXPECT_STREQ("This string is from private namespace (dlopened library)", ns_get_dlopened_string1());
    875   EXPECT_STREQ("This string is from private namespace (dlopened library)", ns_get_dlopened_string2());
    876 
    877   ASSERT_TRUE(ns_get_dlopened_string1() != ns_get_dlopened_string2());
    878 
    879   // Check that symbols from non-shared libraries a shared library depends on are not visible
    880   // from original namespace.
    881 
    882   fn_t ns_get_internal_extern_string =
    883           reinterpret_cast<fn_t>(dlsym(handle1, "ns_get_internal_extern_string"));
    884   ASSERT_TRUE(ns_get_internal_extern_string != nullptr) << dlerror();
    885   ASSERT_TRUE(ns_get_internal_extern_string() == nullptr) <<
    886       "ns_get_internal_extern_string() expected to return null but returns \"" <<
    887       ns_get_internal_extern_string() << "\"";
    888 
    889   dlclose(handle1);
    890 
    891   // Check if handle2 is still alive (and well)
    892   ASSERT_STREQ("This string is local to root library", ns_get_local_string2());
    893   ASSERT_STREQ("This string is from private namespace", ns_get_private_extern_string2());
    894   ASSERT_STREQ("This string is from public namespace", ns_get_public_extern_string2());
    895   ASSERT_STREQ("This string is from private namespace (dlopened library)", ns_get_dlopened_string2());
    896 
    897   dlclose(handle2);
    898 }
    899 
    900 TEST(dlext, dlopen_ext_use_o_tmpfile_fd) {
    901   const std::string lib_path = GetTestlibRoot() + "/libtest_simple.so";
    902 
    903   int tmpfd = TEMP_FAILURE_RETRY(
    904         open(GetTestlibRoot().c_str(), O_TMPFILE | O_CLOEXEC | O_RDWR | O_EXCL, 0));
    905 
    906   // Ignore kernels without O_TMPFILE flag support
    907   if (tmpfd == -1 && (errno == EISDIR || errno == EINVAL || errno == EOPNOTSUPP)) {
    908     return;
    909   }
    910 
    911   ASSERT_TRUE(tmpfd != -1) << strerror(errno);
    912 
    913   android_namespace_t* ns =
    914           android_create_namespace("testing-o_tmpfile",
    915                                    nullptr,
    916                                    GetTestlibRoot().c_str(),
    917                                    ANDROID_NAMESPACE_TYPE_ISOLATED,
    918                                    nullptr,
    919                                    nullptr);
    920 
    921   ASSERT_DL_NOTNULL(ns);
    922 
    923   ASSERT_TRUE(android_link_namespaces(ns, nullptr, g_core_shared_libs.c_str())) << dlerror();
    924 
    925   std::string content;
    926   ASSERT_TRUE(android::base::ReadFileToString(lib_path, &content)) << strerror(errno);
    927   ASSERT_TRUE(android::base::WriteStringToFd(content, tmpfd)) << strerror(errno);
    928 
    929   android_dlextinfo extinfo;
    930   extinfo.flags = ANDROID_DLEXT_USE_LIBRARY_FD | ANDROID_DLEXT_USE_NAMESPACE;
    931   extinfo.library_fd = tmpfd;
    932   extinfo.library_namespace = ns;
    933 
    934   void* handle = android_dlopen_ext("foobar", RTLD_NOW, &extinfo);
    935 
    936   ASSERT_DL_NOTNULL(handle);
    937 
    938   uint32_t* taxicab_number = reinterpret_cast<uint32_t*>(dlsym(handle, "dlopen_testlib_taxicab_number"));
    939   ASSERT_DL_NOTNULL(taxicab_number);
    940   EXPECT_EQ(1729U, *taxicab_number);
    941   dlclose(handle);
    942 }
    943 
    944 TEST(dlext, dlopen_ext_use_memfd) {
    945   const std::string lib_path = GetTestlibRoot() + "/libtest_simple.so";
    946 
    947   // create memfd
    948   int memfd = syscall(__NR_memfd_create, "foobar", MFD_CLOEXEC);
    949   if (memfd == -1 && errno == ENOSYS) {
    950     return;
    951   }
    952 
    953   ASSERT_TRUE(memfd != -1) << strerror(errno);
    954 
    955   // Check st.f_type is TMPFS_MAGIC for memfd
    956   struct statfs st;
    957   ASSERT_TRUE(TEMP_FAILURE_RETRY(fstatfs(memfd, &st)) == 0) << strerror(errno);
    958   ASSERT_EQ(static_cast<decltype(st.f_type)>(TMPFS_MAGIC), st.f_type);
    959 
    960   android_namespace_t* ns =
    961           android_create_namespace("testing-memfd",
    962                                    nullptr,
    963                                    GetTestlibRoot().c_str(),
    964                                    ANDROID_NAMESPACE_TYPE_ISOLATED,
    965                                    nullptr,
    966                                    nullptr);
    967 
    968   ASSERT_DL_NOTNULL(ns);
    969 
    970   ASSERT_TRUE(android_link_namespaces(ns, nullptr, g_core_shared_libs.c_str())) << dlerror();
    971 
    972   // read file into memfd backed one.
    973   std::string content;
    974   ASSERT_TRUE(android::base::ReadFileToString(lib_path, &content)) << strerror(errno);
    975   ASSERT_TRUE(android::base::WriteStringToFd(content, memfd)) << strerror(errno);
    976 
    977   android_dlextinfo extinfo;
    978   extinfo.flags = ANDROID_DLEXT_USE_LIBRARY_FD | ANDROID_DLEXT_USE_NAMESPACE;
    979   extinfo.library_fd = memfd;
    980   extinfo.library_namespace = ns;
    981 
    982   void* handle = android_dlopen_ext("foobar", RTLD_NOW, &extinfo);
    983 
    984   ASSERT_DL_NOTNULL(handle);
    985 
    986   uint32_t* taxicab_number = reinterpret_cast<uint32_t*>(dlsym(handle, "dlopen_testlib_taxicab_number"));
    987   ASSERT_DL_NOTNULL(taxicab_number);
    988   EXPECT_EQ(1729U, *taxicab_number);
    989   dlclose(handle);
    990 }
    991 
    992 TEST(dlext, ns_symbol_visibilty_one_namespace) {
    993   static const char* root_lib = "libnstest_root.so";
    994   ASSERT_TRUE(android_init_anonymous_namespace(g_core_shared_libs.c_str(), nullptr));
    995 
    996   const std::string ns_search_path = GetTestlibRoot() + "/public_namespace_libs:" +
    997                                      GetTestlibRoot() + "/private_namespace_libs";
    998 
    999   android_namespace_t* ns =
   1000           android_create_namespace("one",
   1001                                    nullptr,
   1002                                    ns_search_path.c_str(),
   1003                                    ANDROID_NAMESPACE_TYPE_ISOLATED,
   1004                                    nullptr,
   1005                                    nullptr);
   1006 
   1007   ASSERT_TRUE(android_link_namespaces(ns, nullptr, g_core_shared_libs.c_str())) << dlerror();
   1008 
   1009   android_dlextinfo extinfo;
   1010   extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
   1011   extinfo.library_namespace = ns;
   1012 
   1013   void* handle = android_dlopen_ext(root_lib, RTLD_NOW, &extinfo);
   1014   ASSERT_TRUE(handle != nullptr) << dlerror();
   1015 
   1016   typedef const char* (*fn_t)();
   1017 
   1018   // Check that relocation worked correctly
   1019   fn_t ns_get_internal_extern_string =
   1020           reinterpret_cast<fn_t>(dlsym(handle, "ns_get_internal_extern_string"));
   1021   ASSERT_TRUE(ns_get_internal_extern_string != nullptr) << dlerror();
   1022   ASSERT_STREQ("This string is from a library a shared library depends on", ns_get_internal_extern_string());
   1023 
   1024   fn_t internal_extern_string_fn =
   1025           reinterpret_cast<fn_t>(dlsym(handle, "internal_extern_string"));
   1026   ASSERT_TRUE(internal_extern_string_fn != nullptr) << dlerror();
   1027   ASSERT_STREQ("This string is from a library a shared library depends on", internal_extern_string_fn());
   1028 }
   1029 
   1030 TEST(dlext, ns_symbol_visibilty_between_namespaces) {
   1031   static const char* root_lib = "libnstest_root.so";
   1032   ASSERT_TRUE(android_init_anonymous_namespace(g_core_shared_libs.c_str(), nullptr));
   1033 
   1034   const std::string public_ns_search_path =  GetTestlibRoot() + "/public_namespace_libs";
   1035   const std::string private_ns_search_path = GetTestlibRoot() + "/private_namespace_libs";
   1036 
   1037   android_namespace_t* ns_public =
   1038           android_create_namespace("public",
   1039                                    nullptr,
   1040                                    public_ns_search_path.c_str(),
   1041                                    ANDROID_NAMESPACE_TYPE_ISOLATED,
   1042                                    nullptr,
   1043                                    nullptr);
   1044 
   1045   ASSERT_TRUE(android_link_namespaces(ns_public, nullptr, g_core_shared_libs.c_str())) << dlerror();
   1046 
   1047   android_namespace_t* ns_private =
   1048           android_create_namespace("private",
   1049                                    nullptr,
   1050                                    private_ns_search_path.c_str(),
   1051                                    ANDROID_NAMESPACE_TYPE_ISOLATED,
   1052                                    nullptr,
   1053                                    nullptr);
   1054 
   1055   ASSERT_TRUE(android_link_namespaces(ns_private, ns_public, g_public_lib)) << dlerror();
   1056   ASSERT_TRUE(android_link_namespaces(ns_private, nullptr, g_core_shared_libs.c_str())) << dlerror();
   1057 
   1058   android_dlextinfo extinfo;
   1059   extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
   1060   extinfo.library_namespace = ns_private;
   1061 
   1062   void* handle = android_dlopen_ext(root_lib, RTLD_NOW, &extinfo);
   1063   ASSERT_TRUE(handle != nullptr) << dlerror();
   1064 
   1065   typedef const char* (*fn_t)();
   1066 
   1067   // Check that relocation worked correctly
   1068   fn_t ns_get_internal_extern_string =
   1069           reinterpret_cast<fn_t>(dlsym(handle, "ns_get_internal_extern_string"));
   1070   ASSERT_TRUE(ns_get_internal_extern_string != nullptr) << dlerror();
   1071   ASSERT_TRUE(ns_get_internal_extern_string() == nullptr) <<
   1072       "ns_get_internal_extern_string() expected to return null but returns \"" <<
   1073       ns_get_internal_extern_string() << "\"";
   1074 
   1075   fn_t internal_extern_string_fn =
   1076           reinterpret_cast<fn_t>(dlsym(handle, "internal_extern_string"));
   1077   ASSERT_TRUE(internal_extern_string_fn == nullptr);
   1078   ASSERT_STREQ("undefined symbol: internal_extern_string", dlerror());
   1079 }
   1080 
   1081 TEST(dlext, ns_unload_between_namespaces) {
   1082   static const char* root_lib = "libnstest_root.so";
   1083   ASSERT_TRUE(android_init_anonymous_namespace(g_core_shared_libs.c_str(), nullptr));
   1084 
   1085   const std::string public_ns_search_path =  GetTestlibRoot() + "/public_namespace_libs";
   1086   const std::string private_ns_search_path = GetTestlibRoot() + "/private_namespace_libs";
   1087 
   1088   android_namespace_t* ns_public =
   1089           android_create_namespace("public",
   1090                                    nullptr,
   1091                                    public_ns_search_path.c_str(),
   1092                                    ANDROID_NAMESPACE_TYPE_ISOLATED,
   1093                                    nullptr,
   1094                                    nullptr);
   1095 
   1096   ASSERT_TRUE(android_link_namespaces(ns_public, nullptr, g_core_shared_libs.c_str())) << dlerror();
   1097 
   1098   android_namespace_t* ns_private =
   1099           android_create_namespace("private",
   1100                                    nullptr,
   1101                                    private_ns_search_path.c_str(),
   1102                                    ANDROID_NAMESPACE_TYPE_ISOLATED,
   1103                                    nullptr,
   1104                                    nullptr);
   1105 
   1106   ASSERT_TRUE(android_link_namespaces(ns_private, ns_public, g_public_lib)) << dlerror();
   1107   ASSERT_TRUE(android_link_namespaces(ns_private, nullptr, g_core_shared_libs.c_str())) << dlerror();
   1108 
   1109   android_dlextinfo extinfo;
   1110   extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
   1111   extinfo.library_namespace = ns_private;
   1112 
   1113   void* handle = android_dlopen_ext(root_lib, RTLD_NOW, &extinfo);
   1114   ASSERT_TRUE(handle != nullptr) << dlerror();
   1115 
   1116   dlclose(handle);
   1117   // Check that root_lib was unloaded
   1118   handle = android_dlopen_ext(root_lib, RTLD_NOW | RTLD_NOLOAD, &extinfo);
   1119   ASSERT_TRUE(handle == nullptr);
   1120   ASSERT_EQ(std::string("dlopen failed: library \"") + root_lib +
   1121             "\" wasn't loaded and RTLD_NOLOAD prevented it", dlerror());
   1122 
   1123   // Check that shared library was unloaded in public ns
   1124   extinfo.library_namespace = ns_public;
   1125   handle = android_dlopen_ext(g_public_lib, RTLD_NOW | RTLD_NOLOAD, &extinfo);
   1126   ASSERT_TRUE(handle == nullptr);
   1127   ASSERT_EQ(std::string("dlopen failed: library \"") + g_public_lib +
   1128             "\" wasn't loaded and RTLD_NOLOAD prevented it", dlerror());
   1129 }
   1130 
   1131 TEST(dlext, ns_unload_between_namespaces_missing_symbol_direct) {
   1132   ASSERT_TRUE(android_init_anonymous_namespace(g_core_shared_libs.c_str(), nullptr));
   1133 
   1134   const std::string public_ns_search_path =  GetTestlibRoot() + "/public_namespace_libs";
   1135   const std::string private_ns_search_path = GetTestlibRoot() + "/private_namespace_libs";
   1136 
   1137   android_namespace_t* ns_public =
   1138           android_create_namespace("public",
   1139                                    nullptr,
   1140                                    public_ns_search_path.c_str(),
   1141                                    ANDROID_NAMESPACE_TYPE_ISOLATED,
   1142                                    nullptr,
   1143                                    nullptr);
   1144 
   1145   ASSERT_TRUE(android_link_namespaces(ns_public, nullptr, g_core_shared_libs.c_str())) << dlerror();
   1146 
   1147   android_namespace_t* ns_private =
   1148           android_create_namespace("private",
   1149                                    nullptr,
   1150                                    private_ns_search_path.c_str(),
   1151                                    ANDROID_NAMESPACE_TYPE_ISOLATED,
   1152                                    nullptr,
   1153                                    nullptr);
   1154 
   1155   ASSERT_TRUE(android_link_namespaces(ns_private, ns_public, "libtest_missing_symbol.so")) << dlerror();
   1156   ASSERT_TRUE(android_link_namespaces(ns_private, nullptr, g_core_shared_libs.c_str())) << dlerror();
   1157 
   1158   android_dlextinfo extinfo;
   1159   extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
   1160   extinfo.library_namespace = ns_private;
   1161 
   1162   void* handle = android_dlopen_ext((public_ns_search_path + "/libtest_missing_symbol.so").c_str(),
   1163                                     RTLD_NOW,
   1164                                     &extinfo);
   1165   ASSERT_TRUE(handle == nullptr);
   1166   ASSERT_EQ(std::string("dlopen failed: cannot locate symbol \"dlopen_testlib_missing_symbol\" referenced by \"") +
   1167             public_ns_search_path + "/libtest_missing_symbol.so\"...",
   1168             dlerror());
   1169 }
   1170 
   1171 TEST(dlext, ns_unload_between_namespaces_missing_symbol_indirect) {
   1172   ASSERT_TRUE(android_init_anonymous_namespace(g_core_shared_libs.c_str(), nullptr));
   1173 
   1174   const std::string public_ns_search_path =  GetTestlibRoot() + "/public_namespace_libs";
   1175   const std::string private_ns_search_path = GetTestlibRoot() + "/private_namespace_libs";
   1176 
   1177   android_namespace_t* ns_public =
   1178           android_create_namespace("public",
   1179                                    nullptr,
   1180                                    public_ns_search_path.c_str(),
   1181                                    ANDROID_NAMESPACE_TYPE_ISOLATED,
   1182                                    nullptr,
   1183                                    nullptr);
   1184 
   1185   ASSERT_TRUE(android_link_namespaces(ns_public, nullptr, g_core_shared_libs.c_str())) << dlerror();
   1186 
   1187   android_namespace_t* ns_private =
   1188           android_create_namespace("private",
   1189                                    nullptr,
   1190                                    private_ns_search_path.c_str(),
   1191                                    ANDROID_NAMESPACE_TYPE_ISOLATED,
   1192                                    nullptr,
   1193                                    nullptr);
   1194 
   1195   ASSERT_TRUE(android_link_namespaces(ns_private,
   1196                                       ns_public,
   1197                                       "libnstest_public.so:libtest_missing_symbol_child_public.so")
   1198               ) << dlerror();
   1199   ASSERT_TRUE(android_link_namespaces(ns_private, nullptr, g_core_shared_libs.c_str())) << dlerror();
   1200 
   1201   android_dlextinfo extinfo;
   1202   extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
   1203   extinfo.library_namespace = ns_private;
   1204 
   1205   void* handle = android_dlopen_ext("libtest_missing_symbol_root.so", RTLD_NOW, &extinfo);
   1206   ASSERT_TRUE(handle == nullptr);
   1207   ASSERT_EQ(std::string("dlopen failed: cannot locate symbol \"dlopen_testlib_missing_symbol\" referenced by \"") +
   1208             private_ns_search_path + "/libtest_missing_symbol_root.so\"...",
   1209             dlerror());
   1210 }
   1211 
   1212 TEST(dlext, ns_greylist_enabled) {
   1213   ASSERT_TRUE(android_init_anonymous_namespace(g_core_shared_libs.c_str(), nullptr));
   1214 
   1215   const std::string ns_search_path = GetTestlibRoot() + "/private_namespace_libs";
   1216 
   1217   android_namespace_t* ns =
   1218           android_create_namespace("namespace",
   1219                                    nullptr,
   1220                                    ns_search_path.c_str(),
   1221                                    ANDROID_NAMESPACE_TYPE_ISOLATED | ANDROID_NAMESPACE_TYPE_GREYLIST_ENABLED,
   1222                                    nullptr,
   1223                                    nullptr);
   1224 
   1225   ASSERT_TRUE(android_link_namespaces(ns, nullptr, g_core_shared_libs.c_str())) << dlerror();
   1226 
   1227   android_dlextinfo extinfo;
   1228   extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
   1229   extinfo.library_namespace = ns;
   1230 
   1231   // An app targeting M can open libnativehelper.so because it's on the greylist.
   1232   android_set_application_target_sdk_version(__ANDROID_API_M__);
   1233   void* handle = android_dlopen_ext("libnativehelper.so", RTLD_NOW, &extinfo);
   1234   ASSERT_TRUE(handle != nullptr) << dlerror();
   1235 
   1236   // Check that loader did not load another copy of libdl.so while loading greylisted library.
   1237   void* dlsym_ptr = dlsym(handle, "dlsym");
   1238   ASSERT_TRUE(dlsym_ptr != nullptr) << dlerror();
   1239   ASSERT_EQ(&dlsym, dlsym_ptr);
   1240 
   1241   dlclose(handle);
   1242 
   1243   // An app targeting N no longer has the greylist.
   1244   android_set_application_target_sdk_version(__ANDROID_API_N__);
   1245   handle = android_dlopen_ext("libnativehelper.so", RTLD_NOW, &extinfo);
   1246   ASSERT_TRUE(handle == nullptr);
   1247   ASSERT_STREQ("dlopen failed: library \"libnativehelper.so\" not found", dlerror());
   1248 }
   1249 
   1250 TEST(dlext, ns_greylist_disabled_by_default) {
   1251   ASSERT_TRUE(android_init_anonymous_namespace(g_core_shared_libs.c_str(), nullptr));
   1252 
   1253   const std::string ns_search_path = GetTestlibRoot() + "/private_namespace_libs";
   1254 
   1255   android_namespace_t* ns =
   1256           android_create_namespace("namespace",
   1257                                    nullptr,
   1258                                    ns_search_path.c_str(),
   1259                                    ANDROID_NAMESPACE_TYPE_ISOLATED,
   1260                                    nullptr,
   1261                                    nullptr);
   1262 
   1263   ASSERT_TRUE(android_link_namespaces(ns, nullptr, g_core_shared_libs.c_str())) << dlerror();
   1264 
   1265   android_dlextinfo extinfo;
   1266   extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
   1267   extinfo.library_namespace = ns;
   1268 
   1269   android_set_application_target_sdk_version(__ANDROID_API_M__);
   1270   void* handle = android_dlopen_ext("libnativehelper.so", RTLD_NOW, &extinfo);
   1271   ASSERT_TRUE(handle == nullptr);
   1272   ASSERT_STREQ("dlopen failed: library \"libnativehelper.so\" not found", dlerror());
   1273 }
   1274 
   1275 TEST(dlext, ns_cyclic_namespaces) {
   1276   // Test that ns1->ns2->ns1 link does not break the loader
   1277   ASSERT_TRUE(android_init_anonymous_namespace(g_core_shared_libs.c_str(), nullptr));
   1278   std::string shared_libs = g_core_shared_libs + ":libthatdoesnotexist.so";
   1279 
   1280   const std::string ns_search_path =  GetTestlibRoot() + "/public_namespace_libs";
   1281 
   1282   android_namespace_t* ns1 =
   1283           android_create_namespace("ns1",
   1284                                    nullptr,
   1285                                    ns_search_path.c_str(),
   1286                                    ANDROID_NAMESPACE_TYPE_ISOLATED,
   1287                                    nullptr,
   1288                                    nullptr);
   1289 
   1290   ASSERT_TRUE(android_link_namespaces(ns1, nullptr, g_core_shared_libs.c_str())) << dlerror();
   1291 
   1292   android_namespace_t* ns2 =
   1293           android_create_namespace("ns1",
   1294                                    nullptr,
   1295                                    ns_search_path.c_str(),
   1296                                    ANDROID_NAMESPACE_TYPE_ISOLATED,
   1297                                    nullptr,
   1298                                    nullptr);
   1299 
   1300   ASSERT_TRUE(android_link_namespaces(ns2, nullptr, g_core_shared_libs.c_str())) << dlerror();
   1301 
   1302   ASSERT_TRUE(android_link_namespaces(ns2, ns1, shared_libs.c_str())) << dlerror();
   1303   ASSERT_TRUE(android_link_namespaces(ns1, ns2, shared_libs.c_str())) << dlerror();
   1304 
   1305   android_dlextinfo extinfo;
   1306   extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
   1307   extinfo.library_namespace = ns1;
   1308 
   1309   void* handle = android_dlopen_ext("libthatdoesnotexist.so", RTLD_NOW, &extinfo);
   1310   ASSERT_TRUE(handle == nullptr);
   1311   ASSERT_STREQ("dlopen failed: library \"libthatdoesnotexist.so\" not found", dlerror());
   1312 }
   1313 
   1314 TEST(dlext, ns_isolated) {
   1315   static const char* root_lib = "libnstest_root_not_isolated.so";
   1316   std::string shared_libs = g_core_shared_libs + ":" + g_public_lib;
   1317 
   1318   const std::string lib_public_path = GetTestlibRoot() + "/public_namespace_libs/" + g_public_lib;
   1319   void* handle_public = dlopen(lib_public_path.c_str(), RTLD_NOW);
   1320   ASSERT_TRUE(handle_public != nullptr) << dlerror();
   1321 
   1322   android_set_application_target_sdk_version(42U); // something > 23
   1323 
   1324   ASSERT_TRUE(android_init_anonymous_namespace(shared_libs.c_str(), nullptr)) << dlerror();
   1325 
   1326   android_namespace_t* ns_not_isolated =
   1327           android_create_namespace("private",
   1328                                    nullptr,
   1329                                    (GetTestlibRoot() + "/private_namespace_libs").c_str(),
   1330                                    ANDROID_NAMESPACE_TYPE_REGULAR,
   1331                                    nullptr,
   1332                                    nullptr);
   1333   ASSERT_TRUE(ns_not_isolated != nullptr) << dlerror();
   1334   ASSERT_TRUE(android_link_namespaces(ns_not_isolated, nullptr, shared_libs.c_str())) << dlerror();
   1335 
   1336   android_namespace_t* ns_isolated =
   1337           android_create_namespace("private_isolated1",
   1338                                    nullptr,
   1339                                    (GetTestlibRoot() + "/private_namespace_libs").c_str(),
   1340                                    ANDROID_NAMESPACE_TYPE_ISOLATED,
   1341                                    nullptr,
   1342                                    nullptr);
   1343   ASSERT_TRUE(ns_isolated != nullptr) << dlerror();
   1344   ASSERT_TRUE(android_link_namespaces(ns_isolated, nullptr, shared_libs.c_str())) << dlerror();
   1345 
   1346   android_namespace_t* ns_isolated2 =
   1347           android_create_namespace("private_isolated2",
   1348                                    (GetTestlibRoot() + "/private_namespace_libs").c_str(),
   1349                                    nullptr,
   1350                                    ANDROID_NAMESPACE_TYPE_ISOLATED,
   1351                                    GetTestlibRoot().c_str(),
   1352                                    nullptr);
   1353   ASSERT_TRUE(ns_isolated2 != nullptr) << dlerror();
   1354   ASSERT_TRUE(android_link_namespaces(ns_isolated2, nullptr, shared_libs.c_str())) << dlerror();
   1355 
   1356   ASSERT_TRUE(dlopen(root_lib, RTLD_NOW) == nullptr);
   1357   ASSERT_STREQ("dlopen failed: library \"libnstest_root_not_isolated.so\" not found", dlerror());
   1358 
   1359   std::string lib_private_external_path =
   1360       GetTestlibRoot() + "/private_namespace_libs_external/libnstest_private_external.so";
   1361 
   1362   // Load lib_private_external_path to default namespace
   1363   // (it should remain invisible for the isolated namespaces after this)
   1364   void* handle = dlopen(lib_private_external_path.c_str(), RTLD_NOW);
   1365   ASSERT_TRUE(handle != nullptr) << dlerror();
   1366 
   1367   android_dlextinfo extinfo;
   1368   extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
   1369   extinfo.library_namespace = ns_not_isolated;
   1370 
   1371   void* handle1 = android_dlopen_ext(root_lib, RTLD_NOW, &extinfo);
   1372   ASSERT_TRUE(handle1 != nullptr) << dlerror();
   1373 
   1374   extinfo.library_namespace = ns_isolated;
   1375 
   1376   void* handle2 = android_dlopen_ext(root_lib, RTLD_NOW, &extinfo);
   1377   ASSERT_TRUE(handle2 == nullptr);
   1378   ASSERT_STREQ("dlopen failed: library \"libnstest_private_external.so\" not found", dlerror());
   1379 
   1380   // Check dlopen by absolute path
   1381   handle2 = android_dlopen_ext(lib_private_external_path.c_str(), RTLD_NOW, &extinfo);
   1382   ASSERT_TRUE(handle2 == nullptr);
   1383   ASSERT_EQ("dlopen failed: library \"" + lib_private_external_path + "\" needed"
   1384             " or dlopened by \"" + android::base::GetExecutablePath() +  "\" is not accessible"
   1385             " for the namespace \"private_isolated1\"", dlerror());
   1386 
   1387   extinfo.library_namespace = ns_isolated2;
   1388 
   1389   // this should work because isolation_path for private_isolated2 includes GetTestlibRoot()
   1390   handle2 = android_dlopen_ext(root_lib, RTLD_NOW, &extinfo);
   1391   ASSERT_TRUE(handle2 != nullptr) << dlerror();
   1392   dlclose(handle2);
   1393 
   1394   // Check dlopen by absolute path
   1395   handle2 = android_dlopen_ext(lib_private_external_path.c_str(), RTLD_NOW, &extinfo);
   1396   ASSERT_TRUE(handle2 != nullptr) << dlerror();
   1397   dlclose(handle2);
   1398 
   1399   typedef const char* (*fn_t)();
   1400   fn_t ns_get_local_string = reinterpret_cast<fn_t>(dlsym(handle1, "ns_get_local_string"));
   1401   ASSERT_TRUE(ns_get_local_string != nullptr) << dlerror();
   1402 
   1403   ASSERT_STREQ("This string is local to root library", ns_get_local_string());
   1404 
   1405   fn_t ns_get_private_extern_string =
   1406           reinterpret_cast<fn_t>(dlsym(handle1, "ns_get_private_extern_string"));
   1407   ASSERT_TRUE(ns_get_private_extern_string != nullptr) << dlerror();
   1408 
   1409   ASSERT_STREQ("This string is from private namespace", ns_get_private_extern_string());
   1410 
   1411   fn_t ns_get_public_extern_string =
   1412           reinterpret_cast<fn_t>(dlsym(handle1, "ns_get_public_extern_string"));
   1413   ASSERT_TRUE(ns_get_public_extern_string != nullptr) << dlerror();
   1414 
   1415   ASSERT_STREQ("This string is from public namespace", ns_get_public_extern_string());
   1416 
   1417   fn_t ns_get_dlopened_string = reinterpret_cast<fn_t>(dlsym(handle1, "ns_get_dlopened_string"));
   1418   ASSERT_TRUE(ns_get_dlopened_string != nullptr) << dlerror();
   1419 
   1420   ASSERT_STREQ("This string is from private namespace (dlopened library)", ns_get_dlopened_string());
   1421 
   1422   dlclose(handle1);
   1423 }
   1424 
   1425 TEST(dlext, ns_shared) {
   1426   static const char* root_lib = "libnstest_root_not_isolated.so";
   1427   static const char* root_lib_isolated = "libnstest_root.so";
   1428 
   1429   std::string shared_libs = g_core_shared_libs + ":" + g_public_lib;
   1430 
   1431   // create a parent namespace to use instead of the default namespace. This is
   1432   // to make this test be independent from the configuration of the default
   1433   // namespace.
   1434   android_namespace_t* ns_parent =
   1435           android_create_namespace("parent",
   1436                                    nullptr,
   1437                                    nullptr,
   1438                                    ANDROID_NAMESPACE_TYPE_REGULAR,
   1439                                    nullptr,
   1440                                    nullptr);
   1441   ASSERT_TRUE(ns_parent != nullptr) << dlerror();
   1442   ASSERT_TRUE(android_link_namespaces(ns_parent, nullptr, g_core_shared_libs.c_str())) << dlerror();
   1443 
   1444   android_dlextinfo extinfo;
   1445   extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
   1446   extinfo.library_namespace = ns_parent;
   1447 
   1448   const std::string lib_public_path = GetTestlibRoot() + "/public_namespace_libs/" + g_public_lib;
   1449   void* handle_public = android_dlopen_ext(lib_public_path.c_str(), RTLD_NOW, &extinfo);
   1450   ASSERT_TRUE(handle_public != nullptr) << dlerror();
   1451 
   1452   android_set_application_target_sdk_version(42U); // something > 23
   1453 
   1454   ASSERT_TRUE(android_init_anonymous_namespace(shared_libs.c_str(), nullptr)) << dlerror();
   1455 
   1456   // preload this library to the parent namespace to check if it
   1457   // is shared later on.
   1458   void* handle_dlopened =
   1459           android_dlopen_ext((GetTestlibRoot() + "/private_namespace_libs/libnstest_dlopened.so").c_str(), RTLD_NOW, &extinfo);
   1460   ASSERT_TRUE(handle_dlopened != nullptr) << dlerror();
   1461 
   1462   // create two child namespaces of 'ns_parent'. One with regular, the other
   1463   // with isolated & shared.
   1464   android_namespace_t* ns_not_isolated =
   1465           android_create_namespace("private",
   1466                                    nullptr,
   1467                                    (GetTestlibRoot() + "/private_namespace_libs").c_str(),
   1468                                    ANDROID_NAMESPACE_TYPE_REGULAR,
   1469                                    nullptr,
   1470                                    ns_parent);
   1471   ASSERT_TRUE(ns_not_isolated != nullptr) << dlerror();
   1472   ASSERT_TRUE(android_link_namespaces(ns_not_isolated, ns_parent, g_public_lib)) << dlerror();
   1473   ASSERT_TRUE(android_link_namespaces(ns_not_isolated, nullptr, g_core_shared_libs.c_str())) << dlerror();
   1474 
   1475   android_namespace_t* ns_isolated_shared =
   1476           android_create_namespace("private_isolated_shared",
   1477                                    nullptr,
   1478                                    (GetTestlibRoot() + "/private_namespace_libs").c_str(),
   1479                                    ANDROID_NAMESPACE_TYPE_ISOLATED | ANDROID_NAMESPACE_TYPE_SHARED,
   1480                                    nullptr,
   1481                                    ns_parent);
   1482   ASSERT_TRUE(ns_isolated_shared != nullptr) << dlerror();
   1483   ASSERT_TRUE(android_link_namespaces(ns_isolated_shared, ns_parent, g_public_lib)) << dlerror();
   1484   ASSERT_TRUE(android_link_namespaces(ns_isolated_shared, nullptr, g_core_shared_libs.c_str())) << dlerror();
   1485 
   1486   ASSERT_TRUE(android_dlopen_ext(root_lib, RTLD_NOW, &extinfo) == nullptr);
   1487   ASSERT_STREQ("dlopen failed: library \"libnstest_root_not_isolated.so\" not found", dlerror());
   1488 
   1489   std::string lib_private_external_path =
   1490       GetTestlibRoot() + "/private_namespace_libs_external/libnstest_private_external.so";
   1491 
   1492   // Load lib_private_external_path to the parent namespace
   1493   // (it should remain invisible for the isolated namespaces after this)
   1494   void* handle = android_dlopen_ext(lib_private_external_path.c_str(), RTLD_NOW, &extinfo);
   1495   ASSERT_TRUE(handle != nullptr) << dlerror();
   1496 
   1497   extinfo.library_namespace = ns_not_isolated;
   1498 
   1499   void* handle1 = android_dlopen_ext(root_lib, RTLD_NOW, &extinfo);
   1500   ASSERT_TRUE(handle1 != nullptr) << dlerror();
   1501 
   1502   extinfo.library_namespace = ns_isolated_shared;
   1503 
   1504   void* handle2 = android_dlopen_ext(root_lib, RTLD_NOW, &extinfo);
   1505   ASSERT_TRUE(handle2 == nullptr);
   1506   ASSERT_STREQ("dlopen failed: library \"libnstest_private_external.so\" not found", dlerror());
   1507 
   1508   // Check dlopen by absolute path
   1509   handle2 = android_dlopen_ext(lib_private_external_path.c_str(), RTLD_NOW, &extinfo);
   1510   ASSERT_TRUE(handle2 == nullptr);
   1511   ASSERT_EQ("dlopen failed: library \"" + lib_private_external_path + "\" needed"
   1512             " or dlopened by \"" + android::base::GetExecutablePath() + "\" is not accessible"
   1513             " for the namespace \"private_isolated_shared\"", dlerror());
   1514 
   1515   // load libnstest_root.so to shared namespace in order to check that everything is different
   1516   // except shared libnstest_dlopened.so
   1517 
   1518   handle2 = android_dlopen_ext(root_lib_isolated, RTLD_NOW, &extinfo);
   1519 
   1520   typedef const char* (*fn_t)();
   1521   fn_t ns_get_local_string = reinterpret_cast<fn_t>(dlsym(handle1, "ns_get_local_string"));
   1522   ASSERT_TRUE(ns_get_local_string != nullptr) << dlerror();
   1523   fn_t ns_get_local_string_shared = reinterpret_cast<fn_t>(dlsym(handle2, "ns_get_local_string"));
   1524   ASSERT_TRUE(ns_get_local_string_shared != nullptr) << dlerror();
   1525 
   1526   ASSERT_STREQ("This string is local to root library", ns_get_local_string());
   1527   ASSERT_STREQ("This string is local to root library", ns_get_local_string_shared());
   1528   ASSERT_TRUE(ns_get_local_string() != ns_get_local_string_shared());
   1529 
   1530   fn_t ns_get_private_extern_string =
   1531           reinterpret_cast<fn_t>(dlsym(handle1, "ns_get_private_extern_string"));
   1532   ASSERT_TRUE(ns_get_private_extern_string != nullptr) << dlerror();
   1533   fn_t ns_get_private_extern_string_shared =
   1534           reinterpret_cast<fn_t>(dlsym(handle2, "ns_get_private_extern_string"));
   1535   ASSERT_TRUE(ns_get_private_extern_string_shared() != nullptr) << dlerror();
   1536 
   1537   ASSERT_STREQ("This string is from private namespace", ns_get_private_extern_string());
   1538   ASSERT_STREQ("This string is from private namespace", ns_get_private_extern_string_shared());
   1539   ASSERT_TRUE(ns_get_private_extern_string() != ns_get_private_extern_string_shared());
   1540 
   1541   fn_t ns_get_public_extern_string =
   1542           reinterpret_cast<fn_t>(dlsym(handle1, "ns_get_public_extern_string"));
   1543   ASSERT_TRUE(ns_get_public_extern_string != nullptr) << dlerror();
   1544   fn_t ns_get_public_extern_string_shared =
   1545           reinterpret_cast<fn_t>(dlsym(handle2, "ns_get_public_extern_string"));
   1546   ASSERT_TRUE(ns_get_public_extern_string_shared != nullptr) << dlerror();
   1547 
   1548   ASSERT_STREQ("This string is from public namespace", ns_get_public_extern_string());
   1549   ASSERT_STREQ("This string is from public namespace", ns_get_public_extern_string_shared());
   1550   ASSERT_TRUE(ns_get_public_extern_string() == ns_get_public_extern_string_shared());
   1551 
   1552   fn_t ns_get_dlopened_string = reinterpret_cast<fn_t>(dlsym(handle1, "ns_get_dlopened_string"));
   1553   ASSERT_TRUE(ns_get_dlopened_string != nullptr) << dlerror();
   1554   fn_t ns_get_dlopened_string_shared = reinterpret_cast<fn_t>(dlsym(handle2, "ns_get_dlopened_string"));
   1555   ASSERT_TRUE(ns_get_dlopened_string_shared != nullptr) << dlerror();
   1556   const char** ns_dlopened_string = static_cast<const char**>(dlsym(handle_dlopened, "g_private_dlopened_string"));
   1557   ASSERT_TRUE(ns_dlopened_string != nullptr) << dlerror();
   1558 
   1559   ASSERT_STREQ("This string is from private namespace (dlopened library)", ns_get_dlopened_string());
   1560   ASSERT_STREQ("This string is from private namespace (dlopened library)", *ns_dlopened_string);
   1561   ASSERT_STREQ("This string is from private namespace (dlopened library)", ns_get_dlopened_string_shared());
   1562   ASSERT_TRUE(ns_get_dlopened_string() != ns_get_dlopened_string_shared());
   1563   ASSERT_TRUE(*ns_dlopened_string == ns_get_dlopened_string_shared());
   1564 
   1565   dlclose(handle1);
   1566   dlclose(handle2);
   1567 }
   1568 
   1569 TEST(dlext, ns_shared_links_and_paths) {
   1570   // Create parent namespace (isolated, not shared)
   1571   android_namespace_t* ns_isolated =
   1572           android_create_namespace("private_isolated",
   1573                                    nullptr,
   1574                                    (GetTestlibRoot() + "/private_namespace_libs").c_str(),
   1575                                    ANDROID_NAMESPACE_TYPE_ISOLATED,
   1576                                    (GetTestlibRoot() + "/public_namespace_libs").c_str(),
   1577                                    nullptr);
   1578   ASSERT_TRUE(ns_isolated != nullptr) << dlerror();
   1579   ASSERT_TRUE(android_link_namespaces(ns_isolated, nullptr, g_core_shared_libs.c_str())) << dlerror();
   1580 
   1581   // Create shared namespace with ns_isolated parent
   1582   android_namespace_t* ns_shared =
   1583           android_create_namespace("private_shared",
   1584                                    nullptr,
   1585                                    nullptr,
   1586                                    ANDROID_NAMESPACE_TYPE_SHARED | ANDROID_NAMESPACE_TYPE_ISOLATED,
   1587                                    nullptr,
   1588                                    ns_isolated);
   1589   ASSERT_TRUE(ns_shared != nullptr) << dlerror();
   1590 
   1591   // 1. Load a library in ns_shared to check that it has inherited
   1592   // search path and the link to the default namespace.
   1593   android_dlextinfo extinfo;
   1594   extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
   1595   extinfo.library_namespace = ns_shared;
   1596 
   1597   {
   1598     void* handle = android_dlopen_ext("libnstest_private.so", RTLD_NOW, &extinfo);
   1599     ASSERT_TRUE(handle != nullptr) << dlerror();
   1600     const char** ns_private_extern_string = static_cast<const char**>(dlsym(handle, "g_private_extern_string"));
   1601     ASSERT_TRUE(ns_private_extern_string != nullptr) << dlerror();
   1602     ASSERT_STREQ("This string is from private namespace", *ns_private_extern_string);
   1603 
   1604     dlclose(handle);
   1605   }
   1606   // 2. Load another test library by absolute path to check that
   1607   // it has inherited permitted_when_isolated_path
   1608   {
   1609     void* handle = android_dlopen_ext(
   1610             (GetTestlibRoot() + "/public_namespace_libs/libnstest_public.so").c_str(),
   1611             RTLD_NOW,
   1612             &extinfo);
   1613 
   1614     ASSERT_TRUE(handle != nullptr) << dlerror();
   1615     const char** ns_public_extern_string = static_cast<const char**>(dlsym(handle, "g_public_extern_string"));
   1616     ASSERT_TRUE(ns_public_extern_string != nullptr) << dlerror();
   1617     ASSERT_STREQ("This string is from public namespace", *ns_public_extern_string);
   1618 
   1619     dlclose(handle);
   1620   }
   1621 
   1622   // 3. Check that it is still isolated.
   1623   {
   1624     void* handle = android_dlopen_ext(
   1625             (GetTestlibRoot() + "/libtest_empty.so").c_str(),
   1626             RTLD_NOW,
   1627             &extinfo);
   1628 
   1629     ASSERT_TRUE(handle == nullptr);
   1630   }
   1631 }
   1632 
   1633 TEST(dlext, ns_shared_dlclose) {
   1634   android_set_application_target_sdk_version(42U); // something > 23
   1635 
   1636   ASSERT_TRUE(android_init_anonymous_namespace(g_core_shared_libs.c_str(), nullptr)) << dlerror();
   1637 
   1638   // preload this library to the default namespace to check if it
   1639   // is shared later on.
   1640   void* handle_dlopened =
   1641           dlopen((GetTestlibRoot() + "/private_namespace_libs/libnstest_dlopened.so").c_str(), RTLD_NOW);
   1642   ASSERT_TRUE(handle_dlopened != nullptr) << dlerror();
   1643 
   1644   android_namespace_t* ns_isolated_shared =
   1645           android_create_namespace("private_isolated_shared",
   1646                                    nullptr,
   1647                                    (GetTestlibRoot() + "/private_namespace_libs").c_str(),
   1648                                    ANDROID_NAMESPACE_TYPE_ISOLATED | ANDROID_NAMESPACE_TYPE_SHARED,
   1649                                    nullptr,
   1650                                    nullptr);
   1651   ASSERT_TRUE(ns_isolated_shared != nullptr) << dlerror();
   1652   ASSERT_TRUE(android_link_namespaces(ns_isolated_shared, nullptr, g_core_shared_libs.c_str())) << dlerror();
   1653 
   1654   // Check if "libnstest_dlopened.so" is loaded (and the same)
   1655   android_dlextinfo extinfo;
   1656   extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
   1657   extinfo.library_namespace = ns_isolated_shared;
   1658 
   1659   void* handle = android_dlopen_ext("libnstest_dlopened.so", RTLD_NOW | RTLD_NOLOAD, &extinfo);
   1660   ASSERT_TRUE(handle != nullptr) << dlerror();
   1661   ASSERT_TRUE(handle == handle_dlopened);
   1662   dlclose(handle);
   1663   dlclose(handle_dlopened);
   1664 
   1665   // And now check that the library cannot be found by soname (and is no longer loaded)
   1666   handle = android_dlopen_ext("libnstest_dlopened.so", RTLD_NOW | RTLD_NOLOAD, &extinfo);
   1667   ASSERT_TRUE(handle == nullptr)
   1668       << "Error: libnstest_dlopened.so is still accessible in shared namespace";
   1669 
   1670   handle = android_dlopen_ext((GetTestlibRoot() + "/private_namespace_libs/libnstest_dlopened.so").c_str(),
   1671                               RTLD_NOW | RTLD_NOLOAD, &extinfo);
   1672   ASSERT_TRUE(handle == nullptr)
   1673       << "Error: libnstest_dlopened.so is still accessible in shared namespace";
   1674 
   1675   handle = dlopen("libnstest_dlopened.so", RTLD_NOW | RTLD_NOLOAD);
   1676   ASSERT_TRUE(handle == nullptr)
   1677       << "Error: libnstest_dlopened.so is still accessible in default namespace";
   1678 
   1679   handle = dlopen((GetTestlibRoot() + "/private_namespace_libs/libnstest_dlopened.so").c_str(),
   1680                   RTLD_NOW | RTLD_NOLOAD);
   1681   ASSERT_TRUE(handle == nullptr)
   1682       << "Error: libnstest_dlopened.so is still accessible in default namespace";
   1683 
   1684   // Now lets see if the soinfo area gets reused in the wrong way:
   1685   // load a library to default namespace.
   1686   const std::string lib_public_path = GetTestlibRoot() + "/public_namespace_libs/" + g_public_lib;
   1687   void* handle_public = dlopen(lib_public_path.c_str(), RTLD_NOW);
   1688   ASSERT_TRUE(handle_public != nullptr) << dlerror();
   1689 
   1690   // try to find it in shared namespace
   1691   handle = android_dlopen_ext(g_public_lib, RTLD_NOW | RTLD_NOLOAD, &extinfo);
   1692   ASSERT_TRUE(handle == nullptr)
   1693       << "Error: " << g_public_lib << " is accessible in shared namespace";
   1694 }
   1695 
   1696 TEST(dlext, ns_isolated_rtld_global) {
   1697   static const char* root_lib = "libnstest_root.so";
   1698   ASSERT_TRUE(android_init_anonymous_namespace(g_core_shared_libs.c_str(), nullptr));
   1699 
   1700   const std::string lib_public_path = GetTestlibRoot() + "/public_namespace_libs";
   1701 
   1702   android_namespace_t* ns1 =
   1703           android_create_namespace("isolated1",
   1704                                    nullptr,
   1705                                    (GetTestlibRoot() + "/private_namespace_libs").c_str(),
   1706                                    ANDROID_NAMESPACE_TYPE_ISOLATED,
   1707                                    lib_public_path.c_str(),
   1708                                    nullptr);
   1709   ASSERT_TRUE(ns1 != nullptr) << dlerror();
   1710   ASSERT_TRUE(android_link_namespaces(ns1, nullptr, g_core_shared_libs.c_str())) << dlerror();
   1711 
   1712   android_namespace_t* ns2 =
   1713           android_create_namespace("isolated2",
   1714                                    nullptr,
   1715                                    (GetTestlibRoot() + "/private_namespace_libs").c_str(),
   1716                                    ANDROID_NAMESPACE_TYPE_ISOLATED,
   1717                                    lib_public_path.c_str(),
   1718                                    nullptr);
   1719   ASSERT_TRUE(ns2 != nullptr) << dlerror();
   1720   ASSERT_TRUE(android_link_namespaces(ns2, nullptr, g_core_shared_libs.c_str())) << dlerror();
   1721 
   1722   android_dlextinfo extinfo;
   1723   extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
   1724   extinfo.library_namespace = ns1;
   1725 
   1726   void* handle_global = android_dlopen_ext((lib_public_path + "/" + g_public_lib).c_str(),
   1727                                            RTLD_GLOBAL,
   1728                                            &extinfo);
   1729 
   1730   ASSERT_TRUE(handle_global != nullptr) << dlerror();
   1731 
   1732   android_namespace_t* ns1_child =
   1733           android_create_namespace("isolated1_child",
   1734                                    nullptr,
   1735                                    (GetTestlibRoot() + "/private_namespace_libs").c_str(),
   1736                                    ANDROID_NAMESPACE_TYPE_ISOLATED,
   1737                                    nullptr,
   1738                                    ns1);
   1739 
   1740   ASSERT_TRUE(ns1_child != nullptr) << dlerror();
   1741   ASSERT_TRUE(android_link_namespaces(ns1_child, nullptr, g_core_shared_libs.c_str())) << dlerror();
   1742 
   1743   // Now - only ns1 and ns1 child should be able to dlopen root_lib
   1744   // attempt to use ns2 should result in dlerror()
   1745 
   1746   // Check ns1_child first.
   1747   extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
   1748   extinfo.library_namespace = ns1_child;
   1749 
   1750   void* handle1 = android_dlopen_ext(root_lib, RTLD_NOW, &extinfo);
   1751   ASSERT_TRUE(handle1 != nullptr) << dlerror();
   1752 
   1753   // now ns1
   1754   extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
   1755   extinfo.library_namespace = ns1;
   1756 
   1757   handle1 = android_dlopen_ext(root_lib, RTLD_NOW, &extinfo);
   1758   ASSERT_TRUE(handle1 != nullptr) << dlerror();
   1759 
   1760   // and ns2 should fail
   1761   extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
   1762   extinfo.library_namespace = ns2;
   1763 
   1764   handle1 = android_dlopen_ext(root_lib, RTLD_NOW, &extinfo);
   1765   ASSERT_TRUE(handle1 == nullptr);
   1766   ASSERT_STREQ("dlopen failed: library \"libnstest_public.so\" not found", dlerror());
   1767 }
   1768 
   1769 TEST(dlext, ns_inaccessible_error_message) {
   1770   // We set up 2 namespaces (a and b) and link a->b with a shared library
   1771   // libtestshared.so. Then try to dlopen different library with the same
   1772   // name from in namespace a. Note that library should not be accessible
   1773   // in either namespace but since it's soname is in the list of shared libs
   1774   // the linker will attempt to find it in linked namespace.
   1775   //
   1776   // Check the error message and make sure it mentions correct namespace name.
   1777   ASSERT_TRUE(android_init_anonymous_namespace(g_core_shared_libs.c_str(), nullptr));
   1778 
   1779   android_namespace_t* ns_a =
   1780           android_create_namespace("ns_a",
   1781                                    nullptr,
   1782                                    (GetTestlibRoot() + "/private_namespace_libs").c_str(),
   1783                                    ANDROID_NAMESPACE_TYPE_ISOLATED,
   1784                                    nullptr,
   1785                                    nullptr);
   1786   ASSERT_TRUE(ns_a != nullptr) << dlerror();
   1787   ASSERT_TRUE(android_link_namespaces(ns_a, nullptr, g_core_shared_libs.c_str())) << dlerror();
   1788 
   1789   android_namespace_t* ns_b =
   1790           android_create_namespace("ns_b",
   1791                                    nullptr,
   1792                                    GetTestlibRoot().c_str(),
   1793                                    ANDROID_NAMESPACE_TYPE_ISOLATED,
   1794                                    nullptr,
   1795                                    nullptr);
   1796   ASSERT_TRUE(ns_b != nullptr) << dlerror();
   1797   ASSERT_TRUE(android_link_namespaces(ns_b, nullptr, g_core_shared_libs.c_str())) << dlerror();
   1798 
   1799   ASSERT_TRUE(android_link_namespaces(ns_a, ns_b, "libtestshared.so")) << dlerror();
   1800 
   1801   android_dlextinfo extinfo;
   1802   extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
   1803   extinfo.library_namespace = ns_a;
   1804 
   1805   std::string library_path = GetTestlibRoot() + "/inaccessible_libs/libtestshared.so";
   1806 
   1807   void* handle = android_dlopen_ext(library_path.c_str(), RTLD_NOW, &extinfo);
   1808   ASSERT_TRUE(handle == nullptr);
   1809   std::string expected_dlerror =
   1810       android::base::StringPrintf("dlopen failed: library \"%s\" needed or dlopened by \"%s\""
   1811                                   " is not accessible for the namespace \"ns_a\"",
   1812                                   library_path.c_str(),
   1813                                   android::base::GetExecutablePath().c_str());
   1814   ASSERT_EQ(expected_dlerror, dlerror());
   1815 }
   1816 
   1817 extern "C" bool __loader_android_link_namespaces_all_libs(android_namespace_t* namespace_from,
   1818                                                           android_namespace_t* namespace_to);
   1819 
   1820 TEST(dlext, ns_link_namespaces_invalid_arguments) {
   1821   ASSERT_TRUE(android_init_anonymous_namespace(g_core_shared_libs.c_str(), nullptr));
   1822 
   1823   android_namespace_t* ns =
   1824           android_create_namespace("private",
   1825                                    nullptr,
   1826                                    (GetTestlibRoot() + "/private_namespace_libs").c_str(),
   1827                                    ANDROID_NAMESPACE_TYPE_REGULAR,
   1828                                    nullptr,
   1829                                    nullptr);
   1830   ASSERT_TRUE(ns != nullptr) << dlerror();
   1831 
   1832   // Test android_link_namespaces()
   1833   ASSERT_FALSE(android_link_namespaces(nullptr, nullptr, "libc.so"));
   1834   ASSERT_STREQ("android_link_namespaces failed: error linking namespaces: namespace_from is null.",
   1835                dlerror());
   1836 
   1837   ASSERT_FALSE(android_link_namespaces(ns, nullptr, nullptr));
   1838   ASSERT_STREQ("android_link_namespaces failed: "
   1839                "error linking namespaces \"private\"->\"(default)\": "
   1840                "the list of shared libraries is empty.", dlerror());
   1841 
   1842   ASSERT_FALSE(android_link_namespaces(ns, nullptr, ""));
   1843   ASSERT_STREQ("android_link_namespaces failed: "
   1844                "error linking namespaces \"private\"->\"(default)\": "
   1845                "the list of shared libraries is empty.", dlerror());
   1846 
   1847   // Test __loader_android_link_namespaces_all_libs()
   1848   ASSERT_FALSE(__loader_android_link_namespaces_all_libs(nullptr, nullptr));
   1849   ASSERT_STREQ("android_link_namespaces_all_libs failed: "
   1850                "error linking namespaces: namespace_from is null.", dlerror());
   1851 
   1852   ASSERT_FALSE(__loader_android_link_namespaces_all_libs(nullptr, ns));
   1853   ASSERT_STREQ("android_link_namespaces_all_libs failed: "
   1854                "error linking namespaces: namespace_from is null.", dlerror());
   1855 
   1856   ASSERT_FALSE(__loader_android_link_namespaces_all_libs(ns, nullptr));
   1857   ASSERT_STREQ("android_link_namespaces_all_libs failed: "
   1858                "error linking namespaces: namespace_to is null.", dlerror());
   1859 }
   1860 
   1861 TEST(dlext, ns_allow_all_shared_libs) {
   1862   ASSERT_TRUE(android_init_anonymous_namespace(g_core_shared_libs.c_str(), nullptr));
   1863 
   1864   android_namespace_t* ns_a =
   1865           android_create_namespace("ns_a",
   1866                                    nullptr,
   1867                                    (GetTestlibRoot() + "/ns_a").c_str(),
   1868                                    ANDROID_NAMESPACE_TYPE_ISOLATED,
   1869                                    nullptr,
   1870                                    nullptr);
   1871   ASSERT_TRUE(ns_a != nullptr) << dlerror();
   1872   ASSERT_TRUE(android_link_namespaces(ns_a, nullptr, g_core_shared_libs.c_str())) << dlerror();
   1873 
   1874   android_namespace_t* ns_b =
   1875           android_create_namespace("ns_b",
   1876                                    nullptr,
   1877                                    (GetTestlibRoot() + "/ns_b").c_str(),
   1878                                    ANDROID_NAMESPACE_TYPE_ISOLATED,
   1879                                    nullptr,
   1880                                    nullptr);
   1881   ASSERT_TRUE(ns_b != nullptr) << dlerror();
   1882   ASSERT_TRUE(android_link_namespaces(ns_b, nullptr, g_core_shared_libs.c_str())) << dlerror();
   1883 
   1884   ASSERT_TRUE(android_link_namespaces(ns_b, ns_a, "libnstest_ns_a_public1.so")) << dlerror();
   1885   ASSERT_TRUE(__loader_android_link_namespaces_all_libs(ns_a, ns_b)) << dlerror();
   1886 
   1887   // Load libs with android_dlopen_ext() from namespace b
   1888   android_dlextinfo extinfo;
   1889   extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
   1890   extinfo.library_namespace = ns_b;
   1891 
   1892   void* ns_b_handle1 = android_dlopen_ext("libnstest_ns_a_public1.so", RTLD_NOW, &extinfo);
   1893   ASSERT_TRUE(ns_b_handle1 != nullptr) << dlerror();
   1894 
   1895   void* ns_b_handle1_internal =
   1896       android_dlopen_ext("libnstest_ns_a_public1_internal.so", RTLD_NOW, &extinfo);
   1897   ASSERT_TRUE(ns_b_handle1_internal == nullptr);
   1898 
   1899   void* ns_b_handle2 = android_dlopen_ext("libnstest_ns_b_public2.so", RTLD_NOW, &extinfo);
   1900   ASSERT_TRUE(ns_b_handle2 != nullptr) << dlerror();
   1901 
   1902   void* ns_b_handle3 = android_dlopen_ext("libnstest_ns_b_public3.so", RTLD_NOW, &extinfo);
   1903   ASSERT_TRUE(ns_b_handle3 != nullptr) << dlerror();
   1904 
   1905   // Load libs with android_dlopen_ext() from namespace a
   1906   extinfo.library_namespace = ns_a;
   1907 
   1908   void* ns_a_handle1 = android_dlopen_ext("libnstest_ns_a_public1.so", RTLD_NOW, &extinfo);
   1909   ASSERT_TRUE(ns_a_handle1 != nullptr) << dlerror();
   1910 
   1911   void* ns_a_handle1_internal =
   1912       android_dlopen_ext("libnstest_ns_a_public1_internal.so", RTLD_NOW, &extinfo);
   1913   ASSERT_TRUE(ns_a_handle1_internal != nullptr) << dlerror();
   1914 
   1915   void* ns_a_handle2 = android_dlopen_ext("libnstest_ns_b_public2.so", RTLD_NOW, &extinfo);
   1916   ASSERT_TRUE(ns_a_handle2 != nullptr) << dlerror();
   1917 
   1918   void* ns_a_handle3 = android_dlopen_ext("libnstest_ns_b_public3.so", RTLD_NOW, &extinfo);
   1919   ASSERT_TRUE(ns_a_handle3 != nullptr) << dlerror();
   1920 
   1921   // Compare the dlopen handle
   1922   ASSERT_EQ(ns_b_handle1, ns_a_handle1);
   1923   ASSERT_EQ(ns_b_handle2, ns_a_handle2);
   1924   ASSERT_EQ(ns_b_handle3, ns_a_handle3);
   1925 
   1926   // Close libs
   1927   dlclose(ns_b_handle1);
   1928   dlclose(ns_b_handle2);
   1929   dlclose(ns_b_handle3);
   1930 
   1931   dlclose(ns_a_handle1);
   1932   dlclose(ns_a_handle1_internal);
   1933   dlclose(ns_a_handle2);
   1934   dlclose(ns_a_handle3);
   1935 }
   1936 
   1937 TEST(dlext, ns_anonymous) {
   1938   static const char* root_lib = "libnstest_root.so";
   1939   std::string shared_libs = g_core_shared_libs + ":" + g_public_lib;
   1940 
   1941   const std::string lib_public_path = GetTestlibRoot() + "/public_namespace_libs/" + g_public_lib;
   1942   void* handle_public = dlopen(lib_public_path.c_str(), RTLD_NOW);
   1943 
   1944   ASSERT_TRUE(handle_public != nullptr) << dlerror();
   1945 
   1946   ASSERT_TRUE(
   1947           android_init_anonymous_namespace(shared_libs.c_str(),
   1948                                            (GetTestlibRoot() + "/private_namespace_libs").c_str())
   1949       ) << dlerror();
   1950 
   1951   android_namespace_t* ns =
   1952           android_create_namespace("private",
   1953                                    nullptr,
   1954                                    (GetTestlibRoot() + "/private_namespace_libs").c_str(),
   1955                                    ANDROID_NAMESPACE_TYPE_REGULAR,
   1956                                    nullptr,
   1957                                    nullptr);
   1958 
   1959   ASSERT_TRUE(ns != nullptr) << dlerror();
   1960   ASSERT_TRUE(android_link_namespaces(ns, nullptr, shared_libs.c_str())) << dlerror();
   1961 
   1962   std::string private_library_absolute_path = GetTestlibRoot() + "/private_namespace_libs/" + root_lib;
   1963 
   1964   android_dlextinfo extinfo;
   1965   extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
   1966   extinfo.library_namespace = ns;
   1967 
   1968   // we are going to copy this library to anonymous mmap and call the copy of ns_get_dlopened_string
   1969   void* handle = android_dlopen_ext(private_library_absolute_path.c_str(), RTLD_NOW, &extinfo);
   1970   ASSERT_TRUE(handle != nullptr) << dlerror();
   1971 
   1972   uintptr_t ns_get_dlopened_string_addr =
   1973       reinterpret_cast<uintptr_t>(dlsym(handle, "ns_get_dlopened_string"));
   1974   ASSERT_TRUE(ns_get_dlopened_string_addr != 0) << dlerror();
   1975   typedef const char* (*fn_t)();
   1976   fn_t ns_get_dlopened_string_private = reinterpret_cast<fn_t>(ns_get_dlopened_string_addr);
   1977 
   1978   std::vector<map_record> maps;
   1979   Maps::parse_maps(&maps);
   1980 
   1981   uintptr_t addr_start = 0;
   1982   uintptr_t addr_end = 0;
   1983   bool has_executable_segment = false;
   1984   std::vector<map_record> maps_to_copy;
   1985 
   1986   for (const auto& rec : maps) {
   1987     if (rec.pathname == private_library_absolute_path) {
   1988       if (addr_start == 0) {
   1989         addr_start = rec.addr_start;
   1990       }
   1991       addr_end = rec.addr_end;
   1992       has_executable_segment = has_executable_segment || (rec.perms & PROT_EXEC) != 0;
   1993 
   1994       maps_to_copy.push_back(rec);
   1995     }
   1996   }
   1997 
   1998   // some sanity checks..
   1999   ASSERT_TRUE(addr_start > 0);
   2000   ASSERT_TRUE(addr_end > 0);
   2001   ASSERT_TRUE(maps_to_copy.size() > 0);
   2002   ASSERT_TRUE(ns_get_dlopened_string_addr > addr_start);
   2003   ASSERT_TRUE(ns_get_dlopened_string_addr < addr_end);
   2004 
   2005   if (!has_executable_segment) {
   2006     // For some natively bridged environments this code might be missing
   2007     // the executable flag. This is because the guest code is not supposed
   2008     // to be executed directly and making it non-executable is more secure.
   2009     // If this is the case we assume that the first segment is the one that
   2010     // has this flag.
   2011     ASSERT_TRUE((maps_to_copy[0].perms & PROT_WRITE) == 0);
   2012     maps_to_copy[0].perms |= PROT_EXEC;
   2013   }
   2014 
   2015   // copy
   2016   uintptr_t reserved_addr = reinterpret_cast<uintptr_t>(mmap(nullptr, addr_end - addr_start,
   2017                                                              PROT_NONE, MAP_ANON | MAP_PRIVATE,
   2018                                                              -1, 0));
   2019   ASSERT_TRUE(reinterpret_cast<void*>(reserved_addr) != MAP_FAILED);
   2020 
   2021   for (const auto& rec : maps_to_copy) {
   2022     uintptr_t offset = rec.addr_start - addr_start;
   2023     size_t size = rec.addr_end - rec.addr_start;
   2024     void* addr = reinterpret_cast<void*>(reserved_addr + offset);
   2025     void* map = mmap(addr, size, PROT_READ | PROT_WRITE,
   2026                      MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0);
   2027     ASSERT_TRUE(map != MAP_FAILED);
   2028     memcpy(map, reinterpret_cast<void*>(rec.addr_start), size);
   2029     mprotect(map, size, rec.perms);
   2030   }
   2031 
   2032   // call the function copy
   2033   uintptr_t ns_get_dlopened_string_offset  = ns_get_dlopened_string_addr - addr_start;
   2034   fn_t ns_get_dlopened_string_anon = reinterpret_cast<fn_t>(reserved_addr + ns_get_dlopened_string_offset);
   2035   ASSERT_STREQ("This string is from private namespace (dlopened library)",
   2036                ns_get_dlopened_string_anon());
   2037 
   2038   // They should belong to different namespaces (private and anonymous)
   2039   ASSERT_STREQ("This string is from private namespace (dlopened library)",
   2040                ns_get_dlopened_string_private());
   2041 
   2042   ASSERT_TRUE(ns_get_dlopened_string_anon() != ns_get_dlopened_string_private());
   2043 }
   2044 
   2045 TEST(dlext, dlopen_handle_value_platform) {
   2046   void* handle = dlopen("libtest_dlsym_from_this.so", RTLD_NOW | RTLD_LOCAL);
   2047   ASSERT_TRUE((reinterpret_cast<uintptr_t>(handle) & 1) != 0)
   2048           << "dlopen should return odd value for the handle";
   2049   dlclose(handle);
   2050 }
   2051 
   2052 TEST(dlext, dlopen_handle_value_app_compat) {
   2053   android_set_application_target_sdk_version(__ANDROID_API_M__);
   2054   void* handle = dlopen("libtest_dlsym_from_this.so", RTLD_NOW | RTLD_LOCAL);
   2055   ASSERT_TRUE(reinterpret_cast<uintptr_t>(handle) % sizeof(uintptr_t) == 0)
   2056           << "dlopen should return valid pointer";
   2057   dlclose(handle);
   2058 }
   2059