Loading core/java/android/accounts/Account.java +6 −0 Original line number Diff line number Diff line Loading @@ -88,6 +88,12 @@ public class Account implements Parcelable { public Account(Parcel in) { this.name = in.readString(); this.type = in.readString(); if (TextUtils.isEmpty(name)) { throw new android.os.BadParcelableException("the name must not be empty: " + name); } if (TextUtils.isEmpty(type)) { throw new android.os.BadParcelableException("the type must not be empty: " + type); } this.accessId = in.readString(); if (accessId != null) { synchronized (sAccessedAccounts) { Loading core/java/android/accounts/GrantCredentialsPermissionActivity.java +31 −6 Original line number Diff line number Diff line Loading @@ -16,16 +16,23 @@ package android.accounts; import android.app.Activity; import android.content.res.Resources; import android.os.Bundle; import android.widget.TextView; import android.widget.LinearLayout; import android.view.View; import android.view.LayoutInflater; import android.app.ActivityManager; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.res.Resources; import android.os.Bundle; import android.os.IBinder; import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; import android.text.TextUtils; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.widget.LinearLayout; import android.widget.TextView; import com.android.internal.R; import java.io.IOException; Loading @@ -42,11 +49,15 @@ public class GrantCredentialsPermissionActivity extends Activity implements View private Account mAccount; private String mAuthTokenType; private int mUid; private int mCallingUid; private Bundle mResultBundle = null; protected LayoutInflater mInflater; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().addPrivateFlags( android.view.WindowManager.LayoutParams .PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); setContentView(R.layout.grant_credentials_permission); setTitle(R.string.grant_permissions_header_text); Loading Loading @@ -74,6 +85,20 @@ public class GrantCredentialsPermissionActivity extends Activity implements View return; } try { IBinder activityToken = getActivityToken(); mCallingUid = ActivityManager.getService().getLaunchedFromUid(activityToken); } catch (RemoteException re) { // Couldn't figure out caller details Log.w(getClass().getSimpleName(), "Unable to get caller identity \n" + re); } if (!UserHandle.isSameApp(mCallingUid, Process.SYSTEM_UID) && mCallingUid != mUid) { setResult(Activity.RESULT_CANCELED); finish(); return; } String accountTypeLabel; try { accountTypeLabel = getAccountLabel(mAccount); Loading packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java +41 −30 Original line number Diff line number Diff line Loading @@ -105,6 +105,7 @@ class SaveImageInBackgroundData { imageUri = null; iconSize = 0; } void clearContext() { context = null; } Loading Loading @@ -390,7 +391,8 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> { mPublicNotificationBuilder .setContentTitle(r.getString(R.string.screenshot_saved_title)) .setContentText(r.getString(R.string.screenshot_saved_text)) .setContentIntent(PendingIntent.getActivity(mParams.context, 0, launchIntent, 0)) .setContentIntent(PendingIntent.getActivity(mParams.context, 0, launchIntent, PendingIntent.FLAG_IMMUTABLE)) .setWhen(now) .setAutoCancel(true) .setColor(context.getColor( Loading @@ -398,7 +400,8 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> { mNotificationBuilder .setContentTitle(r.getString(R.string.screenshot_saved_title)) .setContentText(r.getString(R.string.screenshot_saved_text)) .setContentIntent(PendingIntent.getActivity(mParams.context, 0, launchIntent, 0)) .setContentIntent(PendingIntent.getActivity(mParams.context, 0, launchIntent, PendingIntent.FLAG_IMMUTABLE)) .setWhen(now) .setAutoCancel(true) .setColor(context.getColor( Loading Loading @@ -507,7 +510,8 @@ class GlobalScreenshot { mDisplayMatrix = new Matrix(); mScreenshotLayout = layoutInflater.inflate(R.layout.global_screenshot, null); mScreenshotSelectorLayout = layoutInflater.inflate(R.layout.global_screenshot, null); mBackgroundView = (ImageView) mScreenshotLayout.findViewById(R.id.global_screenshot_background); mBackgroundView = (ImageView) mScreenshotLayout.findViewById( R.id.global_screenshot_background); mScreenshotView = (ImageView) mScreenshotLayout.findViewById(R.id.global_screenshot); mScreenshotFlash = (ImageView) mScreenshotLayout.findViewById(R.id.global_screenshot_flash); mScreenshotSelectorView = (ScreenshotSelectorView) mScreenshotSelectorLayout.findViewById( Loading Loading @@ -536,6 +540,7 @@ class GlobalScreenshot { mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); mDisplay = mWindowManager.getDefaultDisplay(); mDisplayMetrics = new DisplayMetrics(); mDisplay.getRealMetrics(mDisplayMetrics); Loading Loading @@ -781,6 +786,7 @@ class GlobalScreenshot { } }); } private ValueAnimator createScreenshotDropInAnimation() { final float flashPeakDurationPct = ((float) (SCREENSHOT_FLASH_TO_PEAK_DURATION) / SCREENSHOT_DROP_IN_DURATION); Loading Loading @@ -821,6 +827,7 @@ class GlobalScreenshot { mScreenshotFlash.setAlpha(0f); mScreenshotFlash.setVisibility(View.VISIBLE); } @Override public void onAnimationEnd(android.animation.Animator animation) { mScreenshotFlash.setVisibility(View.GONE); Loading @@ -842,6 +849,7 @@ class GlobalScreenshot { }); return anim; } private ValueAnimator createScreenshotDropOutAnimation(int w, int h, boolean statusBarVisible, boolean navBarVisible) { ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f); Loading @@ -863,7 +871,8 @@ class GlobalScreenshot { public void onAnimationUpdate(ValueAnimator animation) { float t = (Float) animation.getAnimatedValue(); float scaleT = (SCREENSHOT_DROP_IN_MIN_SCALE + mBgPaddingScale) - t * (SCREENSHOT_DROP_IN_MIN_SCALE - SCREENSHOT_FAST_DROP_OUT_MIN_SCALE); - t * (SCREENSHOT_DROP_IN_MIN_SCALE - SCREENSHOT_FAST_DROP_OUT_MIN_SCALE); mBackgroundView.setAlpha((1f - t) * BACKGROUND_ALPHA); mScreenshotView.setAlpha(1f - t); mScreenshotView.setScaleX(scaleT); Loading @@ -890,8 +899,10 @@ class GlobalScreenshot { float halfScreenHeight = (h - 2f * mBgPadding) / 2f; final float offsetPct = SCREENSHOT_DROP_OUT_MIN_SCALE_OFFSET; final PointF finalPos = new PointF( -halfScreenWidth + (SCREENSHOT_DROP_OUT_MIN_SCALE + offsetPct) * halfScreenWidth, -halfScreenHeight + (SCREENSHOT_DROP_OUT_MIN_SCALE + offsetPct) * halfScreenHeight); -halfScreenWidth + (SCREENSHOT_DROP_OUT_MIN_SCALE + offsetPct) * halfScreenWidth, -halfScreenHeight + (SCREENSHOT_DROP_OUT_MIN_SCALE + offsetPct) * halfScreenHeight); // Animate the screenshot to the status bar anim.setDuration(SCREENSHOT_DROP_OUT_DURATION); Loading Loading @@ -936,7 +947,7 @@ class GlobalScreenshot { DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE); if (intent != null) { final PendingIntent pendingIntent = PendingIntent.getActivityAsUser( context, 0, intent, 0, null, UserHandle.CURRENT); context, 0, intent, PendingIntent.FLAG_IMMUTABLE, null, UserHandle.CURRENT); b.setContentIntent(pendingIntent); } Loading services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +5 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static com.android.internal.util.Preconditions.checkState; import android.Manifest; import android.annotation.CheckResult; import android.annotation.Nullable; import android.app.AppOpsManager; import android.app.PendingIntent; import android.companion.AssociationRequest; import android.companion.CompanionDeviceManager; Loading Loading @@ -275,7 +276,10 @@ public class CompanionDeviceManagerService extends SystemService implements Bind checkArgument(getCallingUserId() == userId, "Must be called by either same user or system"); mAppOpsManager.checkPackage(Binder.getCallingUid(), pkg); int callingUid = Binder.getCallingUid(); if (mAppOpsManager.checkPackage(callingUid, pkg) != AppOpsManager.MODE_ALLOWED) { throw new SecurityException(pkg + " doesn't belong to uid " + callingUid); } } @Override Loading services/core/java/com/android/server/fingerprint/AuthenticationClient.java +91 −3 Original line number Diff line number Diff line Loading @@ -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. */ Loading @@ -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 { Loading @@ -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 + ")"); Loading Loading @@ -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(); } Loading @@ -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 */ Loading Loading
core/java/android/accounts/Account.java +6 −0 Original line number Diff line number Diff line Loading @@ -88,6 +88,12 @@ public class Account implements Parcelable { public Account(Parcel in) { this.name = in.readString(); this.type = in.readString(); if (TextUtils.isEmpty(name)) { throw new android.os.BadParcelableException("the name must not be empty: " + name); } if (TextUtils.isEmpty(type)) { throw new android.os.BadParcelableException("the type must not be empty: " + type); } this.accessId = in.readString(); if (accessId != null) { synchronized (sAccessedAccounts) { Loading
core/java/android/accounts/GrantCredentialsPermissionActivity.java +31 −6 Original line number Diff line number Diff line Loading @@ -16,16 +16,23 @@ package android.accounts; import android.app.Activity; import android.content.res.Resources; import android.os.Bundle; import android.widget.TextView; import android.widget.LinearLayout; import android.view.View; import android.view.LayoutInflater; import android.app.ActivityManager; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.res.Resources; import android.os.Bundle; import android.os.IBinder; import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; import android.text.TextUtils; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.widget.LinearLayout; import android.widget.TextView; import com.android.internal.R; import java.io.IOException; Loading @@ -42,11 +49,15 @@ public class GrantCredentialsPermissionActivity extends Activity implements View private Account mAccount; private String mAuthTokenType; private int mUid; private int mCallingUid; private Bundle mResultBundle = null; protected LayoutInflater mInflater; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().addPrivateFlags( android.view.WindowManager.LayoutParams .PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); setContentView(R.layout.grant_credentials_permission); setTitle(R.string.grant_permissions_header_text); Loading Loading @@ -74,6 +85,20 @@ public class GrantCredentialsPermissionActivity extends Activity implements View return; } try { IBinder activityToken = getActivityToken(); mCallingUid = ActivityManager.getService().getLaunchedFromUid(activityToken); } catch (RemoteException re) { // Couldn't figure out caller details Log.w(getClass().getSimpleName(), "Unable to get caller identity \n" + re); } if (!UserHandle.isSameApp(mCallingUid, Process.SYSTEM_UID) && mCallingUid != mUid) { setResult(Activity.RESULT_CANCELED); finish(); return; } String accountTypeLabel; try { accountTypeLabel = getAccountLabel(mAccount); Loading
packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java +41 −30 Original line number Diff line number Diff line Loading @@ -105,6 +105,7 @@ class SaveImageInBackgroundData { imageUri = null; iconSize = 0; } void clearContext() { context = null; } Loading Loading @@ -390,7 +391,8 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> { mPublicNotificationBuilder .setContentTitle(r.getString(R.string.screenshot_saved_title)) .setContentText(r.getString(R.string.screenshot_saved_text)) .setContentIntent(PendingIntent.getActivity(mParams.context, 0, launchIntent, 0)) .setContentIntent(PendingIntent.getActivity(mParams.context, 0, launchIntent, PendingIntent.FLAG_IMMUTABLE)) .setWhen(now) .setAutoCancel(true) .setColor(context.getColor( Loading @@ -398,7 +400,8 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> { mNotificationBuilder .setContentTitle(r.getString(R.string.screenshot_saved_title)) .setContentText(r.getString(R.string.screenshot_saved_text)) .setContentIntent(PendingIntent.getActivity(mParams.context, 0, launchIntent, 0)) .setContentIntent(PendingIntent.getActivity(mParams.context, 0, launchIntent, PendingIntent.FLAG_IMMUTABLE)) .setWhen(now) .setAutoCancel(true) .setColor(context.getColor( Loading Loading @@ -507,7 +510,8 @@ class GlobalScreenshot { mDisplayMatrix = new Matrix(); mScreenshotLayout = layoutInflater.inflate(R.layout.global_screenshot, null); mScreenshotSelectorLayout = layoutInflater.inflate(R.layout.global_screenshot, null); mBackgroundView = (ImageView) mScreenshotLayout.findViewById(R.id.global_screenshot_background); mBackgroundView = (ImageView) mScreenshotLayout.findViewById( R.id.global_screenshot_background); mScreenshotView = (ImageView) mScreenshotLayout.findViewById(R.id.global_screenshot); mScreenshotFlash = (ImageView) mScreenshotLayout.findViewById(R.id.global_screenshot_flash); mScreenshotSelectorView = (ScreenshotSelectorView) mScreenshotSelectorLayout.findViewById( Loading Loading @@ -536,6 +540,7 @@ class GlobalScreenshot { mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); mDisplay = mWindowManager.getDefaultDisplay(); mDisplayMetrics = new DisplayMetrics(); mDisplay.getRealMetrics(mDisplayMetrics); Loading Loading @@ -781,6 +786,7 @@ class GlobalScreenshot { } }); } private ValueAnimator createScreenshotDropInAnimation() { final float flashPeakDurationPct = ((float) (SCREENSHOT_FLASH_TO_PEAK_DURATION) / SCREENSHOT_DROP_IN_DURATION); Loading Loading @@ -821,6 +827,7 @@ class GlobalScreenshot { mScreenshotFlash.setAlpha(0f); mScreenshotFlash.setVisibility(View.VISIBLE); } @Override public void onAnimationEnd(android.animation.Animator animation) { mScreenshotFlash.setVisibility(View.GONE); Loading @@ -842,6 +849,7 @@ class GlobalScreenshot { }); return anim; } private ValueAnimator createScreenshotDropOutAnimation(int w, int h, boolean statusBarVisible, boolean navBarVisible) { ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f); Loading @@ -863,7 +871,8 @@ class GlobalScreenshot { public void onAnimationUpdate(ValueAnimator animation) { float t = (Float) animation.getAnimatedValue(); float scaleT = (SCREENSHOT_DROP_IN_MIN_SCALE + mBgPaddingScale) - t * (SCREENSHOT_DROP_IN_MIN_SCALE - SCREENSHOT_FAST_DROP_OUT_MIN_SCALE); - t * (SCREENSHOT_DROP_IN_MIN_SCALE - SCREENSHOT_FAST_DROP_OUT_MIN_SCALE); mBackgroundView.setAlpha((1f - t) * BACKGROUND_ALPHA); mScreenshotView.setAlpha(1f - t); mScreenshotView.setScaleX(scaleT); Loading @@ -890,8 +899,10 @@ class GlobalScreenshot { float halfScreenHeight = (h - 2f * mBgPadding) / 2f; final float offsetPct = SCREENSHOT_DROP_OUT_MIN_SCALE_OFFSET; final PointF finalPos = new PointF( -halfScreenWidth + (SCREENSHOT_DROP_OUT_MIN_SCALE + offsetPct) * halfScreenWidth, -halfScreenHeight + (SCREENSHOT_DROP_OUT_MIN_SCALE + offsetPct) * halfScreenHeight); -halfScreenWidth + (SCREENSHOT_DROP_OUT_MIN_SCALE + offsetPct) * halfScreenWidth, -halfScreenHeight + (SCREENSHOT_DROP_OUT_MIN_SCALE + offsetPct) * halfScreenHeight); // Animate the screenshot to the status bar anim.setDuration(SCREENSHOT_DROP_OUT_DURATION); Loading Loading @@ -936,7 +947,7 @@ class GlobalScreenshot { DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE); if (intent != null) { final PendingIntent pendingIntent = PendingIntent.getActivityAsUser( context, 0, intent, 0, null, UserHandle.CURRENT); context, 0, intent, PendingIntent.FLAG_IMMUTABLE, null, UserHandle.CURRENT); b.setContentIntent(pendingIntent); } Loading
services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +5 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static com.android.internal.util.Preconditions.checkState; import android.Manifest; import android.annotation.CheckResult; import android.annotation.Nullable; import android.app.AppOpsManager; import android.app.PendingIntent; import android.companion.AssociationRequest; import android.companion.CompanionDeviceManager; Loading Loading @@ -275,7 +276,10 @@ public class CompanionDeviceManagerService extends SystemService implements Bind checkArgument(getCallingUserId() == userId, "Must be called by either same user or system"); mAppOpsManager.checkPackage(Binder.getCallingUid(), pkg); int callingUid = Binder.getCallingUid(); if (mAppOpsManager.checkPackage(callingUid, pkg) != AppOpsManager.MODE_ALLOWED) { throw new SecurityException(pkg + " doesn't belong to uid " + callingUid); } } @Override Loading
services/core/java/com/android/server/fingerprint/AuthenticationClient.java +91 −3 Original line number Diff line number Diff line Loading @@ -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. */ Loading @@ -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 { Loading @@ -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 + ")"); Loading Loading @@ -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(); } Loading @@ -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 */ Loading