From fde8a2f917663c963090bdfb140cfb353859b2fe Mon Sep 17 00:00:00 2001 From: Joanne Chung Date: Wed, 30 Dec 2020 13:02:13 +0800 Subject: [PATCH] Get ApplicationInfo using usr id Use ApplicationInfoAsUser() to get the application information by user id to make sure we have correct permission, othewise we will get the SecurityException due to lack of INTERACT_ACROSS_USERS. Also add checking in StartProxyOp, we don't add it in client code. Bug: 176313819 Test: atest CtsVoiceRecognitionTestCases Test: manual. 1.create profile user 2.Install sample recognizer app 3.Function works fine and no security exception occurred after apply the change Change-Id: Iaf485537b8082d2109d2134ff987dc7244e31218 --- core/java/android/app/AppOpsManager.java | 20 +++++++++++-------- .../android/server/appop/AppOpsService.java | 8 ++++---- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 20953c6f6637b..a23dd35fa55f9 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -7664,8 +7664,8 @@ public class AppOpsManager { } else if (collectionMode == COLLECT_SYNC // Only collect app-ops when the proxy is trusted && (mContext.checkPermission(Manifest.permission.UPDATE_APP_OPS_STATS, -1, - myUid) == PackageManager.PERMISSION_GRANTED - || isTrustedVoiceServiceProxy(mContext, mContext.getOpPackageName(), op))) { + myUid) == PackageManager.PERMISSION_GRANTED || isTrustedVoiceServiceProxy( + mContext, mContext.getOpPackageName(), op, mContext.getUserId()))) { collectNotedOpSync(op, proxiedAttributionTag); } } @@ -7683,7 +7683,7 @@ public class AppOpsManager { * @hide */ public static boolean isTrustedVoiceServiceProxy(Context context, String packageName, - int code) { + int code, int userId) { // This is a workaround for R QPR, new API change is not allowed. We only allow the current // voice recognizer is also the voice interactor to noteproxy op. if (code != OP_RECORD_AUDIO) { @@ -7695,7 +7695,7 @@ public class AppOpsManager { final String voiceRecognitionServicePackageName = getComponentPackageNameFromString(voiceRecognitionComponent); return (Objects.equals(packageName, voiceRecognitionServicePackageName)) - && isPackagePreInstalled(context, packageName); + && isPackagePreInstalled(context, packageName, userId); } private static String getComponentPackageNameFromString(String from) { @@ -7703,10 +7703,11 @@ public class AppOpsManager { return componentName != null ? componentName.getPackageName() : ""; } - private static boolean isPackagePreInstalled(Context context, String packageName) { + private static boolean isPackagePreInstalled(Context context, String packageName, int userId) { try { final PackageManager pm = context.getPackageManager(); - final ApplicationInfo info = pm.getApplicationInfo(packageName, 0); + final ApplicationInfo info = + pm.getApplicationInfoAsUser(packageName, 0, userId); return ((info.flags & ApplicationInfo.FLAG_SYSTEM) != 0); } catch (PackageManager.NameNotFoundException e) { return false; @@ -8069,12 +8070,15 @@ public class AppOpsManager { collectNotedOpForSelf(opInt, proxiedAttributionTag); } else if (collectionMode == COLLECT_SYNC // Only collect app-ops when the proxy is trusted - && mContext.checkPermission(Manifest.permission.UPDATE_APP_OPS_STATS, -1, - Process.myUid()) == PackageManager.PERMISSION_GRANTED) { + && (mContext.checkPermission(Manifest.permission.UPDATE_APP_OPS_STATS, -1, + Process.myUid()) == PackageManager.PERMISSION_GRANTED + || isTrustedVoiceServiceProxy(mContext, mContext.getOpPackageName(), opInt, + mContext.getUserId()))) { collectNotedOpSync(opInt, proxiedAttributionTag); } } + return mode; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index 360ed9d43a49d..38c8d6cb1e2a2 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -3032,8 +3032,8 @@ public class AppOpsService extends IAppOpsService.Stub { // This is a workaround for R QPR, new API change is not allowed. We only allow the current // voice recognizer is also the voice interactor to noteproxy op. - final boolean isTrustVoiceServiceProxy = - AppOpsManager.isTrustedVoiceServiceProxy(mContext, proxyPackageName, code); + final boolean isTrustVoiceServiceProxy = AppOpsManager.isTrustedVoiceServiceProxy(mContext, + proxyPackageName, code, UserHandle.getUserId(proxyUid)); final boolean isSelfBlame = Binder.getCallingUid() == proxiedUid; final boolean isProxyTrusted = mContext.checkPermission( Manifest.permission.UPDATE_APP_OPS_STATS, -1, proxyUid) @@ -3502,8 +3502,8 @@ public class AppOpsService extends IAppOpsService.Stub { // This is a workaround for R QPR, new API change is not allowed. We only allow the current // voice recognizer is also the voice interactor to noteproxy op. - final boolean isTrustVoiceServiceProxy = - AppOpsManager.isTrustedVoiceServiceProxy(mContext, proxyPackageName, code); + final boolean isTrustVoiceServiceProxy = AppOpsManager.isTrustedVoiceServiceProxy(mContext, + proxyPackageName, code, UserHandle.getUserId(proxyUid)); final boolean isSelfBlame = Binder.getCallingUid() == proxiedUid; final boolean isProxyTrusted = mContext.checkPermission( Manifest.permission.UPDATE_APP_OPS_STATS, -1, proxyUid)