diff --git a/CleanSpec.mk b/CleanSpec.mk index 73379cded..c84bd24c4 100644 --- a/CleanSpec.mk +++ b/CleanSpec.mk @@ -89,3 +89,4 @@ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/product_services) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/recovery/root/product_services) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/debug_ramdisk/product_services) $(call add-clean-step, find $(PRODUCT_OUT) -type l -name "charger" -print0 | xargs -0 rm -f) +$(call add-clean-step, rm -f $(PRODUCT_OUT)/system/bin/adbd) diff --git a/adb/Android.bp b/adb/Android.bp index d14fe56bb..d60590780 100644 --- a/adb/Android.bp +++ b/adb/Android.bp @@ -356,11 +356,12 @@ cc_library_static { generated_headers: ["platform_tools_version"], static_libs: [ - "libadbconnection_server", "libdiagnose_usb", ], shared_libs: [ + "libadbconnection_server", + "libadbd_auth", "libasyncio", "libbase", "libcrypto", @@ -408,12 +409,13 @@ cc_library { ], static_libs: [ - "libadbconnection_server", "libadbd_core", "libdiagnose_usb", ], shared_libs: [ + "libadbconnection_server", + "libadbd_auth", "libasyncio", "libbase", "libcrypto", @@ -460,6 +462,8 @@ cc_library { ], shared_libs: [ + "libadbconnection_server", + "libadbd_auth", "libadbd_services", "libasyncio", "libbase", @@ -492,23 +496,34 @@ cc_binary { keep_symbols: true, }, - shared_libs: [ + stl: "libc++_static", + static_libs: [ "libadbd", + "libadbd_auth", "libadbd_services", + "libasyncio", "libbase", "libcap", - "libcrypto", + "libcrypto_utils", "libcutils", + "libdiagnose_usb", "liblog", + "libmdnssd", "libminijail", "libselinux", ], + + shared_libs: [ + "libadbconnection_server", + "libcrypto", + ], } phony { name: "adbd_system_binaries", required: [ "abb", + "libadbd_auth", "reboot", "set-verity-state", ] @@ -521,53 +536,6 @@ phony { ], } -cc_binary { - name: "static_adbd", - defaults: ["adbd_defaults", "host_adbd_supported"], - - recovery_available: false, - static_executable: true, - host_supported: false, - - srcs: [ - "daemon/main.cpp", - ], - - cflags: [ - "-D_GNU_SOURCE", - "-Wno-deprecated-declarations", - ], - - strip: { - keep_symbols: true, - }, - - static_libs: [ - "libadbconnection_server", - "libadbd", - "libadbd_services", - "libasyncio", - "libavb_user", - "libbase", - "libbootloader_message", - "libcap", - "libcrypto_static", - "libcrypto_utils", - "libcutils", - "libdiagnose_usb", - "libext4_utils", - "libfec", - "libfec_rs", - "libfs_mgr", - "liblog", - "liblp", - "libmdnssd", - "libminijail", - "libselinux", - "libsquashfs_utils", - ], -} - cc_binary { name: "abb", @@ -615,6 +583,7 @@ cc_test { static_libs: [ "libadbd", + "libadbd_auth", "libbase", "libcutils", "libcrypto_utils", @@ -759,3 +728,39 @@ cc_test_host { "fastdeploy/testdata/sample.cd", ], } + +prebuilt_etc { + name: "com.android.adbd.ld.config.txt", + src: "apex/ld.config.txt", + filename: "ld.config.txt", + installable: false, +} + +apex { + name: "com.android.adbd", + manifest: "apex/apex_manifest.json", + + binaries: ["adbd"], + prebuilts: ["com.android.adbd.init.rc", "com.android.adbd.ld.config.txt"], + + key: "com.android.adbd.key", + certificate: ":com.android.adbd.certificate", +} + +apex_key { + name: "com.android.adbd.key", + public_key: "apex/com.android.adbd.avbpubkey", + private_key: "apex/com.android.adbd.pem", +} + +android_app_certificate { + name: "com.android.adbd.certificate", + certificate: "apex/com.android.adbd", +} + +prebuilt_etc { + name: "com.android.adbd.init.rc", + src: "apex/adbd.rc", + filename: "init.rc", + installable: false, +} diff --git a/adb/adb.cpp b/adb/adb.cpp index 1ec145b25..9b663be91 100644 --- a/adb/adb.cpp +++ b/adb/adb.cpp @@ -300,6 +300,7 @@ static void handle_new_connection(atransport* t, apacket* p) { handle_online(t); #else if (!auth_required) { + LOG(INFO) << "authentication not required"; handle_online(t); send_connect(t); } else { diff --git a/adb/apex/adbd.rc b/adb/apex/adbd.rc new file mode 100644 index 000000000..9cb072bcc --- /dev/null +++ b/adb/apex/adbd.rc @@ -0,0 +1,6 @@ +service adbd /apex/com.android.adbd/bin/adbd --root_seclabel=u:r:su:s0 + class core + socket adbd seqpacket 660 system system + disabled + override + seclabel u:r:adbd:s0 diff --git a/adb/apex/apex_manifest.json b/adb/apex/apex_manifest.json new file mode 100644 index 000000000..ff2df127b --- /dev/null +++ b/adb/apex/apex_manifest.json @@ -0,0 +1,4 @@ +{ + "name": "com.android.adbd", + "version": 1 +} diff --git a/adb/apex/com.android.adbd.avbpubkey b/adb/apex/com.android.adbd.avbpubkey new file mode 100644 index 000000000..06235bd1f Binary files /dev/null and b/adb/apex/com.android.adbd.avbpubkey differ diff --git a/adb/apex/com.android.adbd.pem b/adb/apex/com.android.adbd.pem new file mode 100644 index 000000000..2c9a86079 --- /dev/null +++ b/adb/apex/com.android.adbd.pem @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY----- diff --git a/adb/apex/com.android.adbd.pk8 b/adb/apex/com.android.adbd.pk8 new file mode 100644 index 000000000..cdddc3fdf Binary files /dev/null and b/adb/apex/com.android.adbd.pk8 differ diff --git a/adb/apex/com.android.adbd.x509.pem b/adb/apex/com.android.adbd.x509.pem new file mode 100644 index 000000000..bb85c1d11 --- /dev/null +++ b/adb/apex/com.android.adbd.x509.pem @@ -0,0 +1,35 @@ +-----BEGIN CERTIFICATE----- +MIIGHzCCBAegAwIBAgIUW8npFHXBP+wsEAesGMBxaV7TScAwDQYJKoZIhvcNAQEL +BQAwgZ0xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQH +DA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRy +b2lkMRkwFwYDVQQDDBBjb20uYW5kcm9pZC5hZGJkMSIwIAYJKoZIhvcNAQkBFhNh +bmRyb2lkQGFuZHJvaWQuY29tMCAXDTE5MDgxNTE5MzkxM1oYDzQ3NTcwNzExMTkz +OTEzWjCBnTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNV +BAcMDU1vdW50YWluIFZpZXcxEDAOBgNVBAoMB0FuZHJvaWQxEDAOBgNVBAsMB0Fu +ZHJvaWQxGTAXBgNVBAMMEGNvbS5hbmRyb2lkLmFkYmQxIjAgBgkqhkiG9w0BCQEW +E2FuZHJvaWRAYW5kcm9pZC5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQC6zbUeWi5vNA6vCC4FBrJQ9re4UexP6TabsDYvWpFBoCluvMkT2ZRmpXMF +W7EzQ5VmuUvZgLYVHuJmnvHIV3uaRc2VE1SV+spjWTRt+6DtsAN7irR5K66POWMp ++tr5hASdQBVOJdebimsepy0pH6sXREvanrrFzkSM/2Ho0unlwWJ5Y4jcnvdkVHI5 +Ks0vifLmX4y5mYgv1dcXYWzyYx39f8HyePv0cjRhYXiIEYZ49KWU4MjryvQe/mAu +MQuMp901BLps2W1+oKyPPA4DV69KUXgF66RFfsjjkJJ/CSeQGzTuez+UWzFk3Duc +6MmbiL1LTki3vyyVtjW1rYFO2s+M6Pa5NZWHgA55uUxiJ987WPyK9lWnMsY6YeKa +FDBfS1JUzXGPzVncgM7LLvzAEibLdhjII88NsJvzPoHK0SluSn+E7t7iGO1fTjkD +Js94iUJAp8OQ4GwkcTVgtEAR+NXzownNjHJ6qpiq6tXRqXdBqSat/glf01AgNDtz +9AGeW7Mz6FqTdOzg3U4lu77+CGd3SZTuQk8C8PUDNhqhQX5H2qhr90bakGaXuYfE +rWFzIjrVdJIznV1BimOCay5HyyHab4FWlVhAvslEQb2BpHRyi2lhe0laupOpmN44 +LzfjFM18bi2GashIi2OQuYDyAeT5mGtR2g8mC7g44H6dH+wTfQIDAQABo1MwUTAd +BgNVHQ4EFgQU7lyyxPO5SOOh9a5O0l4+RjckcgcwHwYDVR0jBBgwFoAU7lyyxPO5 +SOOh9a5O0l4+RjckcgcwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC +AgEAStsOy8bkbZg/Ygx47bPkLSz0cJIvATxTChUGOabkz+brLis88ABVWVP0IXps +tlLlZR5cjXBJguE7GJXzKPWzQZuB8+YwcGHG6QDFpfdMeGrxPDhwNfGy236ArVnx +K0v1IIxoZRZ0P7aubk3xwUAPgsmT5ayZCKu+dqlEy5B6ioKEsr7Y2RRT/8ifERNm +cjS9AhcyWrp4R3cjy2iA/RpdsPFwE5ac3I+GtUB4D2up5aDMsy85i9t2/1kuTUaA +9UHwGXCpcqP8f8BqeLzuxDzYkAvkntlNxbXn1cbn+dTRIOCBoDbtSeqtxhWooOUH +RQROeRsB7iicdYJJRge0+WyR+216AKUSQPE6/rT0Ifr06ZRwi22/YyySpwuO3SNA ++yWffh+f4h31Dz+p6pu8wjbMDkq4LnCWyjLwfF/yhvWhwwm5+KPAEhvJABeHQc+3 +cslOC9dlXJm9sPoUC7ghmUiFsCmN2hIzQrr2QoK0Obh0AGexOvOAw9cqtOdZQncB +bqC8c4sVYScVxwDWkg0lNfRMC5boPjBsl7+M2CC1ukgVpXTyDOEjMWILrBXfYCDX +unBH3kbKQOfL5RT0nE1Lkt1rn5qAWMJg4mvS4QuIurbRtEoj3QYQadF9md4qJXs0 +TvqvY8iEC4xrWU2SQn1K3PutXgaLP9/b6Cy1SBrhBX+AC5s= +-----END CERTIFICATE----- diff --git a/adb/apex/ld.config.txt b/adb/apex/ld.config.txt new file mode 100644 index 000000000..85f9b298d --- /dev/null +++ b/adb/apex/ld.config.txt @@ -0,0 +1,51 @@ +# Copyright (C) 2019 The Android Open Source Project +# +# Bionic loader config file for the adbd APEX. + +dir.adbd = /apex/com.android.adbd/bin/ + +[adbd] +additional.namespaces = platform,art,adbd + +namespace.default.isolated = true +namespace.default.links = art,adbd,platform +namespace.default.link.art.shared_libs = libadbconnection_server.so +namespace.default.link.platform.allow_all_shared_libs = true +namespace.default.link.adbd.allow_all_shared_libs = true + +############################################################################### +# "adbd" APEX namespace +############################################################################### +namespace.adbd.isolated = true +namespace.adbd.search.paths = /apex/com.android.adbd/${LIB} +namespace.adbd.asan.search.paths = /apex/com.android.adbd/${LIB} +namespace.adbd.links = platform +namespace.adbd.link.platform.allow_all_shared_libs = true + +############################################################################### +# "art" APEX namespace: used for libadbdconnection_server +############################################################################### +namespace.art.isolated = true +namespace.art.search.paths = /apex/com.android.art/${LIB} +namespace.art.asan.search.paths = /apex/com.android.art/${LIB} +namespace.art.links = platform +namespace.art.link.platform.allow_all_shared_libs = true + +############################################################################### +# "platform" namespace: used for NDK libraries, and libadbd_auth +############################################################################### +namespace.platform.isolated = true +namespace.platform.search.paths = /system/${LIB} +namespace.platform.asan.search.paths = /data/asan/system/${LIB} + +# /system/lib/libc.so, etc are symlinks to +# /apex/com.android.runtime/lib/bionic/libc.so, etc. Add the path to the +# permitted paths because linker uses realpath(3) to check the accessibility +# of the lib. We could add this to search.paths instead but that makes the +# resolution of bionic libs be dependent on the order of /system/lib and +# /apex/.../lib/bionic in search.paths. If the latter is after the former, +# then the latter is never tried because libc.so is always found in +# /system/lib but fails to pass the accessibility test because of its realpath. +# It's better to not depend on the ordering if possible. +namespace.platform.permitted.paths = /apex/com.android.runtime/${LIB}/bionic +namespace.platform.asan.permitted.paths = /apex/com.android.runtime/${LIB}/bionic diff --git a/adb/daemon/auth.cpp b/adb/daemon/auth.cpp index 7a3a4f5c5..2e84ce6b9 100644 --- a/adb/daemon/auth.cpp +++ b/adb/daemon/auth.cpp @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -38,85 +39,57 @@ #include #include -static fdevent* listener_fde = nullptr; -static fdevent* framework_fde = nullptr; -static auto& framework_mutex = *new std::mutex(); -static int framework_fd GUARDED_BY(framework_mutex) = -1; -static auto& connected_keys GUARDED_BY(framework_mutex) = *new std::vector; +static AdbdAuthContext* auth_ctx; static void adb_disconnected(void* unused, atransport* t); static struct adisconnect adb_disconnect = {adb_disconnected, nullptr}; -static atransport* adb_transport; -static bool needs_retry = false; bool auth_required = true; -bool adbd_auth_verify(const char* token, size_t token_size, const std::string& sig, - std::string* auth_key) { - static constexpr const char* key_paths[] = { "/adb_keys", "/data/misc/adb/adb_keys", nullptr }; - - for (const auto& path : key_paths) { - if (access(path, R_OK) == 0) { - LOG(INFO) << "Loading keys from " << path; - std::string content; - if (!android::base::ReadFileToString(path, &content)) { - PLOG(ERROR) << "Couldn't read " << path; - continue; - } - - for (const auto& line : android::base::Split(content, "\n")) { - if (line.empty()) continue; - *auth_key = line; - // TODO: do we really have to support both ' ' and '\t'? - char* sep = strpbrk(const_cast(line.c_str()), " \t"); - if (sep) *sep = '\0'; - - // b64_pton requires one additional byte in the target buffer for - // decoding to succeed. See http://b/28035006 for details. - uint8_t keybuf[ANDROID_PUBKEY_ENCODED_SIZE + 1]; - if (b64_pton(line.c_str(), keybuf, sizeof(keybuf)) != ANDROID_PUBKEY_ENCODED_SIZE) { - LOG(ERROR) << "Invalid base64 key " << line.c_str() << " in " << path; - continue; - } - - RSA* key = nullptr; - if (!android_pubkey_decode(keybuf, ANDROID_PUBKEY_ENCODED_SIZE, &key)) { - LOG(ERROR) << "Failed to parse key " << line.c_str() << " in " << path; - continue; - } - - bool verified = - (RSA_verify(NID_sha1, reinterpret_cast(token), token_size, - reinterpret_cast(sig.c_str()), sig.size(), - key) == 1); - RSA_free(key); - if (verified) return true; - } - } - } - auth_key->clear(); - return false; +static void IteratePublicKeys(std::function f) { + adbd_auth_get_public_keys( + auth_ctx, + [](const char* public_key, size_t len, void* arg) { + return (*static_cast(arg))(std::string_view(public_key, len)); + }, + &f); } -static bool adbd_send_key_message_locked(std::string_view msg_type, std::string_view key) - REQUIRES(framework_mutex) { - if (framework_fd < 0) { - LOG(ERROR) << "Client not connected to send msg_type " << msg_type; - return false; - } - std::string msg = std::string(msg_type) + std::string(key); - int msg_len = msg.length(); - if (msg_len >= static_cast(MAX_FRAMEWORK_PAYLOAD)) { - LOG(ERROR) << "Key too long (" << msg_len << ")"; - return false; - } +bool adbd_auth_verify(const char* token, size_t token_size, const std::string& sig, + std::string* auth_key) { + bool authorized = false; + auth_key->clear(); - LOG(DEBUG) << "Sending '" << msg << "'"; - if (!WriteFdExactly(framework_fd, msg.c_str(), msg_len)) { - PLOG(ERROR) << "Failed to write " << msg_type; - return false; - } - return true; + IteratePublicKeys([&](std::string_view public_key) { + // TODO: do we really have to support both ' ' and '\t'? + std::vector split = android::base::Split(std::string(public_key), " \t"); + uint8_t keybuf[ANDROID_PUBKEY_ENCODED_SIZE + 1]; + const std::string& pubkey = split[0]; + if (b64_pton(pubkey.c_str(), keybuf, sizeof(keybuf)) != ANDROID_PUBKEY_ENCODED_SIZE) { + LOG(ERROR) << "Invalid base64 key " << pubkey; + return true; + } + + RSA* key = nullptr; + if (!android_pubkey_decode(keybuf, ANDROID_PUBKEY_ENCODED_SIZE, &key)) { + LOG(ERROR) << "Failed to parse key " << pubkey; + return true; + } + + bool verified = + (RSA_verify(NID_sha1, reinterpret_cast(token), token_size, + reinterpret_cast(sig.c_str()), sig.size(), key) == 1); + RSA_free(key); + if (verified) { + *auth_key = public_key; + authorized = true; + return false; + } + + return true; + }); + + return authorized; } static bool adbd_auth_generate_token(void* token, size_t token_size) { @@ -127,113 +100,6 @@ static bool adbd_auth_generate_token(void* token, size_t token_size) { return okay; } -static void adb_disconnected(void* unused, atransport* t) { - LOG(INFO) << "ADB disconnect"; - adb_transport = nullptr; - needs_retry = false; - { - std::lock_guard lock(framework_mutex); - if (framework_fd >= 0) { - adbd_send_key_message_locked("DC", t->auth_key); - } - connected_keys.erase(std::remove(connected_keys.begin(), connected_keys.end(), t->auth_key), - connected_keys.end()); - } -} - -static void framework_disconnected() { - LOG(INFO) << "Framework disconnect"; - if (framework_fde) { - fdevent_destroy(framework_fde); - { - std::lock_guard lock(framework_mutex); - framework_fd = -1; - } - } -} - -static void adbd_auth_event(int fd, unsigned events, void*) { - if (events & FDE_READ) { - char response[2]; - int ret = unix_read(fd, response, sizeof(response)); - if (ret <= 0) { - framework_disconnected(); - } else if (ret == 2 && response[0] == 'O' && response[1] == 'K') { - if (adb_transport) { - adbd_auth_verified(adb_transport); - } - } - } -} - -void adbd_auth_confirm_key(atransport* t) { - if (!adb_transport) { - adb_transport = t; - t->AddDisconnect(&adb_disconnect); - } - - { - std::lock_guard lock(framework_mutex); - if (framework_fd < 0) { - LOG(ERROR) << "Client not connected"; - needs_retry = true; - return; - } - - adbd_send_key_message_locked("PK", t->auth_key); - } -} - -static void adbd_auth_listener(int fd, unsigned events, void* data) { - int s = adb_socket_accept(fd, nullptr, nullptr); - if (s < 0) { - PLOG(ERROR) << "Failed to accept"; - return; - } - - { - std::lock_guard lock(framework_mutex); - if (framework_fd >= 0) { - LOG(WARNING) << "adb received framework auth socket connection again"; - framework_disconnected(); - } - - framework_fd = s; - framework_fde = fdevent_create(framework_fd, adbd_auth_event, nullptr); - fdevent_add(framework_fde, FDE_READ); - - if (needs_retry) { - needs_retry = false; - send_auth_request(adb_transport); - } - - // if a client connected before the framework was available notify the framework of the - // connected key now. - if (!connected_keys.empty()) { - for (const auto& key : connected_keys) { - adbd_send_key_message_locked("CK", key); - } - } - } -} - -void adbd_notify_framework_connected_key(atransport* t) { - if (!adb_transport) { - adb_transport = t; - t->AddDisconnect(&adb_disconnect); - } - { - std::lock_guard lock(framework_mutex); - if (std::find(connected_keys.begin(), connected_keys.end(), t->auth_key) == - connected_keys.end()) { - connected_keys.push_back(t->auth_key); - } - if (framework_fd >= 0) { - adbd_send_key_message_locked("CK", t->auth_key); - } - } -} - void adbd_cloexec_auth_socket() { int fd = android_get_control_socket("adbd"); if (fd == -1) { @@ -243,20 +109,23 @@ void adbd_cloexec_auth_socket() { fcntl(fd, F_SETFD, FD_CLOEXEC); } +static void adbd_auth_key_authorized(void* arg, uint64_t id) { + LOG(INFO) << "adb client authorized"; + auto* transport = static_cast(arg); + transport->auth_id = id; + adbd_auth_verified(transport); +} + void adbd_auth_init(void) { - int fd = android_get_control_socket("adbd"); - if (fd == -1) { - PLOG(ERROR) << "Failed to get adbd socket"; - return; - } - - if (listen(fd, 4) == -1) { - PLOG(ERROR) << "Failed to listen on '" << fd << "'"; - return; - } - - listener_fde = fdevent_create(fd, adbd_auth_listener, nullptr); - fdevent_add(listener_fde, FDE_READ); + AdbdAuthCallbacks cb; + cb.version = 1; + cb.callbacks.v1.key_authorized = adbd_auth_key_authorized; + auth_ctx = adbd_auth_new(&cb); + std::thread([]() { + adb_thread_setname("adbd auth"); + adbd_auth_run(auth_ctx); + LOG(FATAL) << "auth thread terminated"; + }).detach(); } void send_auth_request(atransport* t) { @@ -280,3 +149,18 @@ void adbd_auth_verified(atransport* t) { handle_online(t); send_connect(t); } + +static void adb_disconnected(void* unused, atransport* t) { + LOG(INFO) << "ADB disconnect"; + adbd_auth_notify_disconnect(auth_ctx, t->auth_id); +} + +void adbd_auth_confirm_key(atransport* t) { + LOG(INFO) << "prompting user to authorize key"; + t->AddDisconnect(&adb_disconnect); + adbd_auth_prompt_user(auth_ctx, t->auth_key.data(), t->auth_key.size(), t); +} + +void adbd_notify_framework_connected_key(atransport* t) { + adbd_auth_notify_auth(auth_ctx, t->auth_key.data(), t->auth_key.size()); +} diff --git a/adb/daemon/main.cpp b/adb/daemon/main.cpp index cbb5e693f..7277cc829 100644 --- a/adb/daemon/main.cpp +++ b/adb/daemon/main.cpp @@ -218,8 +218,6 @@ int adbd_main(int server_port) { } #endif - adbd_auth_init(); - // Our external storage path may be different than apps, since // we aren't able to bind mount after dropping root. const char* adb_external_storage = getenv("ADB_EXTERNAL_STORAGE"); @@ -234,6 +232,9 @@ int adbd_main(int server_port) { drop_privileges(server_port); #endif + // adbd_auth_init will spawn a thread, so we need to defer it until after selinux transitions. + adbd_auth_init(); + bool is_usb = false; #if defined(__ANDROID__) diff --git a/adb/transport.h b/adb/transport.h index c38cb1d8b..89d76b8c9 100644 --- a/adb/transport.h +++ b/adb/transport.h @@ -277,8 +277,11 @@ class atransport { std::string device; std::string devpath; +#if !ADB_HOST // Used to provide the key to the framework. std::string auth_key; + uint64_t auth_id; +#endif bool IsTcpDevice() const { return type == kTransportLocal; } diff --git a/liblog/liblog.map.txt b/liblog/liblog.map.txt index ce4c53c82..aea33507f 100644 --- a/liblog/liblog.map.txt +++ b/liblog/liblog.map.txt @@ -51,7 +51,7 @@ LIBLOG_M { LIBLOG_O { global: __android_log_is_loggable_len; - __android_log_is_debuggable; # vndk + __android_log_is_debuggable; # apex vndk }; LIBLOG_Q { @@ -61,15 +61,15 @@ LIBLOG_Q { __android_log_bwrite; # apex __android_log_close; # apex __android_log_security; # apex - android_log_reset; #vndk - android_log_parser_reset; #vndk + __android_log_security_bswrite; # apex + android_log_reset; # vndk + android_log_parser_reset; # vndk }; LIBLOG_PRIVATE { global: __android_log_pmsg_file_read; __android_log_pmsg_file_write; - __android_log_security_bswrite; __android_logger_get_buffer_size; __android_logger_property_get_bool; android_openEventTagMap; diff --git a/rootdir/init.usb.rc b/rootdir/init.usb.rc index b6cba901e..688d9ad08 100644 --- a/rootdir/init.usb.rc +++ b/rootdir/init.usb.rc @@ -16,6 +16,7 @@ service adbd /system/bin/adbd --root_seclabel=u:r:su:s0 class core socket adbd seqpacket 660 system system disabled + updatable seclabel u:r:adbd:s0 on boot