Make BiometricService check for internal permission
Previously, some paths through BiometricService needed to be accessible by apps. Now that external calls are routed through AuthService instead, we can check for the system-only USE_BIOMETRIC_INTERNAL permission everywhere that we had been checking for USE_BIOMETRIC in BiometricService. In order for this to be enforced properly, we also need to move some of the permission checks that were previously in BiometricService to AuthService, which is now the primary entry point for applications invoking the relevant biometric APIs. Test: com.android.server.biometrics Test: Manually verified functionality using support biometric demo app Bug: 148971767 Change-Id: Ieab61276c6375b0d674f73e1833edabc8700fe74
This commit is contained in:
@@ -29,13 +29,15 @@ interface IBiometricService {
|
||||
// Requests authentication. The service choose the appropriate biometric to use, and show
|
||||
// the corresponding BiometricDialog.
|
||||
void authenticate(IBinder token, long sessionId, int userId,
|
||||
IBiometricServiceReceiver receiver, String opPackageName, in Bundle bundle);
|
||||
IBiometricServiceReceiver receiver, String opPackageName, in Bundle bundle,
|
||||
int callingUid, int callingPid, int callingUserId);
|
||||
|
||||
// Cancel authentication for the given sessionId
|
||||
void cancelAuthentication(IBinder token, String opPackageName);
|
||||
// Cancel authentication for the given session.
|
||||
void cancelAuthentication(IBinder token, String opPackageName, int callingUid, int callingPid,
|
||||
int callingUserId);
|
||||
|
||||
// Checks if biometrics can be used.
|
||||
int canAuthenticate(String opPackageName, int userId, int authenticators);
|
||||
int canAuthenticate(String opPackageName, int userId, int callingUserId, int authenticators);
|
||||
|
||||
// Checks if any biometrics are enrolled.
|
||||
boolean hasEnrolledBiometrics(int userId, String opPackageName);
|
||||
@@ -47,7 +49,8 @@ interface IBiometricService {
|
||||
IBiometricAuthenticator authenticator);
|
||||
|
||||
// Register callback for when keyguard biometric eligibility changes.
|
||||
void registerEnabledOnKeyguardCallback(IBiometricEnabledOnKeyguardCallback callback);
|
||||
void registerEnabledOnKeyguardCallback(IBiometricEnabledOnKeyguardCallback callback,
|
||||
int callingUserId);
|
||||
|
||||
// Explicitly set the active user.
|
||||
void setActiveUser(int userId);
|
||||
|
||||
@@ -30,6 +30,7 @@ import static android.hardware.biometrics.BiometricManager.Authenticators;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.hardware.biometrics.BiometricPrompt;
|
||||
import android.hardware.biometrics.IAuthService;
|
||||
import android.hardware.biometrics.IBiometricAuthenticator;
|
||||
import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
|
||||
@@ -38,6 +39,7 @@ import android.hardware.biometrics.IBiometricServiceReceiver;
|
||||
import android.hardware.face.IFaceService;
|
||||
import android.hardware.fingerprint.IFingerprintService;
|
||||
import android.hardware.iris.IIrisService;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
@@ -133,14 +135,12 @@ public class AuthService extends SystemService {
|
||||
public void authenticate(IBinder token, long sessionId, int userId,
|
||||
IBiometricServiceReceiver receiver, String opPackageName, Bundle bundle)
|
||||
throws RemoteException {
|
||||
final int callingUserId = UserHandle.getCallingUserId();
|
||||
|
||||
// In the BiometricServiceBase, do the AppOps and foreground check.
|
||||
// Only allow internal clients to authenticate with a different userId.
|
||||
final int callingUserId = UserHandle.getCallingUserId();
|
||||
if (userId == callingUserId) {
|
||||
// Check the USE_BIOMETRIC permission here.
|
||||
checkPermission();
|
||||
} else {
|
||||
// Only allow internal clients to authenticate with a different userId
|
||||
Slog.w(TAG, "User " + callingUserId + " is requesting authentication of userid: "
|
||||
+ userId);
|
||||
checkInternalPermission();
|
||||
@@ -150,23 +150,52 @@ public class AuthService extends SystemService {
|
||||
Slog.e(TAG, "Unable to authenticate, one or more null arguments");
|
||||
return;
|
||||
}
|
||||
mBiometricService.authenticate(token, sessionId, userId, receiver, opPackageName,
|
||||
bundle);
|
||||
|
||||
// Only allow internal clients to enable non-public options.
|
||||
if (bundle.getBoolean(BiometricPrompt.EXTRA_DISALLOW_BIOMETRICS_IF_POLICY_EXISTS)
|
||||
|| bundle.getBoolean(BiometricPrompt.KEY_USE_DEFAULT_TITLE, false)) {
|
||||
checkInternalPermission();
|
||||
}
|
||||
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
final int callingPid = Binder.getCallingPid();
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mBiometricService.authenticate(
|
||||
token, sessionId, userId, receiver, opPackageName, bundle, callingUid,
|
||||
callingPid, callingUserId);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelAuthentication(IBinder token, String opPackageName)
|
||||
throws RemoteException {
|
||||
checkPermission();
|
||||
|
||||
if (token == null || opPackageName == null) {
|
||||
Slog.e(TAG, "Unable to authenticate, one or more null arguments");
|
||||
return;
|
||||
}
|
||||
mBiometricService.cancelAuthentication(token, opPackageName);
|
||||
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
final int callingPid = Binder.getCallingPid();
|
||||
final int callingUserId = UserHandle.getCallingUserId();
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mBiometricService.cancelAuthentication(token, opPackageName, callingUid,
|
||||
callingPid, callingUserId);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int canAuthenticate(String opPackageName, int userId,
|
||||
@Authenticators.Types int authenticators) throws RemoteException {
|
||||
|
||||
// Only allow internal clients to call canAuthenticate with a different userId.
|
||||
final int callingUserId = UserHandle.getCallingUserId();
|
||||
Slog.d(TAG, "canAuthenticate, userId: " + userId + ", callingUserId: " + callingUserId
|
||||
+ ", authenticators: " + authenticators);
|
||||
@@ -175,33 +204,61 @@ public class AuthService extends SystemService {
|
||||
} else {
|
||||
checkPermission();
|
||||
}
|
||||
return mBiometricService.canAuthenticate(opPackageName, userId, authenticators);
|
||||
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
return mBiometricService.canAuthenticate(
|
||||
opPackageName, userId, callingUserId, authenticators);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasEnrolledBiometrics(int userId, String opPackageName)
|
||||
throws RemoteException {
|
||||
checkInternalPermission();
|
||||
return mBiometricService.hasEnrolledBiometrics(userId, opPackageName);
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
return mBiometricService.hasEnrolledBiometrics(userId, opPackageName);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerEnabledOnKeyguardCallback(IBiometricEnabledOnKeyguardCallback callback)
|
||||
throws RemoteException {
|
||||
public void registerEnabledOnKeyguardCallback(
|
||||
IBiometricEnabledOnKeyguardCallback callback) throws RemoteException {
|
||||
checkInternalPermission();
|
||||
mBiometricService.registerEnabledOnKeyguardCallback(callback);
|
||||
final int callingUserId = UserHandle.getCallingUserId();
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mBiometricService.registerEnabledOnKeyguardCallback(callback, callingUserId);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActiveUser(int userId) throws RemoteException {
|
||||
checkInternalPermission();
|
||||
mBiometricService.setActiveUser(userId);
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mBiometricService.setActiveUser(userId);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetLockout(byte[] token) throws RemoteException {
|
||||
checkInternalPermission();
|
||||
mBiometricService.resetLockout(token);
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mBiometricService.resetLockout(token);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,8 +273,23 @@ public class AuthService extends SystemService {
|
||||
mImpl = new AuthServiceImpl();
|
||||
}
|
||||
|
||||
private void registerAuthenticator(SensorConfig config) throws RemoteException {
|
||||
@Override
|
||||
public void onStart() {
|
||||
mBiometricService = mInjector.getBiometricService();
|
||||
|
||||
final String[] configs = mInjector.getConfiguration(getContext());
|
||||
for (String config : configs) {
|
||||
try {
|
||||
registerAuthenticator(new SensorConfig(config));
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Remote exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
mInjector.publishBinderService(this, mImpl);
|
||||
}
|
||||
|
||||
private void registerAuthenticator(SensorConfig config) throws RemoteException {
|
||||
Slog.d(TAG, "Registering ID: " + config.mId
|
||||
+ " Modality: " + config.mModality
|
||||
+ " Strength: " + config.mStrength);
|
||||
@@ -267,23 +339,6 @@ public class AuthService extends SystemService {
|
||||
authenticator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
mBiometricService = mInjector.getBiometricService();
|
||||
|
||||
final String[] configs = mInjector.getConfiguration(getContext());
|
||||
|
||||
for (int i = 0; i < configs.length; i++) {
|
||||
try {
|
||||
registerAuthenticator(new SensorConfig(configs[i]));
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Remote exception", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
mInjector.publishBinderService(this, mImpl);
|
||||
}
|
||||
|
||||
private void checkInternalPermission() {
|
||||
getContext().enforceCallingOrSelfPermission(USE_BIOMETRIC_INTERNAL,
|
||||
|
||||
@@ -16,9 +16,7 @@
|
||||
|
||||
package com.android.server.biometrics;
|
||||
|
||||
import static android.Manifest.permission.USE_BIOMETRIC;
|
||||
import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
|
||||
import static android.Manifest.permission.USE_FINGERPRINT;
|
||||
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
|
||||
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
|
||||
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_IRIS;
|
||||
@@ -32,7 +30,6 @@ import android.app.admin.DevicePolicyManager;
|
||||
import android.app.trust.ITrustManager;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.database.ContentObserver;
|
||||
import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.hardware.biometrics.BiometricConstants;
|
||||
@@ -318,7 +315,10 @@ public class BiometricService extends SystemService {
|
||||
SomeArgs args = (SomeArgs) msg.obj;
|
||||
handleCancelAuthentication(
|
||||
(IBinder) args.arg1 /* token */,
|
||||
(String) args.arg2 /* opPackageName */);
|
||||
(String) args.arg2 /* opPackageName */,
|
||||
args.argi1 /* callingUid */,
|
||||
args.argi2 /* callingPid */,
|
||||
args.argi3 /* callingUserId */);
|
||||
args.recycle();
|
||||
break;
|
||||
}
|
||||
@@ -543,8 +543,7 @@ public class BiometricService extends SystemService {
|
||||
final IBiometricServiceReceiverInternal mInternalReceiver =
|
||||
new IBiometricServiceReceiverInternal.Stub() {
|
||||
@Override
|
||||
public void onAuthenticationSucceeded(boolean requireConfirmation, byte[] token)
|
||||
throws RemoteException {
|
||||
public void onAuthenticationSucceeded(boolean requireConfirmation, byte[] token) {
|
||||
SomeArgs args = SomeArgs.obtain();
|
||||
args.arg1 = requireConfirmation;
|
||||
args.arg2 = token;
|
||||
@@ -552,8 +551,7 @@ public class BiometricService extends SystemService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthenticationFailed()
|
||||
throws RemoteException {
|
||||
public void onAuthenticationFailed() {
|
||||
Slog.v(TAG, "onAuthenticationFailed");
|
||||
mHandler.obtainMessage(MSG_ON_AUTHENTICATION_REJECTED).sendToTarget();
|
||||
}
|
||||
@@ -624,22 +622,9 @@ public class BiometricService extends SystemService {
|
||||
|
||||
@Override // Binder call
|
||||
public void authenticate(IBinder token, long sessionId, int userId,
|
||||
IBiometricServiceReceiver receiver, String opPackageName, Bundle bundle)
|
||||
throws RemoteException {
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
final int callingPid = Binder.getCallingPid();
|
||||
final int callingUserId = UserHandle.getCallingUserId();
|
||||
|
||||
// In the BiometricServiceBase, check do the AppOps and foreground check.
|
||||
if (userId == callingUserId) {
|
||||
// Check the USE_BIOMETRIC permission here.
|
||||
checkPermission();
|
||||
} else {
|
||||
// Only allow internal clients to authenticate with a different userId
|
||||
Slog.w(TAG, "User " + callingUserId + " is requesting authentication of userid: "
|
||||
+ userId);
|
||||
checkInternalPermission();
|
||||
}
|
||||
IBiometricServiceReceiver receiver, String opPackageName, Bundle bundle,
|
||||
int callingUid, int callingPid, int callingUserId) {
|
||||
checkInternalPermission();
|
||||
|
||||
if (token == null || receiver == null || opPackageName == null || bundle == null) {
|
||||
Slog.e(TAG, "Unable to authenticate, one or more null arguments");
|
||||
@@ -650,19 +635,10 @@ public class BiometricService extends SystemService {
|
||||
throw new SecurityException("Invalid authenticator configuration");
|
||||
}
|
||||
|
||||
if (bundle.getBoolean(BiometricPrompt.EXTRA_DISALLOW_BIOMETRICS_IF_POLICY_EXISTS)) {
|
||||
checkInternalPermission();
|
||||
}
|
||||
|
||||
Utils.combineAuthenticatorBundles(bundle);
|
||||
|
||||
// Check the usage of this in system server. Need to remove this check if it becomes a
|
||||
// public API.
|
||||
final boolean useDefaultTitle =
|
||||
bundle.getBoolean(BiometricPrompt.KEY_USE_DEFAULT_TITLE, false);
|
||||
if (useDefaultTitle) {
|
||||
checkInternalPermission();
|
||||
// Set the default title if necessary
|
||||
// Set the default title if necessary.
|
||||
if (bundle.getBoolean(BiometricPrompt.KEY_USE_DEFAULT_TITLE, false)) {
|
||||
if (TextUtils.isEmpty(bundle.getCharSequence(BiometricPrompt.KEY_TITLE))) {
|
||||
bundle.putCharSequence(BiometricPrompt.KEY_TITLE,
|
||||
getContext().getString(R.string.biometric_dialog_default_title));
|
||||
@@ -684,28 +660,27 @@ public class BiometricService extends SystemService {
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
public void cancelAuthentication(IBinder token, String opPackageName)
|
||||
throws RemoteException {
|
||||
checkPermission();
|
||||
public void cancelAuthentication(IBinder token, String opPackageName,
|
||||
int callingUid, int callingPid, int callingUserId) {
|
||||
checkInternalPermission();
|
||||
|
||||
SomeArgs args = SomeArgs.obtain();
|
||||
args.arg1 = token;
|
||||
args.arg2 = opPackageName;
|
||||
args.argi1 = callingUid;
|
||||
args.argi2 = callingPid;
|
||||
args.argi3 = callingUserId;
|
||||
mHandler.obtainMessage(MSG_CANCEL_AUTHENTICATION, args).sendToTarget();
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
public int canAuthenticate(String opPackageName, int userId,
|
||||
public int canAuthenticate(String opPackageName, int userId, int callingUserId,
|
||||
@Authenticators.Types int authenticators) {
|
||||
Slog.d(TAG, "canAuthenticate: User=" + userId
|
||||
+ ", Caller=" + UserHandle.getCallingUserId()
|
||||
+ ", Authenticators=" + authenticators);
|
||||
checkInternalPermission();
|
||||
|
||||
if (userId != UserHandle.getCallingUserId()) {
|
||||
checkInternalPermission();
|
||||
} else {
|
||||
checkPermission();
|
||||
}
|
||||
Slog.d(TAG, "canAuthenticate: User=" + userId
|
||||
+ ", Caller=" + callingUserId
|
||||
+ ", Authenticators=" + authenticators);
|
||||
|
||||
if (!Utils.isValidAuthenticatorConfig(authenticators)) {
|
||||
throw new SecurityException("Invalid authenticator configuration");
|
||||
@@ -715,14 +690,11 @@ public class BiometricService extends SystemService {
|
||||
bundle.putInt(BiometricPrompt.KEY_AUTHENTICATORS_ALLOWED, authenticators);
|
||||
|
||||
int biometricConstantsResult = BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE;
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
biometricConstantsResult = checkAndGetAuthenticators(userId, bundle, opPackageName,
|
||||
false /* checkDevicePolicyManager */).second;
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Remote exception", e);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
|
||||
return Utils.biometricConstantsToBiometricManager(biometricConstantsResult);
|
||||
@@ -732,7 +704,6 @@ public class BiometricService extends SystemService {
|
||||
public boolean hasEnrolledBiometrics(int userId, String opPackageName) {
|
||||
checkInternalPermission();
|
||||
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
for (AuthenticatorWrapper authenticator : mAuthenticators) {
|
||||
if (authenticator.impl.hasEnrolledTemplates(userId, opPackageName)) {
|
||||
@@ -741,9 +712,8 @@ public class BiometricService extends SystemService {
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Remote exception", e);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -791,14 +761,14 @@ public class BiometricService extends SystemService {
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
public void registerEnabledOnKeyguardCallback(IBiometricEnabledOnKeyguardCallback callback)
|
||||
throws RemoteException {
|
||||
public void registerEnabledOnKeyguardCallback(
|
||||
IBiometricEnabledOnKeyguardCallback callback, int callingUserId) {
|
||||
checkInternalPermission();
|
||||
|
||||
mEnabledOnKeyguardCallbacks.add(new EnabledOnKeyguardCallback(callback));
|
||||
try {
|
||||
callback.onChanged(BiometricSourceType.FACE,
|
||||
mSettingObserver.getFaceEnabledOnKeyguard(),
|
||||
UserHandle.getCallingUserId());
|
||||
mSettingObserver.getFaceEnabledOnKeyguard(), callingUserId);
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Remote exception", e);
|
||||
}
|
||||
@@ -807,30 +777,26 @@ public class BiometricService extends SystemService {
|
||||
@Override // Binder call
|
||||
public void setActiveUser(int userId) {
|
||||
checkInternalPermission();
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
|
||||
try {
|
||||
for (AuthenticatorWrapper authenticator : mAuthenticators) {
|
||||
authenticator.impl.setActiveUser(userId);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Remote exception", e);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
public void resetLockout(byte[] token) {
|
||||
checkInternalPermission();
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
|
||||
try {
|
||||
for (AuthenticatorWrapper authenticator : mAuthenticators) {
|
||||
authenticator.impl.resetLockout(token);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Remote exception", e);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -840,14 +806,6 @@ public class BiometricService extends SystemService {
|
||||
"Must have USE_BIOMETRIC_INTERNAL permission");
|
||||
}
|
||||
|
||||
private void checkPermission() {
|
||||
if (getContext().checkCallingOrSelfPermission(USE_FINGERPRINT)
|
||||
!= PackageManager.PERMISSION_GRANTED) {
|
||||
getContext().enforceCallingOrSelfPermission(USE_BIOMETRIC,
|
||||
"Must have USE_BIOMETRIC permission");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class for injecting dependencies into BiometricService.
|
||||
* TODO(b/141025588): Replace with a dependency injection framework (e.g. Guice, Dagger).
|
||||
@@ -1440,7 +1398,9 @@ public class BiometricService extends SystemService {
|
||||
mCurrentAuthSession.mClientReceiver.onDialogDismissed(reason);
|
||||
// Cancel authentication. Skip the token/package check since we are cancelling
|
||||
// from system server. The interface is permission protected so this is fine.
|
||||
cancelInternal(null /* token */, null /* package */, false /* fromClient */);
|
||||
cancelInternal(null /* token */, null /* package */,
|
||||
mCurrentAuthSession.mCallingUid, mCurrentAuthSession.mCallingPid,
|
||||
mCurrentAuthSession.mCallingUserId, false /* fromClient */);
|
||||
break;
|
||||
|
||||
case BiometricPrompt.DISMISSED_REASON_USER_CANCEL:
|
||||
@@ -1451,7 +1411,9 @@ public class BiometricService extends SystemService {
|
||||
);
|
||||
// Cancel authentication. Skip the token/package check since we are cancelling
|
||||
// from system server. The interface is permission protected so this is fine.
|
||||
cancelInternal(null /* token */, null /* package */, false /* fromClient */);
|
||||
cancelInternal(null /* token */, null /* package */, Binder.getCallingUid(),
|
||||
Binder.getCallingPid(), UserHandle.getCallingUserId(),
|
||||
false /* fromClient */);
|
||||
break;
|
||||
|
||||
case BiometricPrompt.DISMISSED_REASON_SERVER_REQUESTED:
|
||||
@@ -1501,7 +1463,9 @@ public class BiometricService extends SystemService {
|
||||
|
||||
// Cancel authentication. Skip the token/package check since we are cancelling
|
||||
// from system server. The interface is permission protected so this is fine.
|
||||
cancelInternal(null /* token */, null /* package */, false /* fromClient */);
|
||||
cancelInternal(null /* token */, null /* package */, Binder.getCallingUid(),
|
||||
Binder.getCallingPid(), UserHandle.getCallingUserId(),
|
||||
false /* fromClient */);
|
||||
|
||||
mCurrentAuthSession.mState = STATE_SHOWING_DEVICE_CREDENTIAL;
|
||||
}
|
||||
@@ -1671,7 +1635,8 @@ public class BiometricService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
private void handleCancelAuthentication(IBinder token, String opPackageName) {
|
||||
private void handleCancelAuthentication(IBinder token, String opPackageName, int callingUid,
|
||||
int callingPid, int callingUserId) {
|
||||
if (token == null || opPackageName == null) {
|
||||
Slog.e(TAG, "Unable to cancel, one or more null arguments");
|
||||
return;
|
||||
@@ -1694,14 +1659,13 @@ public class BiometricService extends SystemService {
|
||||
Slog.e(TAG, "Remote exception", e);
|
||||
}
|
||||
} else {
|
||||
cancelInternal(token, opPackageName, true /* fromClient */);
|
||||
cancelInternal(token, opPackageName, callingUid, callingPid, callingUserId,
|
||||
true /* fromClient */);
|
||||
}
|
||||
}
|
||||
|
||||
void cancelInternal(IBinder token, String opPackageName, boolean fromClient) {
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
final int callingPid = Binder.getCallingPid();
|
||||
final int callingUserId = UserHandle.getCallingUserId();
|
||||
void cancelInternal(IBinder token, String opPackageName, int callingUid, int callingPid,
|
||||
int callingUserId, boolean fromClient) {
|
||||
|
||||
if (mCurrentAuthSession == null) {
|
||||
Slog.w(TAG, "Skipping cancelInternal");
|
||||
|
||||
@@ -38,6 +38,7 @@ import android.hardware.fingerprint.IFingerprintService;
|
||||
import android.hardware.iris.IIrisService;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.SmallTest;
|
||||
@@ -136,7 +137,10 @@ public class AuthServiceTest {
|
||||
eq(userId),
|
||||
eq(mReceiver),
|
||||
eq(TEST_OP_PACKAGE_NAME),
|
||||
eq(bundle));
|
||||
eq(bundle),
|
||||
eq(Binder.getCallingUid()),
|
||||
eq(Binder.getCallingPid()),
|
||||
eq(UserHandle.getCallingUserId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -147,7 +151,7 @@ public class AuthServiceTest {
|
||||
final int userId = 0;
|
||||
final int expectedResult = BIOMETRIC_SUCCESS;
|
||||
final int authenticators = 0;
|
||||
when(mBiometricService.canAuthenticate(anyString(), anyInt(), anyInt()))
|
||||
when(mBiometricService.canAuthenticate(anyString(), anyInt(), anyInt(), anyInt()))
|
||||
.thenReturn(expectedResult);
|
||||
|
||||
final int result = mAuthService.mImpl
|
||||
@@ -158,6 +162,7 @@ public class AuthServiceTest {
|
||||
verify(mBiometricService).canAuthenticate(
|
||||
eq(TEST_OP_PACKAGE_NAME),
|
||||
eq(userId),
|
||||
eq(UserHandle.getCallingUserId()),
|
||||
eq(authenticators));
|
||||
}
|
||||
|
||||
@@ -196,7 +201,8 @@ public class AuthServiceTest {
|
||||
mAuthService.mImpl.registerEnabledOnKeyguardCallback(callback);
|
||||
|
||||
waitForIdle();
|
||||
verify(mBiometricService).registerEnabledOnKeyguardCallback(eq(callback));
|
||||
verify(mBiometricService).registerEnabledOnKeyguardCallback(
|
||||
eq(callback), eq(UserHandle.getCallingUserId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -947,7 +947,7 @@ public class BiometricServiceTest {
|
||||
false /* requireConfirmation */, null /* authenticators */);
|
||||
|
||||
mBiometricService.mImpl.cancelAuthentication(mBiometricService.mCurrentAuthSession.mToken,
|
||||
TEST_PACKAGE_NAME);
|
||||
TEST_PACKAGE_NAME, 0 /* callingUId */, 0 /* callingPid */, 0 /* callingUserId */);
|
||||
waitForIdle();
|
||||
|
||||
// Pretend that the HAL has responded to cancel with ERROR_CANCELED
|
||||
@@ -1290,7 +1290,8 @@ public class BiometricServiceTest {
|
||||
|
||||
private int invokeCanAuthenticate(BiometricService service, int authenticators)
|
||||
throws Exception {
|
||||
return service.mImpl.canAuthenticate(TEST_PACKAGE_NAME, 0 /* userId */, authenticators);
|
||||
return service.mImpl.canAuthenticate(
|
||||
TEST_PACKAGE_NAME, 0 /* userId */, 0 /* callingUserId */, authenticators);
|
||||
}
|
||||
|
||||
private void setupAuthForOnly(int modality, int strength) throws Exception {
|
||||
@@ -1393,7 +1394,10 @@ public class BiometricServiceTest {
|
||||
receiver,
|
||||
TEST_PACKAGE_NAME /* packageName */,
|
||||
createTestBiometricPromptBundle(requireConfirmation, authenticators,
|
||||
false /* checkDevicePolicy */));
|
||||
false /* checkDevicePolicy */),
|
||||
0 /* callingUid */,
|
||||
0 /* callingPid */,
|
||||
0 /* callingUserId */);
|
||||
}
|
||||
|
||||
private static void invokeAuthenticateForWorkApp(IBiometricService.Stub service,
|
||||
@@ -1405,7 +1409,10 @@ public class BiometricServiceTest {
|
||||
receiver,
|
||||
TEST_PACKAGE_NAME /* packageName */,
|
||||
createTestBiometricPromptBundle(false /* requireConfirmation */, authenticators,
|
||||
true /* checkDevicePolicy */));
|
||||
true /* checkDevicePolicy */),
|
||||
0 /* callingUid */,
|
||||
0 /* callingPid */,
|
||||
0 /* callingUserId */);
|
||||
}
|
||||
|
||||
private static Bundle createTestBiometricPromptBundle(
|
||||
|
||||
Reference in New Issue
Block a user