// ensures that LD_CONFIG_FILE env var does not work for production builds. // The test input is the same as exec_with_ld_config_file, but it must fail in // this case. TEST(dl, disable_ld_config_file) { #if defined(__BIONIC__) if (getuid() == 0) { // when executed from the shell (e.g. not as part of CTS), skip the test. // This test is only for CTS. return; } if (is_debuggable_build()) { // Skip the test for non production devices return; } 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"; std::string helper = get_testlib_root() + "/ld_config_test_helper/ld_config_test_helper"; TemporaryFile config_file; create_ld_config_file(config_file.filename); std::string env = std::string("LD_CONFIG_FILE=") + config_file.filename; chmod(helper.c_str(), 0755); ExecTestHelper eth; eth.SetArgs({ helper.c_str(), nullptr }); eth.SetEnv({ env.c_str(), nullptr }); eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, EXIT_FAILURE, error_message.c_str()); #endif }
TEST(dl, preinit_system_calls) { #if defined(__BIONIC__) std::string helper = get_testlib_root() + "/preinit_syscall_test_helper/preinit_syscall_test_helper"; chmod(helper.c_str(), 0755); // TODO: "x" lost in CTS, b/34945607 ExecTestHelper eth; eth.SetArgs({ helper.c_str(), nullptr }); eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, nullptr); #endif }
TEST(dl, exec_without_ld_preload) { #if defined(__BIONIC__) std::string helper = get_testlib_root() + "/ld_preload_test_helper/ld_preload_test_helper"; chmod(helper.c_str(), 0755); ExecTestHelper eth; eth.SetArgs({ helper.c_str(), nullptr }); eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, "12345"); #endif }
// ld_config_test_helper must fail because it is depending on a lib which is not // in the search path // // Call sequence is... // _helper -- (get_value_from_lib()) --> // _lib1.so -- (get_value_from_another_lib()) --> // _lib2.so (returns 12345) // The two libs are in ns2/ subdir. TEST(dl, exec_without_ld_config_file) { #if defined(__BIONIC__) 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"; std::string helper = get_testlib_root() + "/ld_config_test_helper/ld_config_test_helper"; chmod(helper.c_str(), 0755); ExecTestHelper eth; eth.SetArgs({ helper.c_str(), nullptr }); eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, EXIT_FAILURE, error_message.c_str()); #endif }
TEST(dl, exec_linker) { #if defined(__BIONIC__) #if defined(__LP64__) static constexpr const char* kPathToLinker = "/system/bin/linker64"; #else static constexpr const char* kPathToLinker = "/system/bin/linker"; #endif ExecTestHelper eth; std::string expected_output = std::string("This is ") + kPathToLinker + ", the helper program for dynamic executables.\n"; eth.SetArgs( { kPathToLinker, nullptr }); eth.Run([&]() { execve(kPathToLinker, eth.GetArgs(), eth.GetEnv()); }, 0, expected_output.c_str()); #endif }
TEST(dl, exec_with_ld_preload) { #if defined(__BIONIC__) std::string helper = get_testlib_root() + "/ld_preload_test_helper/ld_preload_test_helper"; std::string env = std::string("LD_PRELOAD=") + get_testlib_root() + "/ld_preload_test_helper_lib2.so"; chmod(helper.c_str(), 0755); ExecTestHelper eth; eth.SetArgs({ helper.c_str(), nullptr }); eth.SetEnv({ env.c_str(), nullptr }); // ld_preload_test_helper calls get_value_from_lib() and returns the value. // The symbol is defined by two libs: ld_preload_test_helper_lib.so and // ld_preloaded_lib.so. The former is DT_NEEDED and the latter is LD_PRELOADED // via this execution. The main executable is linked to the LD_PRELOADED lib // and the value given from the lib is returned. eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, "54321"); #endif }
// _lib1.so and _lib2.so are now searchable by having another namespace 'ns2' // whose search paths include the 'ns2/' subdir. TEST(dl, exec_with_ld_config_file) { #if defined(__BIONIC__) if (!is_debuggable_build()) { // LD_CONFIG_FILE is not supported on user build return; } std::string helper = get_testlib_root() + "/ld_config_test_helper/ld_config_test_helper"; TemporaryFile config_file; create_ld_config_file(config_file.filename); std::string env = std::string("LD_CONFIG_FILE=") + config_file.filename; chmod(helper.c_str(), 0755); ExecTestHelper eth; eth.SetArgs({ helper.c_str(), nullptr }); eth.SetEnv({ env.c_str(), nullptr }); eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, "12345"); #endif }