diff options
| author | 2020-11-09 21:36:29 +0000 | |
|---|---|---|
| committer | 2020-11-09 21:36:29 +0000 | |
| commit | 1a673296ae4f700d45d0b66111ed3f4d60deb47c (patch) | |
| tree | 4d7cc0c99d8cff3df12043fd4fcc2c67b89cab68 | |
| parent | 09b6ab6bdf745a56a0528f395d81a32fb854afe6 (diff) | |
| parent | 7786f4908fc213447c53dee5f06f830eebc9f110 (diff) | |
Merge "DO NOT MERGE Check fingerprint client against top activity in auth callback" into oc-mr1-dev
| -rw-r--r-- | services/core/java/com/android/server/fingerprint/AuthenticationClient.java | 94 |
1 files changed, 91 insertions, 3 deletions
diff --git a/services/core/java/com/android/server/fingerprint/AuthenticationClient.java b/services/core/java/com/android/server/fingerprint/AuthenticationClient.java index 370e569f2598..0c73c4410cb2 100644 --- a/services/core/java/com/android/server/fingerprint/AuthenticationClient.java +++ b/services/core/java/com/android/server/fingerprint/AuthenticationClient.java @@ -16,18 +16,29 @@ package com.android.server.fingerprint; -import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint; -import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import static android.Manifest.permission.USE_FINGERPRINT; +import android.app.ActivityManager; +import android.app.IActivityManager; +import android.content.ComponentName; import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint; import android.hardware.fingerprint.Fingerprint; import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.IFingerprintServiceReceiver; import android.os.IBinder; import android.os.RemoteException; +import android.util.EventLog; import android.util.Slog; +import com.android.internal.R; +import com.android.internal.logging.MetricsLogger; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; + +import java.util.List; + /** * A class to keep track of the authentication state for a given client. */ @@ -53,6 +64,56 @@ public abstract class AuthenticationClient extends ClientMonitor { boolean result = false; boolean authenticated = fingerId != 0; + // Ensure authentication only succeeds if the client activity is on top or is keyguard. + boolean isBackgroundAuth = false; + if (authenticated && !isKeyguard(getContext(), getOwnerString())) { + final ActivityManager activityManager = + (ActivityManager) getContext().getSystemService(Context.ACTIVITY_SERVICE); + final IActivityManager activityManagerService = activityManager != null + ? activityManager.getService() + : null; + if (activityManagerService == null) { + Slog.e(TAG, "Unable to get activity manager service"); + isBackgroundAuth = true; + } else { + try { + final List<ActivityManager.RunningTaskInfo> tasks = + activityManagerService.getTasks(1, 0 /* flags */); + if (tasks == null || tasks.isEmpty()) { + Slog.e(TAG, "No running tasks reported"); + isBackgroundAuth = true; + } else { + final ComponentName topActivity = tasks.get(0).topActivity; + if (topActivity == null) { + Slog.e(TAG, "Unable to get top activity"); + isBackgroundAuth = true; + } else { + final String topPackage = topActivity.getPackageName(); + if (!topPackage.contentEquals(getOwnerString())) { + Slog.e(TAG, "Background authentication detected, top: " + topPackage + + ", client: " + this); + isBackgroundAuth = true; + } + } + } + } catch (RemoteException e) { + Slog.e(TAG, "Unable to get running tasks", e); + isBackgroundAuth = true; + } + } + } + + // Fail authentication if we can't confirm the client activity is on top. + if (isBackgroundAuth) { + Slog.e(TAG, "Failing possible background authentication"); + authenticated = false; + + // SafetyNet logging for exploitation attempts of b/159249069. + final ApplicationInfo appInfo = getContext().getApplicationInfo(); + EventLog.writeEvent(0x534e4554, "159249069", appInfo != null ? appInfo.uid : -1, + "Attempted background authentication"); + } + IFingerprintServiceReceiver receiver = getReceiver(); if (receiver != null) { try { @@ -61,6 +122,14 @@ public abstract class AuthenticationClient extends ClientMonitor { if (!authenticated) { receiver.onAuthenticationFailed(getHalDeviceId()); } else { + // SafetyNet logging for b/159249069 if constraint is violated. + if (isBackgroundAuth) { + final ApplicationInfo appInfo = getContext().getApplicationInfo(); + EventLog.writeEvent(0x534e4554, "159249069", + appInfo != null ? appInfo.uid : -1, + "Successful background authentication! Receiver notified"); + } + if (DEBUG) { Slog.v(TAG, "onAuthenticated(owner=" + getOwnerString() + ", id=" + fingerId + ", gp=" + groupId + ")"); @@ -98,6 +167,14 @@ public abstract class AuthenticationClient extends ClientMonitor { } result |= lockoutMode != LOCKOUT_NONE; // in a lockout mode } else { + // SafetyNet logging for b/159249069 if constraint is violated. + if (isBackgroundAuth) { + final ApplicationInfo appInfo = getContext().getApplicationInfo(); + EventLog.writeEvent(0x534e4554, "159249069", + appInfo != null ? appInfo.uid : -1, + "Successful background authentication! Lockout reset"); + } + if (receiver != null) { vibrateSuccess(); } @@ -107,6 +184,17 @@ public abstract class AuthenticationClient extends ClientMonitor { return result; } + private static boolean isKeyguard(Context context, String clientPackage) { + final boolean hasPermission = context.checkCallingOrSelfPermission(USE_FINGERPRINT) + == PackageManager.PERMISSION_GRANTED; + + final ComponentName keyguardComponent = ComponentName.unflattenFromString( + context.getResources().getString(R.string.config_keyguardComponent)); + final String keyguardPackage = keyguardComponent != null + ? keyguardComponent.getPackageName() : null; + return hasPermission && keyguardPackage != null && keyguardPackage.equals(clientPackage); + } + /** * Start authentication */ |