From 91bb4412f72207528ed3bf7742f03f3b08a68a95 Mon Sep 17 00:00:00 2001 From: "[6;7~" Date: Mon, 26 Apr 2021 14:22:25 -0700 Subject: [PATCH] Specify UID in getAuthenticatorIds Allow the caller to get authenticator IDs for a specific UID. If that UID is not the caller UID the USE_BIOMETRIC_INTERNAL permission is required; this is enforced by AuthService. Test: aosp/1686345 Bug: 163866361 Change-Id: I0eef28ecefb85f1c10a73a354d08c38087d59814 --- .../hardware/biometrics/BiometricManager.java | 16 +++++++++++++++- .../hardware/biometrics/IAuthService.aidl | 4 +++- .../android/server/biometrics/AuthService.java | 8 ++++++-- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/core/java/android/hardware/biometrics/BiometricManager.java b/core/java/android/hardware/biometrics/BiometricManager.java index d054ee207110a..948da3f6e663d 100644 --- a/core/java/android/hardware/biometrics/BiometricManager.java +++ b/core/java/android/hardware/biometrics/BiometricManager.java @@ -33,6 +33,7 @@ import android.annotation.TestApi; import android.content.Context; import android.os.IBinder; import android.os.RemoteException; +import android.os.UserHandle; import android.security.keystore.KeyProperties; import android.util.Slog; @@ -556,9 +557,22 @@ public class BiometricManager { * @hide */ public long[] getAuthenticatorIds() { + return getAuthenticatorIds(UserHandle.getCallingUserId()); + } + + /** + * Get a list of AuthenticatorIDs for biometric authenticators which have 1) enrolled templates, + * and 2) meet the requirements for integrating with Keystore. The AuthenticatorIDs are known + * in Keystore land as SIDs, and are used during key generation. + * + * @param userId Android user ID for user to look up. + * + * @hide + */ + public long[] getAuthenticatorIds(int userId) { if (mService != null) { try { - return mService.getAuthenticatorIds(); + return mService.getAuthenticatorIds(userId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/hardware/biometrics/IAuthService.aidl b/core/java/android/hardware/biometrics/IAuthService.aidl index 86df0994a2227..4c2a9ae10cbdf 100644 --- a/core/java/android/hardware/biometrics/IAuthService.aidl +++ b/core/java/android/hardware/biometrics/IAuthService.aidl @@ -67,7 +67,9 @@ interface IAuthService { // Get a list of AuthenticatorIDs for authenticators which have enrolled templates and meet // the requirements for integrating with Keystore. The AuthenticatorID are known in Keystore // land as SIDs, and are used during key generation. - long[] getAuthenticatorIds(); + // If userId is not equal to the calling user ID, the caller must have the + // USE_BIOMETRIC_INTERNAL permission. + long[] getAuthenticatorIds(in int userId); // See documentation in BiometricManager. void resetLockoutTimeBound(IBinder token, String opPackageName, int fromSensorId, int userId, diff --git a/services/core/java/com/android/server/biometrics/AuthService.java b/services/core/java/com/android/server/biometrics/AuthService.java index 88e47a0efd835..7b50218cfad66 100644 --- a/services/core/java/com/android/server/biometrics/AuthService.java +++ b/services/core/java/com/android/server/biometrics/AuthService.java @@ -337,7 +337,7 @@ public class AuthService extends SystemService { } @Override - public long[] getAuthenticatorIds() throws RemoteException { + public long[] getAuthenticatorIds(int userId) throws RemoteException { // In this method, we're not checking whether the caller is permitted to use face // API because current authenticator ID is leaked (in a more contrived way) via Android // Keystore (android.security.keystore package): the user of that API can create a key @@ -355,9 +355,13 @@ public class AuthService extends SystemService { // method from inside app processes. final int callingUserId = UserHandle.getCallingUserId(); + if (userId != callingUserId) { + getContext().enforceCallingOrSelfPermission(USE_BIOMETRIC_INTERNAL, + "Must have " + USE_BIOMETRIC_INTERNAL + " permission."); + } final long identity = Binder.clearCallingIdentity(); try { - return mBiometricService.getAuthenticatorIds(callingUserId); + return mBiometricService.getAuthenticatorIds(userId); } finally { Binder.restoreCallingIdentity(identity); }