From 9403fa983207017339a814e7c32fc024e2cb4f41 Mon Sep 17 00:00:00 2001 From: Todd Kennedy Date: Thu, 18 May 2017 16:31:33 -0700 Subject: [PATCH] Blanket deny instant apps from some methods There are many methods instant apps are not allowed to call. Throw a SecurityException if they try to call them. Bug: 35871369 Test: cts-tradefed run commandAndExit cts-dev -m CtsAppSecurityHostTestCases -t android.appsecurity.cts.EphemeralTest Test: Manual; install instant app and ensure it runs Change-Id: Iffdc6cd4e298fc4e1070e68abf7065369d0bed25 --- .../server/pm/PackageManagerService.java | 276 ++++++++++++++---- 1 file changed, 221 insertions(+), 55 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index b1068ae70d803..edf6dfc432dbe 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -20,7 +20,6 @@ import static android.Manifest.permission.DELETE_PACKAGES; import static android.Manifest.permission.INSTALL_PACKAGES; import static android.Manifest.permission.READ_EXTERNAL_STORAGE; import static android.Manifest.permission.REQUEST_DELETE_PACKAGES; -import static android.Manifest.permission.REQUEST_INSTALL_PACKAGES; import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE; import static android.Manifest.permission.WRITE_MEDIA_STORAGE; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; @@ -100,7 +99,6 @@ import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefa import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE; import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS; import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED; - import static dalvik.system.DexFile.getNonProfileGuidedCompilerFilter; import android.Manifest; @@ -126,10 +124,8 @@ import android.content.ServiceConnection; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.AppsQueryHelper; -import android.content.pm.ChangedPackages; -import android.content.pm.ComponentInfo; -import android.content.pm.InstantAppRequest; import android.content.pm.AuxiliaryResolveInfo; +import android.content.pm.ChangedPackages; import android.content.pm.FallbackCategoryProvider; import android.content.pm.FeatureInfo; import android.content.pm.IOnPermissionsChangeListener; @@ -142,6 +138,7 @@ import android.content.pm.IPackageManager; import android.content.pm.IPackageMoveObserver; import android.content.pm.IPackageStatsObserver; import android.content.pm.InstantAppInfo; +import android.content.pm.InstantAppRequest; import android.content.pm.InstantAppResolveInfo; import android.content.pm.InstrumentationInfo; import android.content.pm.IntentFilterVerificationInfo; @@ -3086,16 +3083,19 @@ public class PackageManagerService extends IPackageManager.Stub @Override public boolean isFirstBoot() { + // allow instant applications return mFirstBoot; } @Override public boolean isOnlyCoreApps() { + // allow instant applications return mOnlyCore; } @Override public boolean isUpgrade() { + // allow instant applications return mIsUpgrade; } @@ -3189,6 +3189,9 @@ public class PackageManagerService extends IPackageManager.Stub @Override public @Nullable ComponentName getInstantAppResolverComponent() { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return null; + } synchronized (mPackages) { final Pair instantAppResolver = getInstantAppResolverLPr(); if (instantAppResolver == null) { @@ -3576,8 +3579,10 @@ public class PackageManagerService extends IPackageManager.Stub @Override public void checkPackageStartable(String packageName, int userId) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + throw new SecurityException("Instant applications don't have access to this method"); + } final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId); - synchronized (mPackages) { final PackageSetting ps = mSettings.mPackages.get(packageName); if (ps == null) { @@ -3797,6 +3802,9 @@ public class PackageManagerService extends IPackageManager.Stub @Override public String[] currentToCanonicalPackageNames(String[] names) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return names; + } String[] out = new String[names.length]; // reader synchronized (mPackages) { @@ -3810,6 +3818,9 @@ public class PackageManagerService extends IPackageManager.Stub @Override public String[] canonicalToCurrentPackageNames(String[] names) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return names; + } String[] out = new String[names.length]; // reader synchronized (mPackages) { @@ -3887,6 +3898,9 @@ public class PackageManagerService extends IPackageManager.Stub @Override public PermissionInfo getPermissionInfo(String name, int flags) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return null; + } // reader synchronized (mPackages) { final BasePermission p = mSettings.mPermissions.get(name); @@ -3900,6 +3914,9 @@ public class PackageManagerService extends IPackageManager.Stub @Override public @Nullable ParceledListSlice queryPermissionsByGroup(String group, int flags) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return null; + } // reader synchronized (mPackages) { if (group != null && !mPermissionGroups.containsKey(group)) { @@ -3925,6 +3942,9 @@ public class PackageManagerService extends IPackageManager.Stub @Override public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return null; + } // reader synchronized (mPackages) { return PackageParser.generatePermissionGroupInfo( @@ -3934,6 +3954,9 @@ public class PackageManagerService extends IPackageManager.Stub @Override public @NonNull ParceledListSlice getAllPermissionGroups(int flags) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return ParceledListSlice.emptyList(); + } // reader synchronized (mPackages) { final int N = mPermissionGroups.size(); @@ -4428,6 +4451,9 @@ public class PackageManagerService extends IPackageManager.Stub int flags, int userId) { if (!sUserManager.exists(userId)) return null; Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0"); + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return null; + } flags = updateFlagsForPackage(flags, userId, null); @@ -4638,6 +4664,7 @@ public class PackageManagerService extends IPackageManager.Stub @Override public @NonNull String getServicesSystemSharedLibraryPackageName() { + // allow instant applications synchronized (mPackages) { return mServicesSystemSharedLibraryPackageName; } @@ -4645,6 +4672,7 @@ public class PackageManagerService extends IPackageManager.Stub @Override public @NonNull String getSharedSystemSharedLibraryPackageName() { + // allow instant applications synchronized (mPackages) { return mSharedSystemSharedLibraryPackageName; } @@ -4675,6 +4703,9 @@ public class PackageManagerService extends IPackageManager.Stub @Override public ChangedPackages getChangedPackages(int sequenceNumber, int userId) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return null; + } synchronized (mPackages) { if (sequenceNumber >= mChangedPackagesSequenceNumber) { return null; @@ -4698,6 +4729,7 @@ public class PackageManagerService extends IPackageManager.Stub @Override public @NonNull ParceledListSlice getSystemAvailableFeatures() { + // allow instant applications ArrayList res; synchronized (mAvailableFeatures) { res = new ArrayList<>(mAvailableFeatures.size() + 1); @@ -4713,6 +4745,7 @@ public class PackageManagerService extends IPackageManager.Stub @Override public boolean hasSystemFeature(String name, int version) { + // allow instant applications synchronized (mAvailableFeatures) { final FeatureInfo feat = mAvailableFeatures.get(name); if (feat == null) { @@ -4810,6 +4843,9 @@ public class PackageManagerService extends IPackageManager.Stub @Override public String getPermissionControllerPackageName() { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + throw new SecurityException("Instant applications don't have access to this method"); + } synchronized (mPackages) { return mRequiredInstallerPackage; } @@ -4944,6 +4980,9 @@ public class PackageManagerService extends IPackageManager.Stub } boolean addPermissionLocked(PermissionInfo info, boolean async) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + throw new SecurityException("Instant apps can't add permissions"); + } if (info.labelRes == 0 && info.nonLocalizedLabel == null) { throw new SecurityException("Label must be specified in permission"); } @@ -5003,6 +5042,9 @@ public class PackageManagerService extends IPackageManager.Stub @Override public void removePermission(String name) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + throw new SecurityException("Instant applications don't have access to this method"); + } synchronized (mPackages) { checkPermissionTreeLP(name); BasePermission bp = mSettings.mPermissions.get(name); @@ -5018,8 +5060,8 @@ public class PackageManagerService extends IPackageManager.Stub } } - private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg, - BasePermission bp) { + private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission( + PackageParser.Package pkg, BasePermission bp) { int index = pkg.requestedPermissions.indexOf(bp.name); if (index == -1) { throw new SecurityException("Package " + pkg.packageName @@ -5536,6 +5578,9 @@ public class PackageManagerService extends IPackageManager.Stub @Override public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + throw new SecurityException("Instant applications don't have access to this method"); + } synchronized (mPackages) { mOnPermissionChangeListeners.removeListenerLocked(listener); } @@ -5543,6 +5588,7 @@ public class PackageManagerService extends IPackageManager.Stub @Override public boolean isProtectedBroadcast(String actionName) { + // allow instant applications synchronized (mPackages) { if (mProtectedBroadcasts.contains(actionName)) { return true; @@ -5819,6 +5865,9 @@ public class PackageManagerService extends IPackageManager.Stub @Override public int getUidForSharedUser(String sharedUserName) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return -1; + } if(sharedUserName == null) { return -1; } @@ -5839,6 +5888,9 @@ public class PackageManagerService extends IPackageManager.Stub @Override public int getFlagsForUid(int uid) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return 0; + } synchronized (mPackages) { Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); if (obj instanceof SharedUserSetting) { @@ -5854,6 +5906,9 @@ public class PackageManagerService extends IPackageManager.Stub @Override public int getPrivateFlagsForUid(int uid) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return 0; + } synchronized (mPackages) { Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); if (obj instanceof SharedUserSetting) { @@ -5869,6 +5924,9 @@ public class PackageManagerService extends IPackageManager.Stub @Override public boolean isUidPrivileged(int uid) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return false; + } uid = UserHandle.getAppId(uid); // reader synchronized (mPackages) { @@ -5891,6 +5949,9 @@ public class PackageManagerService extends IPackageManager.Stub @Override public String[] getAppOpPermissionPackages(String permissionName) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return null; + } synchronized (mPackages) { ArraySet pkgs = mAppOpPermissionPackages.get(permissionName); if (pkgs == null) { @@ -5956,6 +6017,9 @@ public class PackageManagerService extends IPackageManager.Stub @Override public void setLastChosenActivity(Intent intent, String resolvedType, int flags, IntentFilter filter, int match, ComponentName activity) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return; + } final int userId = UserHandle.getCallingUserId(); if (DEBUG_PREFERRED) { Log.v(TAG, "setLastChosenActivity intent=" + intent @@ -5979,6 +6043,9 @@ public class PackageManagerService extends IPackageManager.Stub @Override public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return null; + } final int userId = UserHandle.getCallingUserId(); if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent); final List query = queryIntentActivitiesInternal(intent, resolvedType, flags, @@ -6440,12 +6507,12 @@ public class PackageManagerService extends IPackageManager.Stub * instant, returns {@code null}. */ private String getInstantAppPackageName(int callingUid) { - // If the caller is an isolated app use the owner's uid for the lookup. - if (Process.isIsolated(callingUid)) { - callingUid = mIsolatedOwners.get(callingUid); - } - final int appId = UserHandle.getAppId(callingUid); synchronized (mPackages) { + // If the caller is an isolated app use the owner's uid for the lookup. + if (Process.isIsolated(callingUid)) { + callingUid = mIsolatedOwners.get(callingUid); + } + final int appId = UserHandle.getAppId(callingUid); final Object obj = mSettings.getUserIdLPr(appId); if (obj instanceof PackageSetting) { final PackageSetting ps = (PackageSetting) obj; @@ -7662,6 +7729,9 @@ public class PackageManagerService extends IPackageManager.Stub @Override public ParceledListSlice getInstalledPackages(int flags, int userId) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return ParceledListSlice.emptyList(); + } if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); flags = updateFlagsForPackage(flags, userId, null); final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0; @@ -7776,6 +7846,9 @@ public class PackageManagerService extends IPackageManager.Stub @Override public ParceledListSlice getInstalledApplications(int flags, int userId) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return ParceledListSlice.emptyList(); + } if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); flags = updateFlagsForApplication(flags, userId, null); final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0; @@ -7839,7 +7912,6 @@ public class PackageManagerService extends IPackageManager.Stub if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) { return null; } - mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS, "getEphemeralApplications"); enforceCrossUserPermission(Binder.getCallingUid(), userId, @@ -7863,9 +7935,9 @@ public class PackageManagerService extends IPackageManager.Stub if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) { return false; } - int uid = Binder.getCallingUid(); - if (Process.isIsolated(uid)) { - uid = mIsolatedOwners.get(uid); + int callingUid = Binder.getCallingUid(); + if (Process.isIsolated(callingUid)) { + callingUid = mIsolatedOwners.get(callingUid); } synchronized (mPackages) { @@ -7873,12 +7945,12 @@ public class PackageManagerService extends IPackageManager.Stub PackageParser.Package pkg = mPackages.get(packageName); final boolean returnAllowed = ps != null - && (isCallerSameApp(packageName, uid) + && (isCallerSameApp(packageName, callingUid) || mContext.checkCallingOrSelfPermission( android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED || mInstantAppRegistry.isInstantAccessGranted( - userId, UserHandle.getAppId(uid), ps.appId)); + userId, UserHandle.getAppId(callingUid), ps.appId)); if (returnAllowed) { return ps.getInstantApp(userId); } @@ -7949,6 +8021,9 @@ public class PackageManagerService extends IPackageManager.Stub @Override public @NonNull ParceledListSlice getPersistentApplications(int flags) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return ParceledListSlice.emptyList(); + } return new ParceledListSlice<>(getPersistentApplicationsInternal(flags)); } @@ -8032,6 +8107,9 @@ public class PackageManagerService extends IPackageManager.Stub */ @Deprecated public void querySyncProviders(List outNames, List outInfo) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return; + } // reader synchronized (mPackages) { final Iterator> i = mProvidersByAuthority @@ -8727,7 +8805,7 @@ public class PackageManagerService extends IPackageManager.Stub */ private static final void enforceSystemOrRoot(String message) { final int uid = Binder.getCallingUid(); - if (uid != Process.SYSTEM_UID && uid != 0) { + if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID) { throw new SecurityException(message); } } @@ -8933,6 +9011,9 @@ public class PackageManagerService extends IPackageManager.Stub @Override public boolean performDexOptMode(String packageName, boolean checkProfiles, String targetCompilerFilter, boolean force) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return false; + } int dexOptStatus = performDexOptTraced(packageName, checkProfiles, targetCompilerFilter, force); return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED; @@ -9026,6 +9107,9 @@ public class PackageManagerService extends IPackageManager.Stub @Override public boolean performDexOptSecondary(String packageName, String compilerFilter, boolean force) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return false; + } mDexManager.reconcileSecondaryDexFiles(packageName); return mDexManager.dexoptSecondaryDex(packageName, compilerFilter, force); } @@ -9042,6 +9126,9 @@ public class PackageManagerService extends IPackageManager.Stub */ @Override public void reconcileSecondaryDexFiles(String packageName) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return; + } mDexManager.reconcileSecondaryDexFiles(packageName); } @@ -9056,6 +9143,9 @@ public class PackageManagerService extends IPackageManager.Stub */ @Override public boolean runBackgroundDexoptJob() { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return false; + } return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext); } @@ -13509,6 +13599,9 @@ public class PackageManagerService extends IPackageManager.Stub @Override public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return null; + } // writer synchronized (mPackages) { if (!isExternalMediaAvailable()) { @@ -14423,6 +14516,9 @@ public class PackageManagerService extends IPackageManager.Stub @Override public int getIntentVerificationStatus(String packageName, int userId) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; + } synchronized (mPackages) { return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); } @@ -14446,6 +14542,9 @@ public class PackageManagerService extends IPackageManager.Stub @Override public @NonNull ParceledListSlice getIntentFilterVerifications( String packageName) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return ParceledListSlice.emptyList(); + } synchronized (mPackages) { return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName)); } @@ -14490,6 +14589,9 @@ public class PackageManagerService extends IPackageManager.Stub @Override public String getDefaultBrowserPackageName(int userId) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return null; + } synchronized (mPackages) { return mSettings.getDefaultBrowserPackageNameLPw(userId); } @@ -14508,7 +14610,10 @@ public class PackageManagerService extends IPackageManager.Stub @Override public void setInstallerPackageName(String targetPackage, String installerPackageName) { - final int uid = Binder.getCallingUid(); + final int callingUid = Binder.getCallingUid(); + if (getInstantAppPackageName(callingUid) != null) { + return; + } // writer synchronized (mPackages) { PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage); @@ -14528,17 +14633,17 @@ public class PackageManagerService extends IPackageManager.Stub } Signature[] callerSignature; - Object obj = mSettings.getUserIdLPr(uid); + Object obj = mSettings.getUserIdLPr(callingUid); if (obj != null) { if (obj instanceof SharedUserSetting) { callerSignature = ((SharedUserSetting)obj).signatures.mSignatures; } else if (obj instanceof PackageSetting) { callerSignature = ((PackageSetting)obj).signatures.mSignatures; } else { - throw new SecurityException("Bad object " + obj + " for uid " + uid); + throw new SecurityException("Bad object " + obj + " for uid " + callingUid); } } else { - throw new SecurityException("Unknown calling UID: " + uid); + throw new SecurityException("Unknown calling UID: " + callingUid); } // Verify: can't set installerPackageName to a package that is @@ -14583,6 +14688,9 @@ public class PackageManagerService extends IPackageManager.Stub @Override public void setApplicationCategoryHint(String packageName, int categoryHint, String callerPackageName) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + throw new SecurityException("Instant applications don't have access to this method"); + } mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(), callerPackageName); synchronized (mPackages) { @@ -16592,9 +16700,13 @@ public class PackageManagerService extends IPackageManager.Stub } } + @Override public List getPreviousCodePaths(String packageName) { + final List result = new ArrayList<>(); + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return result; + } final PackageSetting ps = mSettings.mPackages.get(packageName); - final List result = new ArrayList(); if (ps != null && ps.oldCodePaths != null) { result.addAll(ps.oldCodePaths); } @@ -18719,11 +18831,7 @@ public class PackageManagerService extends IPackageManager.Stub @Override public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) { - int callingUid = Binder.getCallingUid(); - if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) { - throw new SecurityException( - "setRequiredForSystemUser can only be run by the system or root"); - } + enforceSystemOrRoot("setRequiredForSystemUser can only be run by the system or root"); synchronized (mPackages) { PackageSetting ps = mSettings.mPackages.get(packageName); if (ps == null) { @@ -19577,18 +19685,21 @@ public class PackageManagerService extends IPackageManager.Stub @Override public void clearPackagePreferredActivities(String packageName) { - final int uid = Binder.getCallingUid(); + final int callingUid = Binder.getCallingUid(); + if (getInstantAppPackageName(callingUid) != null) { + return; + } // writer synchronized (mPackages) { PackageParser.Package pkg = mPackages.get(packageName); - if (pkg == null || pkg.applicationInfo.uid != uid) { + if (pkg == null || pkg.applicationInfo.uid != callingUid) { if (mContext.checkCallingOrSelfPermission( android.Manifest.permission.SET_PREFERRED_APPLICATIONS) != PackageManager.PERMISSION_GRANTED) { - if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid()) + if (getUidTargetSdkVersionLockedLPr(callingUid) < Build.VERSION_CODES.FROYO) { Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid " - + Binder.getCallingUid()); + + callingUid); return; } mContext.enforceCallingOrSelfPermission( @@ -19711,7 +19822,9 @@ public class PackageManagerService extends IPackageManager.Stub @Override public int getPreferredActivities(List outFilters, List outActivities, String packageName) { - + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return 0; + } int num = 0; final int userId = UserHandle.getCallingUserId(); // reader @@ -20280,6 +20393,9 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); @Override public ComponentName getHomeActivities(List allHomeCandidates) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return null; + } return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId()); } @@ -20364,6 +20480,9 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); @Override public void setHomeActivity(ComponentName comp, int userId) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return; + } ArrayList homeActivities = new ArrayList<>(); getHomeActivitiesAsUser(homeActivities, userId); @@ -20461,43 +20580,58 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); + newState); } PackageSetting pkgSetting; - final int uid = Binder.getCallingUid(); + final int callingUid = Binder.getCallingUid(); final int permission; - if (uid == Process.SYSTEM_UID) { + if (callingUid == Process.SYSTEM_UID) { permission = PackageManager.PERMISSION_GRANTED; } else { permission = mContext.checkCallingOrSelfPermission( android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); } - enforceCrossUserPermission(uid, userId, + enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */, true /* checkShell */, "set enabled"); final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); boolean sendNow = false; boolean isApp = (className == null); + final boolean isCallerInstantApp = (getInstantAppPackageName(callingUid) != null); String componentName = isApp ? packageName : className; int packageUid = -1; ArrayList components; - // writer + // reader synchronized (mPackages) { pkgSetting = mSettings.mPackages.get(packageName); if (pkgSetting == null) { - if (className == null) { - throw new IllegalArgumentException("Unknown package: " + packageName); + if (!isCallerInstantApp) { + if (className == null) { + throw new IllegalArgumentException("Unknown package: " + packageName); + } + throw new IllegalArgumentException( + "Unknown component: " + packageName + "/" + className); + } else { + // throw SecurityException to prevent leaking package information + throw new SecurityException( + "Attempt to change component state; " + + "pid=" + Binder.getCallingPid() + + ", uid=" + callingUid + + (className == null + ? ", package=" + packageName + : ", component=" + packageName + "/" + className)); } - throw new IllegalArgumentException( - "Unknown component: " + packageName + "/" + className); } } // Limit who can change which apps - if (!UserHandle.isSameApp(uid, pkgSetting.appId)) { + if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) { // Don't allow apps that don't have permission to modify other apps if (!allowedByPermission) { throw new SecurityException( - "Permission Denial: attempt to change component state from pid=" - + Binder.getCallingPid() - + ", uid=" + uid + ", package uid=" + pkgSetting.appId); + "Attempt to change component state; " + + "pid=" + Binder.getCallingPid() + + ", uid=" + callingUid + + (className == null + ? ", package=" + packageName + : ", component=" + packageName + "/" + className)); } // Don't allow changing protected packages. if (mProtectedPackages.isPackageStateProtected(userId, packageName)) { @@ -20506,7 +20640,7 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); } synchronized (mPackages) { - if (uid == Process.SHELL_UID + if (callingUid == Process.SHELL_UID && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) { // Shell can only change whole packages between ENABLED and DISABLED_USER states // unless it is a test package. @@ -20622,6 +20756,9 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); @Override public void flushPackageRestrictionsAsUser(int userId) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return; + } if (!sUserManager.exists(userId)) { return; } @@ -20660,16 +20797,19 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); @Override public void setPackageStoppedState(String packageName, boolean stopped, int userId) { if (!sUserManager.exists(userId)) return; - final int uid = Binder.getCallingUid(); + final int callingUid = Binder.getCallingUid(); + if (getInstantAppPackageName(callingUid) != null) { + return; + } final int permission = mContext.checkCallingOrSelfPermission( android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); - enforceCrossUserPermission(uid, userId, + enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */, true /* checkShell */, "stop package"); // writer synchronized (mPackages) { if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped, - allowedByPermission, uid, userId)) { + allowedByPermission, callingUid, userId)) { scheduleWritePackageRestrictionsLocked(userId); } } @@ -20677,6 +20817,9 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); @Override public String getInstallerPackageName(String packageName) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return null; + } // reader synchronized (mPackages) { return mSettings.getInstallerPackageNameLPr(packageName); @@ -20725,6 +20868,8 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); @Override public void systemReady() { + enforceSystemOrRoot("Only the system can claim the system is ready"); + mSystemReady = true; final ContentResolver resolver = mContext.getContentResolver(); ContentObserver co = new ContentObserver(mHandler) { @@ -20872,11 +21017,13 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); @Override public boolean isSafeMode() { + // allow instant applications return mSafeMode; } @Override public boolean hasSystemUidErrors() { + // allow instant applications return mHasSystemUidErrors; } @@ -21838,10 +21985,7 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); */ @Override public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) { - int callingUid = Binder.getCallingUid(); - if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { - throw new SecurityException("Media status can only be updated by the system"); - } + enforceSystemOrRoot("Media status can only be updated by the system"); // reader; this apparently protects mMediaMounted, but should probably // be a different lock in that case. synchronized (mPackages) { @@ -23173,6 +23317,7 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); @Override public int getInstallLocation() { + // allow instant app access return android.provider.Settings.Global.getInt(mContext.getContentResolver(), android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, PackageHelper.APP_INSTALL_AUTO); @@ -23313,11 +23458,13 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); @Override @Deprecated public boolean isPermissionEnforced(String permission) { + // allow instant applications return true; } @Override public boolean isStorageLow() { + // allow instant applications final long token = Binder.clearCallingIdentity(); try { final DeviceStorageMonitorInternal @@ -23334,6 +23481,9 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); @Override public IPackageInstaller getPackageInstaller() { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return null; + } return mInstallerService; } @@ -23397,6 +23547,9 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); @Override public boolean isPackageSignedByKeySet(String packageName, KeySet ks) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return false; + } if (packageName == null || ks == null) { return false; } @@ -23417,6 +23570,9 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); @Override public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return false; + } if (packageName == null || ks == null) { return false; } @@ -24015,8 +24171,12 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); * Logs process start information (including base APK hash) to the security log. * @hide */ + @Override public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo, String apkFile, int pid) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return; + } if (!SecurityLog.isLoggingEnabled()) { return; } @@ -24065,6 +24225,9 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); @Override public boolean canRequestPackageInstalls(String packageName, int userId) { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return false; + } return canRequestPackageInstallsInternal(packageName, 0, userId, true /* throwIfPermNotDeclared*/); } @@ -24115,6 +24278,9 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); @Override public ComponentName getInstantAppInstallerComponent() { + if (getInstantAppPackageName(Binder.getCallingUid()) != null) { + return null; + } return mInstantAppInstallerActivity == null ? null : mInstantAppInstallerActivity.getComponentName(); }