Add ADB root service changes
Co-authored-by: Alessandro Astone <ales.astone@gmail.com>
Co-authored-by: Bruno Martins <bgcngm@gmail.com>
Co-authored-by: dianlujitao <dianlujitao@lineageos.org>
Co-authored-by: Luca Stefani <luca.stefani.ge1@gmail.com>
Co-authored-by: LuK1337 <priv.luk@gmail.com>
Co-authored-by: nift4 <nift4@protonmail.com>
Change-Id: Ie8db34705d36f3e9f2c53617ec59a26087cbcc87
diff --git a/Android.bp b/Android.bp
index 7a7e491..c099e71 100644
--- a/Android.bp
+++ b/Android.bp
@@ -43,7 +43,6 @@
"-Wall",
"-Wextra",
"-Werror",
- "-Wexit-time-destructors",
"-Wno-non-virtual-dtor",
"-Wno-unused-parameter",
"-Wno-missing-field-initializers",
@@ -696,11 +695,13 @@
"daemon/restart_service.cpp",
],
shared_libs: [
+ "libbinder_ndk",
"libmdnssd",
"libselinux",
],
static_libs: [
"android_trade_in_mode_flags_cc_lib",
+ "adbroot_aidl_interface-ndk",
],
},
recovery: {
@@ -708,11 +709,13 @@
"daemon/abb_service.cpp",
],
exclude_shared_libs: [
+ "libbinder_ndk",
"libadb_pairing_auth",
"libadb_pairing_connection",
],
exclude_static_libs: [
"android_trade_in_mode_flags_cc_lib",
+ "adbroot_aidl_interface-ndk",
],
},
},
@@ -835,8 +838,26 @@
],
target: {
android: {
+ shared_libs: [
+ "libbinder_ndk",
+ ],
+
static_libs: [
"android_trade_in_mode_flags_cc_lib",
+ "adbroot_aidl_interface-ndk",
+ ],
+ },
+
+ recovery: {
+ exclude_shared_libs: [
+ "libadb_pairing_auth",
+ "libadb_pairing_connection",
+ "libbinder_ndk",
+ ],
+
+ exclude_static_libs: [
+ "android_trade_in_mode_flags_cc_lib",
+ "adbroot_aidl_interface-ndk",
],
},
},
@@ -879,6 +900,30 @@
}
cc_binary {
+ name: "adb_root",
+ srcs: [
+ "root/adbroot_service.cpp",
+ "root/main.cpp",
+ ],
+ init_rc: [
+ "root/adb_root.rc",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbinder",
+ "libbinder_ndk",
+ "libcutils",
+ "liblog",
+ "libutils",
+ "packagemanager_aidl-cpp",
+ ],
+ static_libs: [
+ "adbroot_aidl_interface-ndk",
+ ],
+ system_ext_specific: true,
+}
+
+cc_binary {
name: "abb",
defaults: ["adbd_defaults"],
@@ -1117,3 +1162,34 @@
"fastdeploy/testdata/sample.cd",
],
}
+
+aidl_interface {
+ name: "adbroot_aidl_interface",
+ unstable: true,
+ local_include_dir: "aidl",
+ srcs: [
+ "aidl/android/adbroot/IADBRootService.aidl",
+ ],
+ backend: {
+ cpp: {
+ enabled: false,
+ },
+ java: {
+ enabled: false,
+ },
+ ndk: {
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.adbd",
+ ],
+ min_sdk_version: "30",
+ },
+ },
+}
+
+filegroup {
+ name: "adbrootservice_aidl",
+ srcs: [
+ "aidl/android/adbroot/IADBRootService.aidl",
+ ],
+}
diff --git a/aidl/android/adbroot/IADBRootService.aidl b/aidl/android/adbroot/IADBRootService.aidl
new file mode 100644
index 0000000..ada5ce8
--- /dev/null
+++ b/aidl/android/adbroot/IADBRootService.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.adbroot;
+
+/** {@hide} */
+@PermissionManuallyEnforced
+interface IADBRootService {
+ boolean isSupported();
+ void setEnabled(boolean enabled);
+ boolean getEnabled();
+}
diff --git a/daemon/restart_service.cpp b/daemon/restart_service.cpp
index 16d2627..c942c1f 100644
--- a/daemon/restart_service.cpp
+++ b/daemon/restart_service.cpp
@@ -16,6 +16,11 @@
#define TRACE_TAG SERVICES
+#if defined(__ANDROID__) && !defined(__ANDROID_RECOVERY__)
+#include <aidl/android/adbroot/IADBRootService.h>
+#include <android/binder_manager.h>
+#endif
+
#include "sysdeps.h"
#include <unistd.h>
@@ -33,10 +38,33 @@
WriteFdExactly(fd.get(), "adbd is already running as root\n");
return;
}
+
+#if defined(__ANDROID__) && !defined(__ANDROID_RECOVERY__)
+ ndk::SpAIBinder binder = ndk::SpAIBinder(AServiceManager_getService("adbroot_service"));
+ std::shared_ptr<aidl::android::adbroot::IADBRootService> service =
+ aidl::android::adbroot::IADBRootService::fromBinder(binder);
+ if (!service) {
+ LOG(ERROR) << "Failed to get adbroot_service interface";
+ return;
+ }
+#endif
+
+#if defined(__ANDROID__) && !defined(__ANDROID_RECOVERY__)
+ bool enabled = false;
+ if (auto status = service->getEnabled(&enabled); !status.isOk()) {
+#endif
if (!__android_log_is_debuggable()) {
WriteFdExactly(fd.get(), "adbd cannot run as root in production builds\n");
return;
}
+#if defined(__ANDROID__) && !defined(__ANDROID_RECOVERY__)
+ }
+ if (!enabled) {
+ WriteFdExactly(fd, "ADB Root access is disabled by system setting - "
+ "enable in Settings -> System -> Developer options\n");
+ return;
+ }
+#endif
LOG(INFO) << "adbd restarting as root";
android::base::SetProperty("service.adb.root", "1");
diff --git a/root/adb_root.rc b/root/adb_root.rc
new file mode 100644
index 0000000..8c65c0b
--- /dev/null
+++ b/root/adb_root.rc
@@ -0,0 +1,7 @@
+service adb_root /system_ext/bin/adb_root
+ class main
+ user root
+ group root
+
+on post-fs-data
+ mkdir /data/adbroot 0700 root root
diff --git a/root/adbroot_service.cpp b/root/adbroot_service.cpp
new file mode 100644
index 0000000..ff30f4b
--- /dev/null
+++ b/root/adbroot_service.cpp
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/binder_manager.h>
+#include <android/content/pm/IPackageManagerNative.h>
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <android-base/strings.h>
+#include <binder/IBinder.h>
+#include <binder/IServiceManager.h>
+#include <cutils/multiuser.h>
+#include <private/android_filesystem_config.h>
+
+#include "adbroot_service.h"
+
+namespace {
+const std::string kStoragePath = "/data/adbroot/";
+const std::string kEnabled = "enabled";
+
+static ndk::ScopedAStatus SecurityException(const std::string& msg) {
+ LOG(ERROR) << msg;
+ return ndk::ScopedAStatus(AStatus_fromExceptionCodeWithMessage(EX_SECURITY, msg.c_str()));
+}
+} // anonymous namespace
+
+namespace android {
+static bool isAutomotive() {
+ sp<IServiceManager> serviceManager = defaultServiceManager();
+ if (serviceManager.get() == nullptr) {
+ LOG(ERROR) << "Unable to access native ServiceManager";
+ return false;
+ }
+
+ sp<content::pm::IPackageManagerNative> packageManager;
+ sp<IBinder> binder = serviceManager->waitForService(String16("package_native"));
+ packageManager = interface_cast<content::pm::IPackageManagerNative>(binder);
+ if (packageManager == nullptr) {
+ LOG(ERROR) << "Unable to access native PackageManager";
+ return false;
+ }
+
+ bool isAutomotive = false;
+ binder::Status status =
+ packageManager->hasSystemFeature(String16("android.hardware.type.automotive"), 0,
+ &isAutomotive);
+ if (!status.isOk()) {
+ LOG(ERROR) << "Calling hasSystemFeature failed: " << status.exceptionMessage().c_str();
+ return false;
+ }
+
+ return isAutomotive;
+}
+} // namespace android
+
+namespace aidl {
+namespace android {
+namespace adbroot {
+
+using ::android::AutoMutex;
+using ::android::base::ReadFileToString;
+using ::android::base::SetProperty;
+using ::android::base::Trim;
+using ::android::base::WriteStringToFile;
+
+static inline bool isAutomotive(uid_t uid) {
+ appid_t appid = multiuser_get_app_id(uid);
+
+ return appid == AID_SYSTEM && ::android::isAutomotive();
+}
+
+ADBRootService::ADBRootService() : enabled_(false) {
+ std::string buf;
+ if (ReadFileToString(kStoragePath + kEnabled, &buf)) {
+ enabled_ = Trim(buf) == "1";
+ }
+}
+
+void ADBRootService::Register() {
+ auto service = ndk::SharedRefBase::make<ADBRootService>();
+ binder_status_t status = AServiceManager_addService(
+ service->asBinder().get(), getServiceName());
+
+ if (status != STATUS_OK) {
+ LOG(FATAL) << "Could not register adbroot service: " << status;
+ }
+}
+
+ndk::ScopedAStatus ADBRootService::isSupported(bool* _aidl_return) {
+ uid_t uid = AIBinder_getCallingUid();
+ if (uid != AID_SYSTEM && uid != AID_SHELL && !isAutomotive(uid)) {
+ return SecurityException("Caller must be system or shell");
+ }
+
+ AutoMutex _l(lock_);
+ *_aidl_return = __android_log_is_debuggable();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ADBRootService::setEnabled(bool enabled) {
+ uid_t uid = AIBinder_getCallingUid();
+ if (uid != AID_SYSTEM && !isAutomotive(uid)) {
+ return SecurityException("Caller must be system");
+ }
+
+ AutoMutex _l(lock_);
+
+ if (enabled_ != enabled) {
+ enabled_ = enabled;
+ WriteStringToFile(std::to_string(enabled), kStoragePath + kEnabled);
+
+ // Turning off adb root, restart adbd.
+ if (!enabled) {
+ SetProperty("service.adb.root", "0");
+ SetProperty("ctl.restart", "adbd");
+ }
+ }
+
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ADBRootService::getEnabled(bool* _aidl_return) {
+ uid_t uid = AIBinder_getCallingUid();
+ if (uid != AID_SYSTEM && uid != AID_SHELL && !isAutomotive(uid)) {
+ return SecurityException("Caller must be system or shell");
+ }
+
+ AutoMutex _l(lock_);
+ *_aidl_return = enabled_;
+ return ndk::ScopedAStatus::ok();
+}
+
+} // namespace adbroot
+} // namespace android
+} // namespace aidl
diff --git a/root/adbroot_service.h b/root/adbroot_service.h
new file mode 100644
index 0000000..9881542
--- /dev/null
+++ b/root/adbroot_service.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/adbroot/BnADBRootService.h>
+#include <android/binder_status.h>
+#include <log/log_properties.h>
+#include <utils/Mutex.h>
+
+namespace aidl {
+namespace android {
+namespace adbroot {
+
+using ::android::Mutex;
+
+class ADBRootService : public BnADBRootService {
+ public:
+ ADBRootService();
+
+ static void Register();
+
+ ndk::ScopedAStatus isSupported(bool* _aidl_return) override;
+ ndk::ScopedAStatus setEnabled(bool enabled) override;
+ ndk::ScopedAStatus getEnabled(bool* _aidl_return) override;
+
+ static char const* getServiceName() { return "adbroot_service"; }
+ private:
+ bool enabled_;
+ Mutex lock_;
+};
+
+} // namespace adbroot
+} // namespace android
+} // namespace aidl
diff --git a/root/main.cpp b/root/main.cpp
new file mode 100644
index 0000000..7de0945
--- /dev/null
+++ b/root/main.cpp
@@ -0,0 +1,31 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include <android/binder_process.h>
+#include <android-base/logging.h>
+
+#include "adbroot_service.h"
+
+int main(int /* argc */, char** argv) {
+ android::base::InitLogging(argv, android::base::LogdLogger(android::base::SYSTEM));
+
+ aidl::android::adbroot::ADBRootService::Register();
+
+ ABinderProcess_startThreadPool();
+ ABinderProcess_joinThreadPool();
+
+ return 0;
+}