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
This commit is contained in:
Adrian Roos 2017-04-12 13:03:04 -07:00
parent 7afd4cdf82
commit cb4ed1bdb9
3 changed files with 47 additions and 7 deletions

View file

@ -158,6 +158,12 @@ status_t BnGateKeeperService::onTransact(
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);
}

View file

@ -33,6 +33,7 @@ public:
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 @@ public:
* 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;
};
// ----------------------------------------------------------------------------

View file

@ -56,19 +56,13 @@ static const String16 DUMP_PERMISSION("android.permission.DUMP");
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 @@ public:
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 @@ public:
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 @@ public:
}
}
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 @@ public:
private:
sp<IGatekeeper> hw_device;
UniquePtr<SoftGateKeeperDevice> soft_device;
bool clear_state_if_needed_done;
};
}// namespace android