summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Curtis Belmonte <curtislb@google.com> 2020-11-09 21:36:29 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2020-11-09 21:36:29 +0000
commit1a673296ae4f700d45d0b66111ed3f4d60deb47c (patch)
tree4d7cc0c99d8cff3df12043fd4fcc2c67b89cab68
parent09b6ab6bdf745a56a0528f395d81a32fb854afe6 (diff)
parent7786f4908fc213447c53dee5f06f830eebc9f110 (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.java94
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
*/