Allow enabling or disabling a previously installed GSI as non-root.
Bug: 123716647
Test: manual test
Change-Id: Ia7987ed007e9de57e32df87cd63d999d76402ccc
diff --git a/gsi_service.cpp b/gsi_service.cpp
index d5c85ca..e3c43bc 100644
--- a/gsi_service.cpp
+++ b/gsi_service.cpp
@@ -77,15 +77,21 @@
PostInstallCleanup();
}
-#define ENFORCE_UID \
+#define ENFORCE_SYSTEM \
do { \
binder::Status status = CheckUid(); \
if (!status.isOk()) return status; \
} while (0)
+#define ENFORCE_SYSTEM_OR_SHELL \
+ do { \
+ binder::Status status = CheckUid(AccessLevel::SystemOrShell); \
+ if (!status.isOk()) return status; \
+ } while (0)
+
binder::Status GsiService::startGsiInstall(int64_t gsiSize, int64_t userdataSize, bool wipeUserdata,
int* _aidl_return) {
- ENFORCE_UID;
+ ENFORCE_SYSTEM;
std::lock_guard<std::mutex> guard(main_lock_);
// Make sure any interrupted installations are cleaned up.
@@ -109,7 +115,7 @@
binder::Status GsiService::commitGsiChunkFromStream(const android::os::ParcelFileDescriptor& stream,
int64_t bytes, bool* _aidl_return) {
- ENFORCE_UID;
+ ENFORCE_SYSTEM;
std::lock_guard<std::mutex> guard(main_lock_);
*_aidl_return = CommitGsiChunk(stream.get(), bytes);
@@ -140,7 +146,7 @@
}
binder::Status GsiService::getInstallProgress(::android::gsi::GsiProgress* _aidl_return) {
- ENFORCE_UID;
+ ENFORCE_SYSTEM;
std::lock_guard<std::mutex> guard(progress_lock_);
*_aidl_return = progress_;
@@ -149,7 +155,7 @@
binder::Status GsiService::commitGsiChunkFromMemory(const std::vector<uint8_t>& bytes,
bool* _aidl_return) {
- ENFORCE_UID;
+ ENFORCE_SYSTEM;
std::lock_guard<std::mutex> guard(main_lock_);
*_aidl_return = CommitGsiChunk(bytes.data(), bytes.size());
@@ -157,7 +163,7 @@
}
binder::Status GsiService::setGsiBootable(int* _aidl_return) {
- ENFORCE_UID;
+ ENFORCE_SYSTEM;
std::lock_guard<std::mutex> guard(main_lock_);
if (installing_) {
@@ -169,7 +175,7 @@
}
binder::Status GsiService::removeGsiInstall(bool* _aidl_return) {
- ENFORCE_UID;
+ ENFORCE_SYSTEM_OR_SHELL;
std::lock_guard<std::mutex> guard(main_lock_);
// Just in case an install was left hanging.
@@ -185,7 +191,7 @@
}
binder::Status GsiService::disableGsiInstall(bool* _aidl_return) {
- ENFORCE_UID;
+ ENFORCE_SYSTEM_OR_SHELL;
std::lock_guard<std::mutex> guard(main_lock_);
*_aidl_return = DisableGsiInstall();
@@ -193,7 +199,7 @@
}
binder::Status GsiService::isGsiRunning(bool* _aidl_return) {
- ENFORCE_UID;
+ ENFORCE_SYSTEM_OR_SHELL;
std::lock_guard<std::mutex> guard(main_lock_);
*_aidl_return = IsGsiRunning();
@@ -201,7 +207,7 @@
}
binder::Status GsiService::isGsiInstalled(bool* _aidl_return) {
- ENFORCE_UID;
+ ENFORCE_SYSTEM_OR_SHELL;
std::lock_guard<std::mutex> guard(main_lock_);
*_aidl_return = IsGsiInstalled();
@@ -209,7 +215,7 @@
}
binder::Status GsiService::isGsiInstallInProgress(bool* _aidl_return) {
- ENFORCE_UID;
+ ENFORCE_SYSTEM_OR_SHELL;
std::lock_guard<std::mutex> guard(main_lock_);
*_aidl_return = installing_;
@@ -217,7 +223,7 @@
}
binder::Status GsiService::cancelGsiInstall(bool* _aidl_return) {
- ENFORCE_UID;
+ ENFORCE_SYSTEM;
std::lock_guard<std::mutex> guard(main_lock_);
if (!installing_) {
@@ -234,7 +240,7 @@
}
binder::Status GsiService::getUserdataImageSize(int64_t* _aidl_return) {
- ENFORCE_UID;
+ ENFORCE_SYSTEM;
*_aidl_return = -1;
if (installing_) {
@@ -270,14 +276,20 @@
return binder::Status::ok();
}
-binder::Status GsiService::CheckUid() {
- uid_t expected_uid = AID_SYSTEM;
- uid_t uid = IPCThreadState::self()->getCallingUid();
- if (uid == expected_uid || uid == AID_ROOT) {
- return binder::Status::ok();
+binder::Status GsiService::CheckUid(AccessLevel level) {
+ std::vector<uid_t> allowed_uids{AID_ROOT, AID_SYSTEM};
+ if (level == AccessLevel::SystemOrShell) {
+ allowed_uids.push_back(AID_SHELL);
}
- auto message = StringPrintf("UID %d is not expected UID %d", uid, expected_uid);
+ uid_t uid = IPCThreadState::self()->getCallingUid();
+ for (const auto& allowed_uid : allowed_uids) {
+ if (allowed_uid == uid) {
+ return binder::Status::ok();
+ }
+ }
+
+ auto message = StringPrintf("UID %d is not allowed", uid);
return binder::Status::fromExceptionCode(binder::Status::EX_SECURITY,
String8(message.c_str()));
}