From 011ee12b1def041d71621da7740bf5784a5e6488 Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Tue, 29 May 2018 16:41:30 +0900 Subject: [PATCH] Shared libs are supported in recovery mode adbd has been built as a static executable since the same binary was copied to the recovery partition where shared library is not supported. However, since we now support shared library in the recovery partition, adbd is built as a dynamic executable. In addition, the dependency from adbd to libdebuggerd_handler is removed as debuggerd is handled by the dynamic linker. A few more modules in /system/core are marked as recovery_available: true as they are transitive dependencies of the dynamic linker. This change also includes ld.config.recovery.txt which is the linker config file for the recovery mode. It is installed to /etc/ld.config.txt and contains linker namespace config for the dynamic binaries under /sbin. Bug: 63673171 Test: `adb reboot recovery; adb devices` shows the device ID Test: Select 'mount /system' in the recovery mode, then `adb shell`. $ lsof -p `pidof adbd` shows that libm.so, libc.so, etc. are loaded from the /lib directory. Change-Id: I363d5a787863f1677ee40afb5d5841321ddaae77 --- CleanSpec.mk | 1 + adb/Android.bp | 4 +--- adb/daemon/main.cpp | 2 -- adb/daemon/shell_service.cpp | 19 +++++++++++++++++++ debuggerd/Android.bp | 9 ++++++++- libutils/Android.bp | 5 +++++ libutils/misc.cpp | 6 +++--- libziparchive/Android.bp | 1 + rootdir/Android.mk | 10 ++++++++++ rootdir/etc/ld.config.recovery.txt | 9 +++++++++ shell_and_utilities/Android.bp | 3 +++ toolbox/Android.bp | 1 + 12 files changed, 61 insertions(+), 9 deletions(-) create mode 100644 rootdir/etc/ld.config.recovery.txt diff --git a/CleanSpec.mk b/CleanSpec.mk index e6f871652..0e43dae31 100644 --- a/CleanSpec.mk +++ b/CleanSpec.mk @@ -77,3 +77,4 @@ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/etc/vndksp.libraries.txt) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/etc/ld.config.txt) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/etc/llndk.libraries.txt) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/etc/vndksp.libraries.txt) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/recovery/root/) diff --git a/adb/Android.bp b/adb/Android.bp index 553473f19..53bf7e34a 100644 --- a/adb/Android.bp +++ b/adb/Android.bp @@ -302,8 +302,6 @@ cc_binary { name: "adbd", defaults: ["adb_defaults"], - // adbd must be static, as it is copied into the recovery image. - static_executable: true, recovery_available: true, srcs: [ @@ -344,7 +342,6 @@ cc_binary { "libselinux", "libsquashfs_utils", "libqemu_pipe", - "libdebuggerd_handler", "libbase", "libcutils", @@ -371,6 +368,7 @@ cc_test { "liblog", "libusb", "libmdnssd", + "libselinux", ], test_suites: ["device-tests"], } diff --git a/adb/daemon/main.cpp b/adb/daemon/main.cpp index 232d9c5fd..c02cafab7 100644 --- a/adb/daemon/main.cpp +++ b/adb/daemon/main.cpp @@ -38,7 +38,6 @@ #include #include -#include "debuggerd/handler.h" #include "selinux/android.h" #include "adb.h" @@ -274,7 +273,6 @@ int main(int argc, char** argv) { close_stdin(); - debuggerd_init(nullptr); adb_trace_init(argv); D("Handling main()"); diff --git a/adb/daemon/shell_service.cpp b/adb/daemon/shell_service.cpp index 401c99c54..56d647a7b 100644 --- a/adb/daemon/shell_service.cpp +++ b/adb/daemon/shell_service.cpp @@ -98,6 +98,7 @@ #include #include #include +#include #include "adb.h" #include "adb_io.h" @@ -343,6 +344,24 @@ bool Subprocess::ForkAndExec(std::string* error) { adb_write(oom_score_adj_fd, oom_score_adj_value, strlen(oom_score_adj_value))); } +#ifdef __ANDROID_RECOVERY__ + // Special routine for recovery. Switch to shell domain when adbd is + // is running with dropped privileged (i.e. not running as root) and + // is built for the recovery mode. This is required because recovery + // rootfs is not labeled and everything is labeled just as rootfs. + char* con = nullptr; + if (getcon(&con) == 0) { + if (!strcmp(con, "u:r:adbd:s0")) { + if (selinux_android_setcon("u:r:shell:s0") < 0) { + LOG(FATAL) << "Could not set SELinux context for subprocess"; + } + } + freecon(con); + } else { + LOG(FATAL) << "Failed to get SELinux context"; + } +#endif + if (command_.empty()) { // Spawn a login shell if we don't have a command. execle(_PATH_BSHELL, "-" _PATH_BSHELL, nullptr, cenv.data()); diff --git a/debuggerd/Android.bp b/debuggerd/Android.bp index 0b1366209..1b20157b3 100644 --- a/debuggerd/Android.bp +++ b/debuggerd/Android.bp @@ -47,6 +47,7 @@ cc_library_shared { cc_library_static { name: "libtombstoned_client_static", defaults: ["debuggerd_defaults"], + recovery_available: true, srcs: [ "tombstoned/tombstoned_client.cpp", "util.cpp", @@ -90,7 +91,6 @@ cc_library_static { cc_library_static { name: "libdebuggerd_handler", defaults: ["debuggerd_defaults"], - recovery_available: true, srcs: ["handler/debuggerd_fallback_nop.cpp"], whole_static_libs: [ @@ -104,6 +104,7 @@ cc_library_static { cc_library_static { name: "libdebuggerd_handler_fallback", defaults: ["debuggerd_defaults"], + recovery_available: true, srcs: [ "handler/debuggerd_fallback.cpp", ], @@ -120,6 +121,12 @@ cc_library_static { "liblzma", "libcutils", ], + target: { + recovery: { + cflags: ["-DNO_LIBDEXFILE_SUPPORT"], + exclude_static_libs: ["libdexfile"], + }, + }, export_include_dirs: ["include"], } diff --git a/libutils/Android.bp b/libutils/Android.bp index 9395ef807..bbfa9d857 100644 --- a/libutils/Android.bp +++ b/libutils/Android.bp @@ -47,6 +47,7 @@ cc_library_headers { cc_defaults { name: "libutils_defaults", vendor_available: true, + recovery_available: true, vndk: { enabled: true, support_system_process: true, @@ -90,6 +91,10 @@ cc_defaults { }, }, + recovery: { + exclude_shared_libs: ["libvndksupport"], + }, + host: { cflags: ["-DLIBUTILS_NATIVE=1"], diff --git a/libutils/misc.cpp b/libutils/misc.cpp index da28dfae6..f07434187 100644 --- a/libutils/misc.cpp +++ b/libutils/misc.cpp @@ -23,7 +23,7 @@ #include #include -#if defined(__ANDROID__) +#if defined(__ANDROID__) && !defined(__ANDROID_RECOVERY__) #include #include #endif @@ -70,7 +70,7 @@ void add_sysprop_change_callback(sysprop_change_callback cb, int priority) { void add_sysprop_change_callback(sysprop_change_callback, int) {} #endif -#if defined(__ANDROID__) +#if defined(__ANDROID__) && !defined(__ANDROID_RECOVERY__) void (*get_report_sysprop_change_func())() { void (*func)() = nullptr; void* handle = android_load_sphal_library("libutils.so", RTLD_NOW); @@ -85,7 +85,7 @@ void (*get_report_sysprop_change_func())() { void report_sysprop_change() { do_report_sysprop_change(); -#if defined(__ANDROID__) +#if defined(__ANDROID__) && !defined(__ANDROID_RECOVERY__) // libutils.so is double loaded; from the default namespace and from the // 'sphal' namespace. Redirect the sysprop change event to the other instance // of libutils.so loaded in the 'sphal' namespace so that listeners attached diff --git a/libziparchive/Android.bp b/libziparchive/Android.bp index 6c0661822..2606aa9e3 100644 --- a/libziparchive/Android.bp +++ b/libziparchive/Android.bp @@ -58,6 +58,7 @@ cc_library { name: "libziparchive", host_supported: true, vendor_available: true, + recovery_available: true, vndk: { enabled: true, }, diff --git a/rootdir/Android.mk b/rootdir/Android.mk index 3c9e5f3c5..70b6a3e2c 100644 --- a/rootdir/Android.mk +++ b/rootdir/Android.mk @@ -305,6 +305,16 @@ endif # ifeq ($(_enforce_vndk_lite_at_runtime),false) _enforce_vndk_at_runtime := _enforce_vndk_lite_at_runtime := +####################################### +# ld.config.txt for recovery +include $(CLEAR_VARS) +LOCAL_MODULE := ld.config.recovery.txt +LOCAL_MODULE_CLASS := ETC +LOCAL_SRC_FILES := etc/ld.config.recovery.txt +LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/etc +LOCAL_MODULE_STEM := ld.config.txt +include $(BUILD_PREBUILT) + ####################################### # llndk.libraries.txt include $(CLEAR_VARS) diff --git a/rootdir/etc/ld.config.recovery.txt b/rootdir/etc/ld.config.recovery.txt new file mode 100644 index 000000000..5d6c01a85 --- /dev/null +++ b/rootdir/etc/ld.config.recovery.txt @@ -0,0 +1,9 @@ +# Copyright (C) 2018 The Android Open Source Project +# +# Bionic loader config file for recovery mode +# + +dir.recovery = /system/bin + +[recovery] +namespace.default.search.paths = /system/${LIB} diff --git a/shell_and_utilities/Android.bp b/shell_and_utilities/Android.bp index 2e42b7099..6438e3d5e 100644 --- a/shell_and_utilities/Android.bp +++ b/shell_and_utilities/Android.bp @@ -12,10 +12,13 @@ phony { "mkshrc_vendor", "reboot", "sh", + "sh.recovery", "sh_vendor", "toolbox", + "toolbox.recovery", "toolbox_vendor", "toybox", + "toybox.recovery", "toybox_vendor", ], } diff --git a/toolbox/Android.bp b/toolbox/Android.bp index 077f5423d..f12c810cd 100644 --- a/toolbox/Android.bp +++ b/toolbox/Android.bp @@ -46,6 +46,7 @@ cc_defaults { cc_binary { name: "toolbox", defaults: ["toolbox_binary_defaults"], + recovery_available: true, } cc_binary {