Loading services/core/java/com/android/server/fingerprint/AuthenticationClient.java +99 −0 Original line number Diff line number Diff line Loading @@ -16,7 +16,15 @@ package com.android.server.fingerprint; import static android.Manifest.permission.USE_BIOMETRIC; 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.biometrics.BiometricPrompt; import android.hardware.biometrics.IBiometricPromptReceiver; Loading @@ -26,12 +34,16 @@ import android.hardware.fingerprint.IFingerprintServiceReceiver; import android.os.Bundle; 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 com.android.internal.statusbar.IStatusBarService; import java.util.List; /** * A class to keep track of the authentication state for a given client. */ Loading Loading @@ -156,10 +168,68 @@ 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); 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"); } // If the fingerprint dialog is showing, notify authentication succeeded if (mBundle != null) { try { if (authenticated) { // 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! Dialog notified"); } mStatusBarService.onFingerprintAuthenticated(); } else { mStatusBarService.onFingerprintHelp(getContext().getResources().getString( Loading @@ -178,6 +248,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 + ")"); Loading Loading @@ -226,6 +304,13 @@ 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(); } Loading @@ -236,6 +321,20 @@ public abstract class AuthenticationClient extends ClientMonitor { return result; } private static boolean isKeyguard(Context context, String clientPackage) { final boolean hasFingerPermission = context.checkCallingOrSelfPermission(USE_FINGERPRINT) == PackageManager.PERMISSION_GRANTED; final boolean hasBiometricPermission = context.checkCallingOrSelfPermission(USE_BIOMETRIC) == PackageManager.PERMISSION_GRANTED; final boolean hasPermission = hasFingerPermission || hasBiometricPermission; 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 */ Loading Loading
services/core/java/com/android/server/fingerprint/AuthenticationClient.java +99 −0 Original line number Diff line number Diff line Loading @@ -16,7 +16,15 @@ package com.android.server.fingerprint; import static android.Manifest.permission.USE_BIOMETRIC; 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.biometrics.BiometricPrompt; import android.hardware.biometrics.IBiometricPromptReceiver; Loading @@ -26,12 +34,16 @@ import android.hardware.fingerprint.IFingerprintServiceReceiver; import android.os.Bundle; 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 com.android.internal.statusbar.IStatusBarService; import java.util.List; /** * A class to keep track of the authentication state for a given client. */ Loading Loading @@ -156,10 +168,68 @@ 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); 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"); } // If the fingerprint dialog is showing, notify authentication succeeded if (mBundle != null) { try { if (authenticated) { // 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! Dialog notified"); } mStatusBarService.onFingerprintAuthenticated(); } else { mStatusBarService.onFingerprintHelp(getContext().getResources().getString( Loading @@ -178,6 +248,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 + ")"); Loading Loading @@ -226,6 +304,13 @@ 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(); } Loading @@ -236,6 +321,20 @@ public abstract class AuthenticationClient extends ClientMonitor { return result; } private static boolean isKeyguard(Context context, String clientPackage) { final boolean hasFingerPermission = context.checkCallingOrSelfPermission(USE_FINGERPRINT) == PackageManager.PERMISSION_GRANTED; final boolean hasBiometricPermission = context.checkCallingOrSelfPermission(USE_BIOMETRIC) == PackageManager.PERMISSION_GRANTED; final boolean hasPermission = hasFingerPermission || hasBiometricPermission; 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 */ Loading