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:
@@ -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
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user