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