Only allow AID_SYSTEM and AID_ROOT to access IGsiService.
Bug: N/A
Test: manual test
Change-Id: Ic19b24a32ca8a42a23bc37ac72da8128d5f0ff57
diff --git a/gsi_service.cpp b/gsi_service.cpp
index f24f478..d5c85ca 100644
--- a/gsi_service.cpp
+++ b/gsi_service.cpp
@@ -36,6 +36,7 @@
#include <libdm/dm.h>
#include <libfiemap_writer/fiemap_writer.h>
#include <logwrap/logwrap.h>
+#include <private/android_filesystem_config.h>
#include "file_paths.h"
#include "libgsi_private.h"
@@ -47,6 +48,7 @@
using namespace android::dm;
using namespace android::fs_mgr;
using namespace android::fiemap_writer;
+using android::base::StringPrintf;
static constexpr char kUserdataDevice[] = "/dev/block/by-name/userdata";
@@ -75,8 +77,15 @@
PostInstallCleanup();
}
+#define ENFORCE_UID \
+ do { \
+ binder::Status status = CheckUid(); \
+ if (!status.isOk()) return status; \
+ } while (0)
+
binder::Status GsiService::startGsiInstall(int64_t gsiSize, int64_t userdataSize, bool wipeUserdata,
int* _aidl_return) {
+ ENFORCE_UID;
std::lock_guard<std::mutex> guard(main_lock_);
// Make sure any interrupted installations are cleaned up.
@@ -100,6 +109,7 @@
binder::Status GsiService::commitGsiChunkFromStream(const android::os::ParcelFileDescriptor& stream,
int64_t bytes, bool* _aidl_return) {
+ ENFORCE_UID;
std::lock_guard<std::mutex> guard(main_lock_);
*_aidl_return = CommitGsiChunk(stream.get(), bytes);
@@ -130,6 +140,7 @@
}
binder::Status GsiService::getInstallProgress(::android::gsi::GsiProgress* _aidl_return) {
+ ENFORCE_UID;
std::lock_guard<std::mutex> guard(progress_lock_);
*_aidl_return = progress_;
@@ -138,6 +149,7 @@
binder::Status GsiService::commitGsiChunkFromMemory(const std::vector<uint8_t>& bytes,
bool* _aidl_return) {
+ ENFORCE_UID;
std::lock_guard<std::mutex> guard(main_lock_);
*_aidl_return = CommitGsiChunk(bytes.data(), bytes.size());
@@ -145,6 +157,7 @@
}
binder::Status GsiService::setGsiBootable(int* _aidl_return) {
+ ENFORCE_UID;
std::lock_guard<std::mutex> guard(main_lock_);
if (installing_) {
@@ -156,6 +169,7 @@
}
binder::Status GsiService::removeGsiInstall(bool* _aidl_return) {
+ ENFORCE_UID;
std::lock_guard<std::mutex> guard(main_lock_);
// Just in case an install was left hanging.
@@ -171,6 +185,7 @@
}
binder::Status GsiService::disableGsiInstall(bool* _aidl_return) {
+ ENFORCE_UID;
std::lock_guard<std::mutex> guard(main_lock_);
*_aidl_return = DisableGsiInstall();
@@ -178,6 +193,7 @@
}
binder::Status GsiService::isGsiRunning(bool* _aidl_return) {
+ ENFORCE_UID;
std::lock_guard<std::mutex> guard(main_lock_);
*_aidl_return = IsGsiRunning();
@@ -185,6 +201,7 @@
}
binder::Status GsiService::isGsiInstalled(bool* _aidl_return) {
+ ENFORCE_UID;
std::lock_guard<std::mutex> guard(main_lock_);
*_aidl_return = IsGsiInstalled();
@@ -192,6 +209,7 @@
}
binder::Status GsiService::isGsiInstallInProgress(bool* _aidl_return) {
+ ENFORCE_UID;
std::lock_guard<std::mutex> guard(main_lock_);
*_aidl_return = installing_;
@@ -199,6 +217,7 @@
}
binder::Status GsiService::cancelGsiInstall(bool* _aidl_return) {
+ ENFORCE_UID;
std::lock_guard<std::mutex> guard(main_lock_);
if (!installing_) {
@@ -215,6 +234,7 @@
}
binder::Status GsiService::getUserdataImageSize(int64_t* _aidl_return) {
+ ENFORCE_UID;
*_aidl_return = -1;
if (installing_) {
@@ -250,6 +270,18 @@
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();
+ }
+
+ auto message = StringPrintf("UID %d is not expected UID %d", uid, expected_uid);
+ return binder::Status::fromExceptionCode(binder::Status::EX_SECURITY,
+ String8(message.c_str()));
+}
+
void GsiService::PostInstallCleanup() {
// This must be closed before unmapping partitions.
system_fd_ = {};