DO NOT MERGE Check fingerprint client against top activity in auth callback am: bb5706541d

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/12769285

Change-Id: I732e5a1c826f728b683078884e02b0756ae59ae2
This commit is contained in:
Curtis Belmonte
2020-11-09 23:29:34 +00:00
committed by Automerger Merge Worker

View File

@@ -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
*/