Credential FRP: keep gatekeeperd credentials after reset
Gatekeeperd now delays clearing all user credentials
until the device setup is complete or we enroll a new
credential (whichever comes first).
Bug: 36814845
Test: Set lockscreen credential, "adb reboot-bootloader && fastboot -w", "adb shell am start -a android.app.action.CONFIRM_FRP_CREDENTIAL", verify that credential still works
Change-Id: If2ad78ff5b80a6ddffd997be0949b03ed11797f4
diff --git a/gatekeeperd/IGateKeeperService.cpp b/gatekeeperd/IGateKeeperService.cpp
index 95fbfd1..1c339f4 100644
--- a/gatekeeperd/IGateKeeperService.cpp
+++ b/gatekeeperd/IGateKeeperService.cpp
@@ -158,6 +158,12 @@
reply->writeNoException();
return NO_ERROR;
}
+ case REPORT_DEVICE_SETUP_COMPLETE: {
+ CHECK_INTERFACE(IGateKeeperService, data, reply);
+ reportDeviceSetupComplete();
+ reply->writeNoException();
+ return NO_ERROR;
+ }
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/gatekeeperd/IGateKeeperService.h b/gatekeeperd/IGateKeeperService.h
index f070486..2816efc 100644
--- a/gatekeeperd/IGateKeeperService.h
+++ b/gatekeeperd/IGateKeeperService.h
@@ -33,6 +33,7 @@
VERIFY_CHALLENGE = IBinder::FIRST_CALL_TRANSACTION + 2,
GET_SECURE_USER_ID = IBinder::FIRST_CALL_TRANSACTION + 3,
CLEAR_SECURE_USER_ID = IBinder::FIRST_CALL_TRANSACTION + 4,
+ REPORT_DEVICE_SETUP_COMPLETE = IBinder::FIRST_CALL_TRANSACTION + 5,
};
enum {
@@ -95,6 +96,12 @@
* Clears the secure user ID associated with the user.
*/
virtual void clearSecureUserId(uint32_t uid) = 0;
+
+ /**
+ * Notifies gatekeeper that device setup has been completed and any potentially still existing
+ * state from before a factory reset can be cleaned up (if it has not been already).
+ */
+ virtual void reportDeviceSetupComplete() = 0;
};
// ----------------------------------------------------------------------------
diff --git a/gatekeeperd/gatekeeperd.cpp b/gatekeeperd/gatekeeperd.cpp
index e6eb3bc..c6369f9 100644
--- a/gatekeeperd/gatekeeperd.cpp
+++ b/gatekeeperd/gatekeeperd.cpp
@@ -56,19 +56,13 @@
class GateKeeperProxy : public BnGateKeeperService {
public:
GateKeeperProxy() {
+ clear_state_if_needed_done = false;
hw_device = IGatekeeper::getService();
if (hw_device == nullptr) {
ALOGW("falling back to software GateKeeper");
soft_device.reset(new SoftGateKeeperDevice());
}
-
- if (mark_cold_boot()) {
- ALOGI("cold boot: clearing state");
- if (hw_device != nullptr) {
- hw_device->deleteAllUsers([](const GatekeeperResponse &){});
- }
- }
}
virtual ~GateKeeperProxy() {
@@ -86,6 +80,21 @@
close(fd);
}
+ void clear_state_if_needed() {
+ if (clear_state_if_needed_done) {
+ return;
+ }
+
+ if (mark_cold_boot()) {
+ ALOGI("cold boot: clearing state");
+ if (hw_device != nullptr) {
+ hw_device->deleteAllUsers([](const GatekeeperResponse &){});
+ }
+ }
+
+ clear_state_if_needed_done = true;
+ }
+
bool mark_cold_boot() {
const char *filename = ".coldboot";
if (access(filename, F_OK) == -1) {
@@ -140,6 +149,10 @@
return PERMISSION_DENIED;
}
+ // Make sure to clear any state from before factory reset as soon as a credential is
+ // enrolled (which may happen during device setup).
+ clear_state_if_needed();
+
// need a desired password to enroll
if (desired_password_length == 0) return -EINVAL;
@@ -354,6 +367,18 @@
}
}
+ virtual void reportDeviceSetupComplete() {
+ IPCThreadState* ipc = IPCThreadState::self();
+ const int calling_pid = ipc->getCallingPid();
+ const int calling_uid = ipc->getCallingUid();
+ if (!PermissionCache::checkPermission(KEYGUARD_PERMISSION, calling_pid, calling_uid)) {
+ ALOGE("%s: permission denied for [%d:%d]", __func__, calling_pid, calling_uid);
+ return;
+ }
+
+ clear_state_if_needed();
+ }
+
virtual status_t dump(int fd, const Vector<String16> &) {
IPCThreadState* ipc = IPCThreadState::self();
const int pid = ipc->getCallingPid();
@@ -376,6 +401,8 @@
private:
sp<IGatekeeper> hw_device;
UniquePtr<SoftGateKeeperDevice> soft_device;
+
+ bool clear_state_if_needed_done;
};
}// namespace android