1 /* 2 * Copyright (C) 2012 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 #if defined(__BIONIC__) 20 #include <android-base/properties.h> 21 #endif 22 23 #include <dlfcn.h> 24 #include <libgen.h> 25 #include <limits.h> 26 #include <stdio.h> 27 #include <stdint.h> 28 29 #include <string> 30 #include <iostream> 31 #include <fstream> 32 33 #include "gtest_globals.h" 34 #include "TemporaryFile.h" 35 #include "utils.h" 36 37 extern "C" int main_global_default_serial() { 38 return 3370318; 39 } 40 41 extern "C" int main_global_protected_serial() { 42 return 2716057; 43 } 44 45 // The following functions are defined in DT_NEEDED 46 // libdl_preempt_test.so library. 47 48 // This one calls main_global_default_serial 49 extern "C" int main_global_default_get_serial(); 50 51 // This one calls main_global_protected_serial 52 extern "C" int main_global_protected_get_serial(); 53 54 // This one calls lib_global_default_serial 55 extern "C" int lib_global_default_get_serial(); 56 57 // This one calls lib_global_protected_serial 58 extern "C" int lib_global_protected_get_serial(); 59 60 // This test verifies that the global default function 61 // main_global_default_serial() is preempted by 62 // the function defined above. 63 TEST(dl, main_preempts_global_default) { 64 ASSERT_EQ(3370318, main_global_default_get_serial()); 65 } 66 67 // This one makes sure that the global protected 68 // symbols do not get preempted 69 TEST(dl, main_does_not_preempt_global_protected) { 70 ASSERT_EQ(3370318, main_global_protected_get_serial()); 71 } 72 73 // check same things for lib 74 TEST(dl, lib_preempts_global_default) { 75 ASSERT_EQ(3370318, lib_global_default_get_serial()); 76 } 77 78 TEST(dl, lib_does_not_preempt_global_protected) { 79 ASSERT_EQ(3370318, lib_global_protected_get_serial()); 80 } 81 82 TEST(dl, exec_linker) { 83 #if defined(__BIONIC__) 84 #if defined(__LP64__) 85 static constexpr const char* kPathToLinker = "/system/bin/linker64"; 86 #else 87 static constexpr const char* kPathToLinker = "/system/bin/linker"; 88 #endif 89 ExecTestHelper eth; 90 std::string expected_output = std::string("This is ") + kPathToLinker + 91 ", the helper program for dynamic executables.\n"; 92 eth.SetArgs( { kPathToLinker, nullptr }); 93 eth.Run([&]() { execve(kPathToLinker, eth.GetArgs(), eth.GetEnv()); }, 0, expected_output.c_str()); 94 #endif 95 } 96 97 TEST(dl, preinit_system_calls) { 98 #if defined(__BIONIC__) 99 std::string helper = get_testlib_root() + 100 "/preinit_syscall_test_helper/preinit_syscall_test_helper"; 101 chmod(helper.c_str(), 0755); // TODO: "x" lost in CTS, b/34945607 102 ExecTestHelper eth; 103 eth.SetArgs({ helper.c_str(), nullptr }); 104 eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, nullptr); 105 #endif 106 } 107 108 TEST(dl, xfail_preinit_getauxval) { 109 #if defined(__BIONIC__) 110 std::string helper = get_testlib_root() + 111 "/preinit_getauxval_test_helper/preinit_getauxval_test_helper"; 112 chmod(helper.c_str(), 0755); // TODO: "x" lost in CTS, b/34945607 113 ExecTestHelper eth; 114 eth.SetArgs({ helper.c_str(), nullptr }); 115 eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, nullptr); 116 #endif 117 } 118 119 120 TEST(dl, exec_without_ld_preload) { 121 #if defined(__BIONIC__) 122 std::string helper = get_testlib_root() + 123 "/ld_preload_test_helper/ld_preload_test_helper"; 124 chmod(helper.c_str(), 0755); 125 ExecTestHelper eth; 126 eth.SetArgs({ helper.c_str(), nullptr }); 127 eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, "12345"); 128 #endif 129 } 130 131 TEST(dl, exec_with_ld_preload) { 132 #if defined(__BIONIC__) 133 std::string helper = get_testlib_root() + 134 "/ld_preload_test_helper/ld_preload_test_helper"; 135 std::string env = std::string("LD_PRELOAD=") + get_testlib_root() + "/ld_preload_test_helper_lib2.so"; 136 chmod(helper.c_str(), 0755); 137 ExecTestHelper eth; 138 eth.SetArgs({ helper.c_str(), nullptr }); 139 eth.SetEnv({ env.c_str(), nullptr }); 140 // ld_preload_test_helper calls get_value_from_lib() and returns the value. 141 // The symbol is defined by two libs: ld_preload_test_helper_lib.so and 142 // ld_preloaded_lib.so. The former is DT_NEEDED and the latter is LD_PRELOADED 143 // via this execution. The main executable is linked to the LD_PRELOADED lib 144 // and the value given from the lib is returned. 145 eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, "54321"); 146 #endif 147 } 148 149 150 // ld_config_test_helper must fail because it is depending on a lib which is not 151 // in the search path 152 // 153 // Call sequence is... 154 // _helper -- (get_value_from_lib()) --> 155 // _lib1.so -- (get_value_from_another_lib()) --> 156 // _lib2.so (returns 12345) 157 // The two libs are in ns2/ subdir. 158 TEST(dl, exec_without_ld_config_file) { 159 #if defined(__BIONIC__) 160 std::string error_message = "CANNOT LINK EXECUTABLE \"" + get_testlib_root() + "/ld_config_test_helper/ld_config_test_helper\": library \"ld_config_test_helper_lib1.so\" not found\n"; 161 std::string helper = get_testlib_root() + 162 "/ld_config_test_helper/ld_config_test_helper"; 163 chmod(helper.c_str(), 0755); 164 ExecTestHelper eth; 165 eth.SetArgs({ helper.c_str(), nullptr }); 166 eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, EXIT_FAILURE, error_message.c_str()); 167 #endif 168 } 169 170 #if defined(__BIONIC__) 171 extern "C" void android_get_LD_LIBRARY_PATH(char*, size_t); 172 static void create_ld_config_file(const char* config_file) { 173 char default_search_paths[PATH_MAX]; 174 android_get_LD_LIBRARY_PATH(default_search_paths, sizeof(default_search_paths)); 175 176 std::ofstream fout(config_file, std::ios::out); 177 fout << "dir.test = " << get_testlib_root() << "/ld_config_test_helper/" << std::endl 178 << "[test]" << std::endl 179 << "additional.namespaces = ns2" << std::endl 180 << "namespace.default.search.paths = " << get_testlib_root() << std::endl 181 << "namespace.default.links = ns2" << std::endl 182 << "namespace.default.link.ns2.shared_libs = libc.so:libm.so:libdl.so:ld_config_test_helper_lib1.so" << std::endl 183 << "namespace.ns2.search.paths = " << default_search_paths << ":" << get_testlib_root() << "/ns2" << std::endl; 184 fout.close(); 185 } 186 #endif 187 188 #if defined(__BIONIC__) 189 static bool is_debuggable_build() { 190 return android::base::GetBoolProperty("ro.debuggable", false); 191 } 192 #endif 193 194 // _lib1.so and _lib2.so are now searchable by having another namespace 'ns2' 195 // whose search paths include the 'ns2/' subdir. 196 TEST(dl, exec_with_ld_config_file) { 197 #if defined(__BIONIC__) 198 if (!is_debuggable_build()) { 199 // LD_CONFIG_FILE is not supported on user build 200 return; 201 } 202 std::string helper = get_testlib_root() + 203 "/ld_config_test_helper/ld_config_test_helper"; 204 TemporaryFile config_file; 205 create_ld_config_file(config_file.filename); 206 std::string env = std::string("LD_CONFIG_FILE=") + config_file.filename; 207 chmod(helper.c_str(), 0755); 208 ExecTestHelper eth; 209 eth.SetArgs({ helper.c_str(), nullptr }); 210 eth.SetEnv({ env.c_str(), nullptr }); 211 eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, "12345"); 212 #endif 213 } 214 215 // _lib3.so has same symbol as lib2.so but returns 54321. _lib3.so is 216 // LD_PRELOADed. This test is to ensure LD_PRELOADed libs are available to 217 // additional namespaces other than the default namespace. 218 TEST(dl, exec_with_ld_config_file_with_ld_preload) { 219 #if defined(__BIONIC__) 220 if (!is_debuggable_build()) { 221 // LD_CONFIG_FILE is not supported on user build 222 return; 223 } 224 std::string helper = get_testlib_root() + 225 "/ld_config_test_helper/ld_config_test_helper"; 226 TemporaryFile config_file; 227 create_ld_config_file(config_file.filename); 228 std::string env = std::string("LD_CONFIG_FILE=") + config_file.filename; 229 std::string env2 = std::string("LD_PRELOAD=") + get_testlib_root() + "/ld_config_test_helper_lib3.so"; 230 chmod(helper.c_str(), 0755); 231 ExecTestHelper eth; 232 eth.SetArgs({ helper.c_str(), nullptr }); 233 eth.SetEnv({ env.c_str(), env2.c_str(), nullptr }); 234 eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, "54321"); 235 #endif 236 } 237 238 // ensures that LD_CONFIG_FILE env var does not work for production builds. 239 // The test input is the same as exec_with_ld_config_file, but it must fail in 240 // this case. 241 TEST(dl, disable_ld_config_file) { 242 #if defined(__BIONIC__) 243 if (getuid() == 0) { 244 // when executed from the shell (e.g. not as part of CTS), skip the test. 245 // This test is only for CTS. 246 return; 247 } 248 if (is_debuggable_build()) { 249 // Skip the test for non production devices 250 return; 251 } 252 253 std::string error_message = "CANNOT LINK EXECUTABLE \"" + get_testlib_root() + "/ld_config_test_helper/ld_config_test_helper\": library \"ld_config_test_helper_lib1.so\" not found\n"; 254 std::string helper = get_testlib_root() + 255 "/ld_config_test_helper/ld_config_test_helper"; 256 TemporaryFile config_file; 257 create_ld_config_file(config_file.filename); 258 std::string env = std::string("LD_CONFIG_FILE=") + config_file.filename; 259 chmod(helper.c_str(), 0755); 260 ExecTestHelper eth; 261 eth.SetArgs({ helper.c_str(), nullptr }); 262 eth.SetEnv({ env.c_str(), nullptr }); 263 eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, EXIT_FAILURE, error_message.c_str()); 264 #endif 265 } 266