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