Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cb4ed1bd authored by Adrian Roos's avatar Adrian Roos
Browse files

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
parent 7afd4cdf
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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);
    }
+7 −0
Original line number Diff line number Diff line
@@ -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;
};

// ----------------------------------------------------------------------------
+34 −7
Original line number Diff line number Diff line
@@ -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