diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java index 6a4f4db5ef246..c33d5ecc5d164 100644 --- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java +++ b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java @@ -332,20 +332,20 @@ public class AppSearchManagerService extends SystemService { long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime(); int callingUid = Binder.getCallingUid(); - UserHandle targetUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK; AppSearchUserInstance instance = null; int operationSuccessCount = 0; int operationFailureCount = 0; try { - Context targetUserContext = mContext.createContextAsUser(targetUser, - /*flags=*/ 0); + verifyCaller(callingUid, packageName); + + // Obtain the user where the client wants to run the operations in. This should + // end up being the same as userHandle, assuming it is not a special user and + // the client is allowed to run operations in that user. + UserHandle targetUser = handleIncomingUser(userHandle, callingUid); verifyUserUnlocked(targetUser); - // TODO(b/193902620): Pass in the callingUser and not the targetUser. - verifyCallingPackage(targetUserContext, targetUser, callingUid, packageName); - // TODO(b/194939218): Pass in the callingUser and not the targetUser. - verifyNotInstantApp(targetUserContext, packageName); + List schemas = new ArrayList<>(schemaBundles.size()); for (int i = 0; i < schemaBundles.size(); i++) { schemas.add(new AppSearchSchema(schemaBundles.get(i))); @@ -421,16 +421,16 @@ public class AppSearchManagerService extends SystemService { Objects.requireNonNull(callback); int callingUid = Binder.getCallingUid(); - UserHandle targetUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { try { - Context targetUserContext = mContext.createContextAsUser(targetUser, - /*flags=*/ 0); + verifyCaller(callingUid, packageName); + + // Obtain the user where the client wants to run the operations in. This should + // end up being the same as userHandle, assuming it is not a special user and + // the client is allowed to run operations in that user. + UserHandle targetUser = handleIncomingUser(userHandle, callingUid); verifyUserUnlocked(targetUser); - // TODO(b/193902620): Pass in the callingUser and not the targetUser. - verifyCallingPackage(targetUserContext, targetUser, callingUid, packageName); - // TODO(b/194939218): Pass in the callingUser and not the targetUser. - verifyNotInstantApp(targetUserContext, packageName); + AppSearchUserInstance instance = mAppSearchUserInstanceManager.getUserInstance(targetUser); GetSchemaResponse response = @@ -456,16 +456,16 @@ public class AppSearchManagerService extends SystemService { Objects.requireNonNull(callback); int callingUid = Binder.getCallingUid(); - UserHandle targetUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { try { - Context targetUserContext = mContext.createContextAsUser(targetUser, - /*flags=*/ 0); + verifyCaller(callingUid, packageName); + + // Obtain the user where the client wants to run the operations in. This should + // end up being the same as userHandle, assuming it is not a special user and + // the client is allowed to run operations in that user. + UserHandle targetUser = handleIncomingUser(userHandle, callingUid); verifyUserUnlocked(targetUser); - // TODO(b/193902620): Pass in the callingUser and not the targetUser. - verifyCallingPackage(targetUserContext, targetUser, callingUid, packageName); - // TODO(b/194939218): Pass in the callingUser and not the targetUser. - verifyNotInstantApp(targetUserContext, packageName); + AppSearchUserInstance instance = mAppSearchUserInstanceManager.getUserInstance(targetUser); List namespaces = @@ -494,20 +494,20 @@ public class AppSearchManagerService extends SystemService { long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime(); int callingUid = Binder.getCallingUid(); - UserHandle targetUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK; AppSearchUserInstance instance = null; int operationSuccessCount = 0; int operationFailureCount = 0; try { - Context targetUserContext = mContext.createContextAsUser(targetUser, - /*flags=*/ 0); + verifyCaller(callingUid, packageName); + + // Obtain the user where the client wants to run the operations in. This should + // end up being the same as userHandle, assuming it is not a special user and + // the client is allowed to run operations in that user. + UserHandle targetUser = handleIncomingUser(userHandle, callingUid); verifyUserUnlocked(targetUser); - // TODO(b/193902620): Pass in the callingUser and not the targetUser. - verifyCallingPackage(targetUserContext, targetUser, callingUid, packageName); - // TODO(b/194939218): Pass in the callingUser and not the targetUser. - verifyNotInstantApp(targetUserContext, packageName); + AppSearchBatchResult.Builder resultBuilder = new AppSearchBatchResult.Builder<>(); instance = mAppSearchUserInstanceManager.getUserInstance(targetUser); @@ -583,20 +583,20 @@ public class AppSearchManagerService extends SystemService { long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime(); int callingUid = Binder.getCallingUid(); - UserHandle targetUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK; AppSearchUserInstance instance = null; int operationSuccessCount = 0; int operationFailureCount = 0; try { - Context targetUserContext = mContext.createContextAsUser(targetUser, - /*flags=*/ 0); + verifyCaller(callingUid, packageName); + + // Obtain the user where the client wants to run the operations in. This should + // end up being the same as userHandle, assuming it is not a special user and + // the client is allowed to run operations in that user. + UserHandle targetUser = handleIncomingUser(userHandle, callingUid); verifyUserUnlocked(targetUser); - // TODO(b/193902620): Pass in the callingUser and not the targetUser. - verifyCallingPackage(targetUserContext, targetUser, callingUid, packageName); - // TODO(b/194939218): Pass in the callingUser and not the targetUser. - verifyNotInstantApp(targetUserContext, packageName); + AppSearchBatchResult.Builder resultBuilder = new AppSearchBatchResult.Builder<>(); instance = mAppSearchUserInstanceManager.getUserInstance(targetUser); @@ -667,20 +667,20 @@ public class AppSearchManagerService extends SystemService { long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime(); int callingUid = Binder.getCallingUid(); - UserHandle targetUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK; AppSearchUserInstance instance = null; int operationSuccessCount = 0; int operationFailureCount = 0; try { - Context targetUserContext = mContext.createContextAsUser(targetUser, - /*flags=*/ 0); + verifyCaller(callingUid, packageName); + + // Obtain the user where the client wants to run the operations in. This should + // end up being the same as userHandle, assuming it is not a special user and + // the client is allowed to run operations in that user. + UserHandle targetUser = handleIncomingUser(userHandle, callingUid); verifyUserUnlocked(targetUser); - // TODO(b/193902620): Pass in the callingUser and not the targetUser. - verifyCallingPackage(targetUserContext, targetUser, callingUid, packageName); - // TODO(b/194939218): Pass in the callingUser and not the targetUser. - verifyNotInstantApp(targetUserContext, packageName); + instance = mAppSearchUserInstanceManager.getUserInstance(targetUser); SearchResultPage searchResultPage = instance.getAppSearchImpl().query( packageName, @@ -736,20 +736,20 @@ public class AppSearchManagerService extends SystemService { long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime(); int callingUid = Binder.getCallingUid(); - UserHandle targetUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK; AppSearchUserInstance instance = null; int operationSuccessCount = 0; int operationFailureCount = 0; try { - Context targetUserContext = mContext.createContextAsUser(targetUser, - /*flags=*/ 0); + verifyCaller(callingUid, packageName); + + // Obtain the user where the client wants to run the operations in. This should + // end up being the same as userHandle, assuming it is not a special user and + // the client is allowed to run operations in that user. + UserHandle targetUser = handleIncomingUser(userHandle, callingUid); verifyUserUnlocked(targetUser); - // TODO(b/193902620): Pass in the callingUser and not the targetUser. - verifyCallingPackage(targetUserContext, targetUser, callingUid, packageName); - // TODO(b/194939218): Pass in the callingUser and not the targetUser. - verifyNotInstantApp(targetUserContext, packageName); + instance = mAppSearchUserInstanceManager.getUserInstance(targetUser); boolean callerHasSystemAccess = @@ -804,18 +804,16 @@ public class AppSearchManagerService extends SystemService { Objects.requireNonNull(callback); int callingUid = Binder.getCallingUid(); - UserHandle targetUser = handleIncomingUser(userHandle, callingUid); - // TODO(b/162450968) check nextPageToken is being advanced by the same uid as originally - // opened it EXECUTOR.execute(() -> { try { - Context targetUserContext = mContext.createContextAsUser(targetUser, - /*flags=*/ 0); + verifyCaller(callingUid, packageName); + + // Obtain the user where the client wants to run the operations in. This should + // end up being the same as userHandle, assuming it is not a special user and + // the client is allowed to run operations in that user. + UserHandle targetUser = handleIncomingUser(userHandle, callingUid); verifyUserUnlocked(targetUser); - // TODO(b/193902620): Pass in the callingUser and not the targetUser. - verifyCallingPackage(targetUserContext, targetUser, callingUid, packageName); - // TODO(b/194939218): Pass in the callingUser and not the targetUser. - verifyNotInstantApp(targetUserContext, packageName); + AppSearchUserInstance instance = mAppSearchUserInstanceManager.getUserInstance(targetUser); SearchResultPage searchResultPage = @@ -836,16 +834,16 @@ public class AppSearchManagerService extends SystemService { Objects.requireNonNull(userHandle); int callingUid = Binder.getCallingUid(); - UserHandle targetUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { try { - Context targetUserContext = mContext.createContextAsUser(targetUser, - /*flags=*/ 0); + verifyCaller(callingUid, packageName); + + // Obtain the user where the client wants to run the operations in. This should + // end up being the same as userHandle, assuming it is not a special user and + // the client is allowed to run operations in that user. + UserHandle targetUser = handleIncomingUser(userHandle, callingUid); verifyUserUnlocked(targetUser); - // TODO(b/193902620): Pass in the callingUser and not the targetUser. - verifyCallingPackage(targetUserContext, targetUser, callingUid, packageName); - // TODO(b/194939218): Pass in the callingUser and not the targetUser. - verifyNotInstantApp(targetUserContext, packageName); + AppSearchUserInstance instance = mAppSearchUserInstanceManager.getUserInstance(targetUser); instance.getAppSearchImpl().invalidateNextPageToken(packageName, nextPageToken); @@ -873,16 +871,16 @@ public class AppSearchManagerService extends SystemService { Objects.requireNonNull(callback); int callingUid = Binder.getCallingUid(); - UserHandle targetUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { try { - Context targetUserContext = mContext.createContextAsUser(targetUser, - /*flags=*/ 0); + verifyCaller(callingUid, packageName); + + // Obtain the user where the client wants to run the operations in. This should + // end up being the same as userHandle, assuming it is not a special user and + // the client is allowed to run operations in that user. + UserHandle targetUser = handleIncomingUser(userHandle, callingUid); verifyUserUnlocked(targetUser); - // TODO(b/193902620): Pass in the callingUser and not the targetUser. - verifyCallingPackage(targetUserContext, targetUser, callingUid, packageName); - // TODO(b/194939218): Pass in the callingUser and not the targetUser. - verifyNotInstantApp(targetUserContext, packageName); + AppSearchUserInstance instance = mAppSearchUserInstanceManager.getUserInstance(targetUser); // we don't need to append the file. The file is always brand new. @@ -925,16 +923,16 @@ public class AppSearchManagerService extends SystemService { Objects.requireNonNull(callback); int callingUid = Binder.getCallingUid(); - UserHandle targetUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { try { - Context targetUserContext = mContext.createContextAsUser(targetUser, - /*flags=*/ 0); + verifyCaller(callingUid, packageName); + + // Obtain the user where the client wants to run the operations in. This should + // end up being the same as userHandle, assuming it is not a special user and + // the client is allowed to run operations in that user. + UserHandle targetUser = handleIncomingUser(userHandle, callingUid); verifyUserUnlocked(targetUser); - // TODO(b/193902620): Pass in the callingUser and not the targetUser. - verifyCallingPackage(targetUserContext, targetUser, callingUid, packageName); - // TODO(b/194939218): Pass in the callingUser and not the targetUser. - verifyNotInstantApp(targetUserContext, packageName); + AppSearchUserInstance instance = mAppSearchUserInstanceManager.getUserInstance(targetUser); @@ -990,16 +988,16 @@ public class AppSearchManagerService extends SystemService { Objects.requireNonNull(callback); int callingUid = Binder.getCallingUid(); - UserHandle targetUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { try { - Context targetUserContext = mContext.createContextAsUser(targetUser, - /*flags=*/ 0); + verifyCaller(callingUid, packageName); + + // Obtain the user where the client wants to run the operations in. This should + // end up being the same as userHandle, assuming it is not a special user and + // the client is allowed to run operations in that user. + UserHandle targetUser = handleIncomingUser(userHandle, callingUid); verifyUserUnlocked(targetUser); - // TODO(b/193902620): Pass in the callingUser and not the targetUser. - verifyCallingPackage(targetUserContext, targetUser, callingUid, packageName); - // TODO(b/194939218): Pass in the callingUser and not the targetUser. - verifyNotInstantApp(targetUserContext, packageName); + AppSearchUserInstance instance = mAppSearchUserInstanceManager.getUserInstance(targetUser); @@ -1040,20 +1038,20 @@ public class AppSearchManagerService extends SystemService { long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime(); int callingUid = Binder.getCallingUid(); - UserHandle targetUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK; AppSearchUserInstance instance = null; int operationSuccessCount = 0; int operationFailureCount = 0; try { - Context targetUserContext = mContext.createContextAsUser(targetUser, - /*flags=*/ 0); + verifyCaller(callingUid, packageName); + + // Obtain the user where the client wants to run the operations in. This should + // end up being the same as userHandle, assuming it is not a special user and + // the client is allowed to run operations in that user. + UserHandle targetUser = handleIncomingUser(userHandle, callingUid); verifyUserUnlocked(targetUser); - // TODO(b/193902620): Pass in the callingUser and not the targetUser. - verifyCallingPackage(targetUserContext, targetUser, callingUid, packageName); - // TODO(b/194939218): Pass in the callingUser and not the targetUser. - verifyNotInstantApp(targetUserContext, packageName); + AppSearchBatchResult.Builder resultBuilder = new AppSearchBatchResult.Builder<>(); instance = mAppSearchUserInstanceManager.getUserInstance(targetUser); @@ -1129,20 +1127,20 @@ public class AppSearchManagerService extends SystemService { long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime(); int callingUid = Binder.getCallingUid(); - UserHandle targetUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK; AppSearchUserInstance instance = null; int operationSuccessCount = 0; int operationFailureCount = 0; try { - Context targetUserContext = mContext.createContextAsUser(targetUser, - /*flags=*/ 0); + verifyCaller(callingUid, packageName); + + // Obtain the user where the client wants to run the operations in. This should + // end up being the same as userHandle, assuming it is not a special user and + // the client is allowed to run operations in that user. + UserHandle targetUser = handleIncomingUser(userHandle, callingUid); verifyUserUnlocked(targetUser); - // TODO(b/193902620): Pass in the callingUser and not the targetUser. - verifyCallingPackage(targetUserContext, targetUser, callingUid, packageName); - // TODO(b/194939218): Pass in the callingUser and not the targetUser. - verifyNotInstantApp(targetUserContext, packageName); + instance = mAppSearchUserInstanceManager.getUserInstance(targetUser); instance.getAppSearchImpl().removeByQuery( packageName, @@ -1196,16 +1194,16 @@ public class AppSearchManagerService extends SystemService { Objects.requireNonNull(callback); int callingUid = Binder.getCallingUid(); - UserHandle targetUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { try { - Context targetUserContext = mContext.createContextAsUser(targetUser, - /*flags=*/ 0); + verifyCaller(callingUid, packageName); + + // Obtain the user where the client wants to run the operations in. This should + // end up being the same as userHandle, assuming it is not a special user and + // the client is allowed to run operations in that user. + UserHandle targetUser = handleIncomingUser(userHandle, callingUid); verifyUserUnlocked(targetUser); - // TODO(b/193902620): Pass in the callingUser and not the targetUser. - verifyCallingPackage(targetUserContext, targetUser, callingUid, packageName); - // TODO(b/194939218): Pass in the callingUser and not the targetUser. - verifyNotInstantApp(targetUserContext, packageName); + AppSearchUserInstance instance = mAppSearchUserInstanceManager.getUserInstance(targetUser); StorageInfo storageInfo = instance.getAppSearchImpl() @@ -1229,20 +1227,20 @@ public class AppSearchManagerService extends SystemService { long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime(); int callingUid = Binder.getCallingUid(); - UserHandle targetUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK; AppSearchUserInstance instance = null; int operationSuccessCount = 0; int operationFailureCount = 0; try { - Context targetUserContext = mContext.createContextAsUser(targetUser, - /*flags=*/ 0); + verifyCaller(callingUid, packageName); + + // Obtain the user where the client wants to run the operations in. This should + // end up being the same as userHandle, assuming it is not a special user and + // the client is allowed to run operations in that user. + UserHandle targetUser = handleIncomingUser(userHandle, callingUid); verifyUserUnlocked(targetUser); - // TODO(b/193902620): Pass in the callingUser and not the targetUser. - verifyCallingPackage(targetUserContext, targetUser, callingUid, packageName); - // TODO(b/194939218): Pass in the callingUser and not the targetUser. - verifyNotInstantApp(targetUserContext, packageName); + instance = mAppSearchUserInstanceManager.getUserInstance(targetUser); instance.getAppSearchImpl().persistToDisk(PersistType.Code.FULL); ++operationSuccessCount; @@ -1284,7 +1282,6 @@ public class AppSearchManagerService extends SystemService { long totalLatencyStartTimeMillis = SystemClock.elapsedRealtime(); int callingUid = Binder.getCallingUid(); - UserHandle targetUser = handleIncomingUser(userHandle, callingUid); EXECUTOR.execute(() -> { @AppSearchResult.ResultCode int statusCode = AppSearchResult.RESULT_OK; @@ -1292,13 +1289,16 @@ public class AppSearchManagerService extends SystemService { int operationSuccessCount = 0; int operationFailureCount = 0; try { + verifyCaller(callingUid, packageName); + + // Obtain the user where the client wants to run the operations in. This should + // end up being the same as userHandle, assuming it is not a special user and + // the client is allowed to run operations in that user. + UserHandle targetUser = handleIncomingUser(userHandle, callingUid); + verifyUserUnlocked(targetUser); + Context targetUserContext = mContext.createContextAsUser(targetUser, /*flags=*/ 0); - verifyUserUnlocked(targetUser); - // TODO(b/193902620): Pass in the callingUser and not the targetUser. - verifyCallingPackage(targetUserContext, targetUser, callingUid, packageName); - // TODO(b/194939218): Pass in the callingUser and not the targetUser. - verifyNotInstantApp(targetUserContext, packageName); instance = mAppSearchUserInstanceManager.getOrCreateUserInstance( targetUserContext, targetUser, AppSearchConfig.getInstance(EXECUTOR)); ++operationSuccessCount; @@ -1329,29 +1329,6 @@ public class AppSearchManagerService extends SystemService { }); } - private void verifyCallingPackage( - @NonNull Context userContext, - @NonNull UserHandle actualCallingUser, - int actualCallingUid, - @NonNull String claimedCallingPackage) { - Objects.requireNonNull(actualCallingUser); - Objects.requireNonNull(claimedCallingPackage); - - int claimedCallingUid = PackageUtil.getPackageUid( - userContext, claimedCallingPackage); - if (claimedCallingUid == INVALID_UID) { - throw new SecurityException( - "Specified calling package [" + claimedCallingPackage + "] not found"); - } - if (claimedCallingUid != actualCallingUid) { - throw new SecurityException( - "Specified calling package [" - + claimedCallingPackage - + "] does not match the calling uid " - + actualCallingUid); - } - } - /** Invokes the {@link IAppSearchResultCallback} with the result. */ private void invokeCallbackOnResult( IAppSearchResultCallback callback, AppSearchResult result) { @@ -1428,10 +1405,49 @@ public class AppSearchManagerService extends SystemService { } /** - * Helper for ensuring instant apps can't make calls to AppSearch. + * Verify various aspects of the calling user. + * + * @param callingUid Uid of the caller, usually retrieved from Binder for authenticity. + * @param claimedCallingPackage Package name the caller claims to be. + */ + private void verifyCaller(int callingUid, @NonNull String claimedCallingPackage) { + // Obtain the user where the client is running in. Note that this could be different from + // the userHandle where the client wants to run the AppSearch operation in. + UserHandle callingUserHandle = UserHandle.getUserHandleForUid(callingUid); + Context callingUserContext = mContext.createContextAsUser(callingUserHandle, + /*flags=*/ 0); + + verifyCallingPackage(callingUserContext, callingUid, claimedCallingPackage); + verifyNotInstantApp(callingUserContext, claimedCallingPackage); + } + + /** + * Check that the caller's supposed package name matches the uid making the call. + * + * @throws SecurityException if the package name and uid don't match. + */ + private void verifyCallingPackage( + @NonNull Context actualCallingUserContext, + int actualCallingUid, + @NonNull String claimedCallingPackage) { + int claimedCallingUid = PackageUtil.getPackageUid( + actualCallingUserContext, claimedCallingPackage); + if (claimedCallingUid == INVALID_UID) { + throw new SecurityException( + "Specified calling package [" + claimedCallingPackage + "] not found"); + } + if (claimedCallingUid != actualCallingUid) { + throw new SecurityException( + "Specified calling package [" + + claimedCallingPackage + + "] does not match the calling uid " + + actualCallingUid); + } + } + + /** + * Ensure instant apps can't make calls to AppSearch. * - * @param userContext Context of the user making the call. - * @param packageName Package name of the caller. * @throws SecurityException if the caller is an instant app. */ private void verifyNotInstantApp(@NonNull Context userContext, @NonNull String packageName) {