Loading core/java/android/app/AppOpsManagerInternal.java +0 −29 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package android.app; import android.annotation.NonNull; import android.util.SparseIntArray; import com.android.internal.util.function.QuadFunction; Loading Loading @@ -76,20 +75,6 @@ public abstract class AppOpsManagerInternal { */ public abstract void setDeviceAndProfileOwners(SparseIntArray owners); /** * Sets the app-ops mode for a certain app-op and uid. * * <p>Similar as {@link AppOpsManager#setUidMode} but does not require the package manager to be * working. Hence this can be used very early during boot. * * <p>Only for internal callers. Does <u>not</u> verify that package name belongs to uid. * * @param code The op code to set. * @param uid The UID for which to set. * @param mode The new mode to set. */ public abstract void setUidMode(int code, int uid, int mode); /** * Set all {@link #setMode (package) modes} for this uid to the default value. * Loading @@ -97,18 +82,4 @@ public abstract class AppOpsManagerInternal { * @param uid The uid */ public abstract void setAllPkgModesToDefault(int code, int uid); /** * Get the (raw) mode of an app-op. * * <p>Does <u>not</u> verify that package belongs to uid. The caller needs to do that. * * @param code The code of the op * @param uid The uid of the package the op belongs to * @param packageName The package the op belongs to * * @return The mode of the op */ public abstract @AppOpsManager.Mode int checkOperationUnchecked(int code, int uid, @NonNull String packageName); } services/core/java/com/android/server/appop/AppOpsService.java +147 −116 Original line number Diff line number Diff line Loading @@ -1105,8 +1105,8 @@ public class AppOpsService extends IAppOpsService.Stub { return Collections.emptyList(); } synchronized (this) { Ops pkgOps = getOpsRawLocked(uid, resolvedPackageName, false /* edit */, false /* uidMismatchExpected */); Ops pkgOps = getOpsRawLocked(uid, resolvedPackageName, false /* isPrivileged */, false /* edit */); if (pkgOps == null) { return null; } Loading Loading @@ -1203,8 +1203,7 @@ public class AppOpsService extends IAppOpsService.Stub { private void pruneOp(Op op, int uid, String packageName) { if (!op.hasAnyTime()) { Ops ops = getOpsRawLocked(uid, packageName, false /* edit */, false /* uidMismatchExpected */); Ops ops = getOpsRawLocked(uid, packageName, false /* isPrivileged */, false /* edit */); if (ops != null) { ops.remove(op.op); if (ops.size() <= 0) { Loading Loading @@ -1404,11 +1403,6 @@ public class AppOpsService extends IAppOpsService.Stub { } } @Override public void setMode(int code, int uid, String packageName, int mode) { setMode(code, uid, packageName, mode, true, false); } /** * Sets the mode for a certain op and uid. * Loading @@ -1416,19 +1410,25 @@ public class AppOpsService extends IAppOpsService.Stub { * @param uid The UID for which to set * @param packageName The package for which to set * @param mode The new mode to set * @param verifyUid Iff {@code true}, check that the package name belongs to the uid * @param isPrivileged Whether the package is privileged. (Only used if {@code verifyUid == * false}) */ private void setMode(int code, int uid, @NonNull String packageName, int mode, boolean verifyUid, boolean isPrivileged) { @Override public void setMode(int code, int uid, @NonNull String packageName, int mode) { enforceManageAppOpsModes(Binder.getCallingPid(), Binder.getCallingUid(), uid); verifyIncomingOp(code); ArraySet<ModeCallback> repCbs = null; code = AppOpsManager.opToSwitch(code); boolean isPrivileged; try { isPrivileged = verifyAndGetIsPrivileged(uid, packageName); } catch (SecurityException e) { Slog.e(TAG, "Cannot setMode", e); return; } synchronized (this) { UidState uidState = getUidStateLocked(uid, false); Op op = getOpLocked(code, uid, packageName, true, verifyUid, isPrivileged); Op op = getOpLocked(code, uid, packageName, isPrivileged, true); if (op != null) { if (op.mode != mode) { op.mode = mode; Loading Loading @@ -1793,14 +1793,6 @@ public class AppOpsService extends IAppOpsService.Stub { return checkOperationUnchecked(code, uid, resolvedPackageName, raw); } /** * @see #checkOperationUnchecked(int, int, String, boolean, boolean) */ private @Mode int checkOperationUnchecked(int code, int uid, @NonNull String packageName, boolean raw) { return checkOperationUnchecked(code, uid, packageName, raw, true); } /** * Get the mode of an app-op. * Loading @@ -1808,20 +1800,26 @@ public class AppOpsService extends IAppOpsService.Stub { * @param uid The uid of the package the op belongs to * @param packageName The package the op belongs to * @param raw If the raw state of eval-ed state should be checked. * @param verify If the code should check the package belongs to the uid * * @return The mode of the op */ private @Mode int checkOperationUnchecked(int code, int uid, @NonNull String packageName, boolean raw, boolean verify) { boolean raw) { if (isOpRestrictedDueToSuspend(code, packageName, uid)) { return AppOpsManager.MODE_IGNORED; } synchronized (this) { if (verify) { checkPackage(uid, packageName); boolean isPrivileged; try { isPrivileged = verifyAndGetIsPrivileged(uid, packageName); } catch (SecurityException e) { Slog.e(TAG, "checkOperation", e); return AppOpsManager.opToDefaultMode(code); } if (isOpRestrictedLocked(uid, code, packageName)) { synchronized (this) { if (isOpRestrictedLocked(uid, code, packageName, isPrivileged)) { return AppOpsManager.MODE_IGNORED; } code = AppOpsManager.opToSwitch(code); Loading @@ -1831,7 +1829,7 @@ public class AppOpsService extends IAppOpsService.Stub { final int rawMode = uidState.opModes.get(code); return raw ? rawMode : uidState.evalMode(code, rawMode); } Op op = getOpLocked(code, uid, packageName, false, verify, false); Op op = getOpLocked(code, uid, packageName, false, false); if (op == null) { return AppOpsManager.opToDefaultMode(code); } Loading Loading @@ -1936,16 +1934,14 @@ public class AppOpsService extends IAppOpsService.Stub { @Override public int checkPackage(int uid, String packageName) { Preconditions.checkNotNull(packageName); synchronized (this) { Ops ops = getOpsRawLocked(uid, packageName, true /* edit */, true /* uidMismatchExpected */); if (ops != null) { try { verifyAndGetIsPrivileged(uid, packageName); return AppOpsManager.MODE_ALLOWED; } else { } catch (SecurityException ignored) { return AppOpsManager.MODE_ERRORED; } } } @Override public int noteProxyOperation(int code, int proxyUid, Loading Loading @@ -2006,9 +2002,16 @@ public class AppOpsService extends IAppOpsService.Stub { private int noteOperationUnchecked(int code, int uid, String packageName, int proxyUid, String proxyPackageName, @OpFlags int flags) { boolean isPrivileged; try { isPrivileged = verifyAndGetIsPrivileged(uid, packageName); } catch (SecurityException e) { Slog.e(TAG, "noteOperation", e); return AppOpsManager.MODE_ERRORED; } synchronized (this) { final Ops ops = getOpsRawLocked(uid, packageName, true /* edit */, false /* uidMismatchExpected */); final Ops ops = getOpsRawLocked(uid, packageName, isPrivileged, true /* edit */); if (ops == null) { scheduleOpNotedIfNeededLocked(code, uid, packageName, AppOpsManager.MODE_IGNORED); Loading @@ -2017,7 +2020,7 @@ public class AppOpsService extends IAppOpsService.Stub { return AppOpsManager.MODE_ERRORED; } final Op op = getOpLocked(ops, code, true); if (isOpRestrictedLocked(uid, code, packageName)) { if (isOpRestrictedLocked(uid, code, packageName, isPrivileged)) { scheduleOpNotedIfNeededLocked(code, uid, packageName, AppOpsManager.MODE_IGNORED); return AppOpsManager.MODE_IGNORED; Loading Loading @@ -2176,16 +2179,25 @@ public class AppOpsService extends IAppOpsService.Stub { return AppOpsManager.MODE_IGNORED; } ClientState client = (ClientState)token; boolean isPrivileged; try { isPrivileged = verifyAndGetIsPrivileged(uid, packageName); } catch (SecurityException e) { Slog.e(TAG, "startOperation", e); return AppOpsManager.MODE_ERRORED; } synchronized (this) { final Ops ops = getOpsRawLocked(uid, resolvedPackageName, true /* edit */, false /* uidMismatchExpected */); final Ops ops = getOpsRawLocked(uid, resolvedPackageName, isPrivileged, true /* edit */); if (ops == null) { if (DEBUG) Slog.d(TAG, "startOperation: no op for code " + code + " uid " + uid + " package " + resolvedPackageName); return AppOpsManager.MODE_ERRORED; } final Op op = getOpLocked(ops, code, true); if (isOpRestrictedLocked(uid, code, resolvedPackageName)) { if (isOpRestrictedLocked(uid, code, resolvedPackageName, isPrivileged)) { return AppOpsManager.MODE_IGNORED; } final int switchCode = AppOpsManager.opToSwitch(code); Loading Loading @@ -2257,8 +2269,17 @@ public class AppOpsService extends IAppOpsService.Stub { return; } ClientState client = (ClientState) token; boolean isPrivileged; try { isPrivileged = verifyAndGetIsPrivileged(uid, packageName); } catch (SecurityException e) { Slog.e(TAG, "Cannot finishOperation", e); return; } synchronized (this) { Op op = getOpLocked(code, uid, resolvedPackageName, true, true, false); Op op = getOpLocked(code, uid, resolvedPackageName, isPrivileged, true); if (op == null) { return; } Loading Loading @@ -2508,38 +2529,44 @@ public class AppOpsService extends IAppOpsService.Stub { uidState.pendingStateCommitTime = 0; } private Ops getOpsRawLocked(int uid, String packageName, boolean edit, boolean uidMismatchExpected) { UidState uidState = getUidStateLocked(uid, edit); if (uidState == null) { return null; /** * Verify that package belongs to uid and return whether the package is privileged. * * @param uid The uid the package belongs to * @param packageName The package the might belong to the uid * * @return {@code true} iff the package is privileged */ private boolean verifyAndGetIsPrivileged(int uid, String packageName) { if (uid == Process.ROOT_UID) { // For backwards compatibility, don't check package name for root UID. return false; } if (uidState.pkgOps == null) { if (!edit) { return null; // Do not check if uid/packageName is already known synchronized (this) { UidState uidState = mUidStates.get(uid); if (uidState != null && uidState.pkgOps != null) { Ops ops = uidState.pkgOps.get(packageName); if (ops != null) { return ops.isPrivileged; } uidState.pkgOps = new ArrayMap<>(); } Ops ops = uidState.pkgOps.get(packageName); if (ops == null) { if (!edit) { return null; } boolean isPrivileged = false; // This is the first time we have seen this package name under this uid, // so let's make sure it is valid. if (uid != 0) { final long ident = Binder.clearCallingIdentity(); try { int pkgUid = -1; try { ApplicationInfo appInfo = ActivityThread.getPackageManager() .getApplicationInfo(packageName, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, UserHandle.getUserId(uid)); int pkgUid; ApplicationInfo appInfo = LocalServices.getService(PackageManagerInternal.class) .getApplicationInfo(packageName, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS | PackageManager.MATCH_UNINSTALLED_PACKAGES | PackageManager.MATCH_INSTANT, Process.SYSTEM_UID, UserHandle.getUserId(uid)); if (appInfo != null) { pkgUid = appInfo.uid; isPrivileged = (appInfo.privateFlags Loading @@ -2550,23 +2577,44 @@ public class AppOpsService extends IAppOpsService.Stub { isPrivileged = false; } } } catch (RemoteException e) { Slog.w(TAG, "Could not contact PackageManager", e); } if (pkgUid != uid) { // Oops! The package name is not valid for the uid they are calling // under. Abort. if (!uidMismatchExpected) { RuntimeException ex = new RuntimeException("here"); ex.fillInStackTrace(); Slog.w(TAG, "Bad call: specified package " + packageName + " under uid " + uid + " but it is really " + pkgUid, ex); } return null; throw new SecurityException("Specified package " + packageName + " under uid " + uid + " but it is really " + pkgUid); } } finally { Binder.restoreCallingIdentity(ident); } return isPrivileged; } /** * Get (and potentially create) ops. * * @param uid The uid the package belongs to * @param packageName The name of the package * @param isPrivileged If the package is privilidged (ignored if {@code edit} is false) * @param edit If an ops does not exist, create the ops? * @return */ private Ops getOpsRawLocked(int uid, String packageName, boolean isPrivileged, boolean edit) { UidState uidState = getUidStateLocked(uid, edit); if (uidState == null) { return null; } if (uidState.pkgOps == null) { if (!edit) { return null; } uidState.pkgOps = new ArrayMap<>(); } Ops ops = uidState.pkgOps.get(packageName); if (ops == null) { if (!edit) { return null; } ops = new Ops(packageName, uidState, isPrivileged); uidState.pkgOps.put(packageName, ops); Loading @@ -2575,7 +2623,7 @@ public class AppOpsService extends IAppOpsService.Stub { } /** * Get the state of all ops for a package, <b>don't verify that package belongs to uid</b>. * Get the state of all ops for a package. * * <p>Usually callers should use {@link #getOpLocked} and not call this directly. * Loading Loading @@ -2633,23 +2681,15 @@ public class AppOpsService extends IAppOpsService.Stub { * @param code The code of the op * @param uid The uid the of the package * @param packageName The package name for which to get the state for * @param isPrivileged Whether the package is privileged or not (only used if {@code edit * == true}) * @param edit Iff {@code true} create the {@link Op} object if not yet created * @param verifyUid Iff {@code true} check that the package belongs to the uid * @param isPrivileged Whether the package is privileged or not (only used if {@code verifyUid * == false}) * * @return The {@link Op state} of the op */ private @Nullable Op getOpLocked(int code, int uid, @NonNull String packageName, boolean edit, boolean verifyUid, boolean isPrivileged) { Ops ops; if (verifyUid) { ops = getOpsRawLocked(uid, packageName, edit, false /* uidMismatchExpected */); } else { ops = getOpsRawNoVerifyLocked(uid, packageName, edit, isPrivileged); } private @Nullable Op getOpLocked(int code, int uid, @NonNull String packageName, boolean isPrivileged, boolean edit) { Ops ops = getOpsRawNoVerifyLocked(uid, packageName, edit, isPrivileged); if (ops == null) { return null; } Loading Loading @@ -2679,7 +2719,8 @@ public class AppOpsService extends IAppOpsService.Stub { return pmi.isPackageSuspended(packageName, UserHandle.getUserId(uid)); } private boolean isOpRestrictedLocked(int uid, int code, String packageName) { private boolean isOpRestrictedLocked(int uid, int code, String packageName, boolean isPrivileged) { int userHandle = UserHandle.getUserId(uid); final int restrictionSetCount = mOpUserRestrictions.size(); Loading @@ -2691,8 +2732,8 @@ public class AppOpsService extends IAppOpsService.Stub { if (AppOpsManager.opAllowSystemBypassRestriction(code)) { // If we are the system, bypass user restrictions for certain codes synchronized (this) { Ops ops = getOpsRawLocked(uid, packageName, true /* edit */, false /* uidMismatchExpected */); Ops ops = getOpsRawLocked(uid, packageName, isPrivileged, true /* edit */); if ((ops != null) && ops.isPrivileged) { return false; } Loading Loading @@ -3063,7 +3104,7 @@ public class AppOpsService extends IAppOpsService.Stub { out.attribute(null, "n", Integer.toString(pkg.getUid())); synchronized (this) { Ops ops = getOpsRawLocked(pkg.getUid(), pkg.getPackageName(), false /* edit */, false /* uidMismatchExpected */); false /* isPrivileged */, false /* edit */); // Should always be present as the list of PackageOps is generated // from Ops. if (ops != null) { Loading Loading @@ -4641,19 +4682,9 @@ public class AppOpsService extends IAppOpsService.Stub { } } @Override public void setUidMode(int code, int uid, int mode) { AppOpsService.this.setUidMode(code, uid, mode); } @Override public void setAllPkgModesToDefault(int code, int uid) { AppOpsService.this.setAllPkgModesToDefault(code, uid); } @Override public @Mode int checkOperationUnchecked(int code, int uid, @NonNull String packageName) { return AppOpsService.this.checkOperationUnchecked(code, uid, packageName, true, false); } } } services/tests/servicestests/src/com/android/server/pm/ModuleInfoProviderTest.java +5 −4 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.pm; import android.content.Context; import android.content.pm.ModuleInfo; import android.content.pm.PackageManager; import android.test.InstrumentationTestCase; import com.android.frameworks.servicestests.R; Loading @@ -28,7 +29,7 @@ public class ModuleInfoProviderTest extends InstrumentationTestCase { public void testSuccessfulParse() { ModuleInfoProvider provider = getProvider(R.xml.well_formed_metadata); List<ModuleInfo> mi = provider.getInstalledModules(0); List<ModuleInfo> mi = provider.getInstalledModules(PackageManager.MATCH_ALL); assertEquals(2, mi.size()); Collections.sort(mi, (ModuleInfo m1, ModuleInfo m2) -> Loading @@ -49,18 +50,18 @@ public class ModuleInfoProviderTest extends InstrumentationTestCase { public void testParseFailure_incorrectTopLevelElement() { ModuleInfoProvider provider = getProvider(R.xml.unparseable_metadata1); assertEquals(0, provider.getInstalledModules(0).size()); assertEquals(0, provider.getInstalledModules(PackageManager.MATCH_ALL).size()); } public void testParseFailure_incorrectModuleElement() { ModuleInfoProvider provider = getProvider(R.xml.unparseable_metadata2); assertEquals(0, provider.getInstalledModules(0).size()); assertEquals(0, provider.getInstalledModules(PackageManager.MATCH_ALL).size()); } public void testParse_unknownAttributesIgnored() { ModuleInfoProvider provider = getProvider(R.xml.well_formed_metadata); List<ModuleInfo> mi = provider.getInstalledModules(0); List<ModuleInfo> mi = provider.getInstalledModules(PackageManager.MATCH_ALL); assertEquals(2, mi.size()); ModuleInfo mi1 = provider.getModuleInfo("com.android.module1", 0); Loading Loading
core/java/android/app/AppOpsManagerInternal.java +0 −29 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package android.app; import android.annotation.NonNull; import android.util.SparseIntArray; import com.android.internal.util.function.QuadFunction; Loading Loading @@ -76,20 +75,6 @@ public abstract class AppOpsManagerInternal { */ public abstract void setDeviceAndProfileOwners(SparseIntArray owners); /** * Sets the app-ops mode for a certain app-op and uid. * * <p>Similar as {@link AppOpsManager#setUidMode} but does not require the package manager to be * working. Hence this can be used very early during boot. * * <p>Only for internal callers. Does <u>not</u> verify that package name belongs to uid. * * @param code The op code to set. * @param uid The UID for which to set. * @param mode The new mode to set. */ public abstract void setUidMode(int code, int uid, int mode); /** * Set all {@link #setMode (package) modes} for this uid to the default value. * Loading @@ -97,18 +82,4 @@ public abstract class AppOpsManagerInternal { * @param uid The uid */ public abstract void setAllPkgModesToDefault(int code, int uid); /** * Get the (raw) mode of an app-op. * * <p>Does <u>not</u> verify that package belongs to uid. The caller needs to do that. * * @param code The code of the op * @param uid The uid of the package the op belongs to * @param packageName The package the op belongs to * * @return The mode of the op */ public abstract @AppOpsManager.Mode int checkOperationUnchecked(int code, int uid, @NonNull String packageName); }
services/core/java/com/android/server/appop/AppOpsService.java +147 −116 Original line number Diff line number Diff line Loading @@ -1105,8 +1105,8 @@ public class AppOpsService extends IAppOpsService.Stub { return Collections.emptyList(); } synchronized (this) { Ops pkgOps = getOpsRawLocked(uid, resolvedPackageName, false /* edit */, false /* uidMismatchExpected */); Ops pkgOps = getOpsRawLocked(uid, resolvedPackageName, false /* isPrivileged */, false /* edit */); if (pkgOps == null) { return null; } Loading Loading @@ -1203,8 +1203,7 @@ public class AppOpsService extends IAppOpsService.Stub { private void pruneOp(Op op, int uid, String packageName) { if (!op.hasAnyTime()) { Ops ops = getOpsRawLocked(uid, packageName, false /* edit */, false /* uidMismatchExpected */); Ops ops = getOpsRawLocked(uid, packageName, false /* isPrivileged */, false /* edit */); if (ops != null) { ops.remove(op.op); if (ops.size() <= 0) { Loading Loading @@ -1404,11 +1403,6 @@ public class AppOpsService extends IAppOpsService.Stub { } } @Override public void setMode(int code, int uid, String packageName, int mode) { setMode(code, uid, packageName, mode, true, false); } /** * Sets the mode for a certain op and uid. * Loading @@ -1416,19 +1410,25 @@ public class AppOpsService extends IAppOpsService.Stub { * @param uid The UID for which to set * @param packageName The package for which to set * @param mode The new mode to set * @param verifyUid Iff {@code true}, check that the package name belongs to the uid * @param isPrivileged Whether the package is privileged. (Only used if {@code verifyUid == * false}) */ private void setMode(int code, int uid, @NonNull String packageName, int mode, boolean verifyUid, boolean isPrivileged) { @Override public void setMode(int code, int uid, @NonNull String packageName, int mode) { enforceManageAppOpsModes(Binder.getCallingPid(), Binder.getCallingUid(), uid); verifyIncomingOp(code); ArraySet<ModeCallback> repCbs = null; code = AppOpsManager.opToSwitch(code); boolean isPrivileged; try { isPrivileged = verifyAndGetIsPrivileged(uid, packageName); } catch (SecurityException e) { Slog.e(TAG, "Cannot setMode", e); return; } synchronized (this) { UidState uidState = getUidStateLocked(uid, false); Op op = getOpLocked(code, uid, packageName, true, verifyUid, isPrivileged); Op op = getOpLocked(code, uid, packageName, isPrivileged, true); if (op != null) { if (op.mode != mode) { op.mode = mode; Loading Loading @@ -1793,14 +1793,6 @@ public class AppOpsService extends IAppOpsService.Stub { return checkOperationUnchecked(code, uid, resolvedPackageName, raw); } /** * @see #checkOperationUnchecked(int, int, String, boolean, boolean) */ private @Mode int checkOperationUnchecked(int code, int uid, @NonNull String packageName, boolean raw) { return checkOperationUnchecked(code, uid, packageName, raw, true); } /** * Get the mode of an app-op. * Loading @@ -1808,20 +1800,26 @@ public class AppOpsService extends IAppOpsService.Stub { * @param uid The uid of the package the op belongs to * @param packageName The package the op belongs to * @param raw If the raw state of eval-ed state should be checked. * @param verify If the code should check the package belongs to the uid * * @return The mode of the op */ private @Mode int checkOperationUnchecked(int code, int uid, @NonNull String packageName, boolean raw, boolean verify) { boolean raw) { if (isOpRestrictedDueToSuspend(code, packageName, uid)) { return AppOpsManager.MODE_IGNORED; } synchronized (this) { if (verify) { checkPackage(uid, packageName); boolean isPrivileged; try { isPrivileged = verifyAndGetIsPrivileged(uid, packageName); } catch (SecurityException e) { Slog.e(TAG, "checkOperation", e); return AppOpsManager.opToDefaultMode(code); } if (isOpRestrictedLocked(uid, code, packageName)) { synchronized (this) { if (isOpRestrictedLocked(uid, code, packageName, isPrivileged)) { return AppOpsManager.MODE_IGNORED; } code = AppOpsManager.opToSwitch(code); Loading @@ -1831,7 +1829,7 @@ public class AppOpsService extends IAppOpsService.Stub { final int rawMode = uidState.opModes.get(code); return raw ? rawMode : uidState.evalMode(code, rawMode); } Op op = getOpLocked(code, uid, packageName, false, verify, false); Op op = getOpLocked(code, uid, packageName, false, false); if (op == null) { return AppOpsManager.opToDefaultMode(code); } Loading Loading @@ -1936,16 +1934,14 @@ public class AppOpsService extends IAppOpsService.Stub { @Override public int checkPackage(int uid, String packageName) { Preconditions.checkNotNull(packageName); synchronized (this) { Ops ops = getOpsRawLocked(uid, packageName, true /* edit */, true /* uidMismatchExpected */); if (ops != null) { try { verifyAndGetIsPrivileged(uid, packageName); return AppOpsManager.MODE_ALLOWED; } else { } catch (SecurityException ignored) { return AppOpsManager.MODE_ERRORED; } } } @Override public int noteProxyOperation(int code, int proxyUid, Loading Loading @@ -2006,9 +2002,16 @@ public class AppOpsService extends IAppOpsService.Stub { private int noteOperationUnchecked(int code, int uid, String packageName, int proxyUid, String proxyPackageName, @OpFlags int flags) { boolean isPrivileged; try { isPrivileged = verifyAndGetIsPrivileged(uid, packageName); } catch (SecurityException e) { Slog.e(TAG, "noteOperation", e); return AppOpsManager.MODE_ERRORED; } synchronized (this) { final Ops ops = getOpsRawLocked(uid, packageName, true /* edit */, false /* uidMismatchExpected */); final Ops ops = getOpsRawLocked(uid, packageName, isPrivileged, true /* edit */); if (ops == null) { scheduleOpNotedIfNeededLocked(code, uid, packageName, AppOpsManager.MODE_IGNORED); Loading @@ -2017,7 +2020,7 @@ public class AppOpsService extends IAppOpsService.Stub { return AppOpsManager.MODE_ERRORED; } final Op op = getOpLocked(ops, code, true); if (isOpRestrictedLocked(uid, code, packageName)) { if (isOpRestrictedLocked(uid, code, packageName, isPrivileged)) { scheduleOpNotedIfNeededLocked(code, uid, packageName, AppOpsManager.MODE_IGNORED); return AppOpsManager.MODE_IGNORED; Loading Loading @@ -2176,16 +2179,25 @@ public class AppOpsService extends IAppOpsService.Stub { return AppOpsManager.MODE_IGNORED; } ClientState client = (ClientState)token; boolean isPrivileged; try { isPrivileged = verifyAndGetIsPrivileged(uid, packageName); } catch (SecurityException e) { Slog.e(TAG, "startOperation", e); return AppOpsManager.MODE_ERRORED; } synchronized (this) { final Ops ops = getOpsRawLocked(uid, resolvedPackageName, true /* edit */, false /* uidMismatchExpected */); final Ops ops = getOpsRawLocked(uid, resolvedPackageName, isPrivileged, true /* edit */); if (ops == null) { if (DEBUG) Slog.d(TAG, "startOperation: no op for code " + code + " uid " + uid + " package " + resolvedPackageName); return AppOpsManager.MODE_ERRORED; } final Op op = getOpLocked(ops, code, true); if (isOpRestrictedLocked(uid, code, resolvedPackageName)) { if (isOpRestrictedLocked(uid, code, resolvedPackageName, isPrivileged)) { return AppOpsManager.MODE_IGNORED; } final int switchCode = AppOpsManager.opToSwitch(code); Loading Loading @@ -2257,8 +2269,17 @@ public class AppOpsService extends IAppOpsService.Stub { return; } ClientState client = (ClientState) token; boolean isPrivileged; try { isPrivileged = verifyAndGetIsPrivileged(uid, packageName); } catch (SecurityException e) { Slog.e(TAG, "Cannot finishOperation", e); return; } synchronized (this) { Op op = getOpLocked(code, uid, resolvedPackageName, true, true, false); Op op = getOpLocked(code, uid, resolvedPackageName, isPrivileged, true); if (op == null) { return; } Loading Loading @@ -2508,38 +2529,44 @@ public class AppOpsService extends IAppOpsService.Stub { uidState.pendingStateCommitTime = 0; } private Ops getOpsRawLocked(int uid, String packageName, boolean edit, boolean uidMismatchExpected) { UidState uidState = getUidStateLocked(uid, edit); if (uidState == null) { return null; /** * Verify that package belongs to uid and return whether the package is privileged. * * @param uid The uid the package belongs to * @param packageName The package the might belong to the uid * * @return {@code true} iff the package is privileged */ private boolean verifyAndGetIsPrivileged(int uid, String packageName) { if (uid == Process.ROOT_UID) { // For backwards compatibility, don't check package name for root UID. return false; } if (uidState.pkgOps == null) { if (!edit) { return null; // Do not check if uid/packageName is already known synchronized (this) { UidState uidState = mUidStates.get(uid); if (uidState != null && uidState.pkgOps != null) { Ops ops = uidState.pkgOps.get(packageName); if (ops != null) { return ops.isPrivileged; } uidState.pkgOps = new ArrayMap<>(); } Ops ops = uidState.pkgOps.get(packageName); if (ops == null) { if (!edit) { return null; } boolean isPrivileged = false; // This is the first time we have seen this package name under this uid, // so let's make sure it is valid. if (uid != 0) { final long ident = Binder.clearCallingIdentity(); try { int pkgUid = -1; try { ApplicationInfo appInfo = ActivityThread.getPackageManager() .getApplicationInfo(packageName, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, UserHandle.getUserId(uid)); int pkgUid; ApplicationInfo appInfo = LocalServices.getService(PackageManagerInternal.class) .getApplicationInfo(packageName, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS | PackageManager.MATCH_UNINSTALLED_PACKAGES | PackageManager.MATCH_INSTANT, Process.SYSTEM_UID, UserHandle.getUserId(uid)); if (appInfo != null) { pkgUid = appInfo.uid; isPrivileged = (appInfo.privateFlags Loading @@ -2550,23 +2577,44 @@ public class AppOpsService extends IAppOpsService.Stub { isPrivileged = false; } } } catch (RemoteException e) { Slog.w(TAG, "Could not contact PackageManager", e); } if (pkgUid != uid) { // Oops! The package name is not valid for the uid they are calling // under. Abort. if (!uidMismatchExpected) { RuntimeException ex = new RuntimeException("here"); ex.fillInStackTrace(); Slog.w(TAG, "Bad call: specified package " + packageName + " under uid " + uid + " but it is really " + pkgUid, ex); } return null; throw new SecurityException("Specified package " + packageName + " under uid " + uid + " but it is really " + pkgUid); } } finally { Binder.restoreCallingIdentity(ident); } return isPrivileged; } /** * Get (and potentially create) ops. * * @param uid The uid the package belongs to * @param packageName The name of the package * @param isPrivileged If the package is privilidged (ignored if {@code edit} is false) * @param edit If an ops does not exist, create the ops? * @return */ private Ops getOpsRawLocked(int uid, String packageName, boolean isPrivileged, boolean edit) { UidState uidState = getUidStateLocked(uid, edit); if (uidState == null) { return null; } if (uidState.pkgOps == null) { if (!edit) { return null; } uidState.pkgOps = new ArrayMap<>(); } Ops ops = uidState.pkgOps.get(packageName); if (ops == null) { if (!edit) { return null; } ops = new Ops(packageName, uidState, isPrivileged); uidState.pkgOps.put(packageName, ops); Loading @@ -2575,7 +2623,7 @@ public class AppOpsService extends IAppOpsService.Stub { } /** * Get the state of all ops for a package, <b>don't verify that package belongs to uid</b>. * Get the state of all ops for a package. * * <p>Usually callers should use {@link #getOpLocked} and not call this directly. * Loading Loading @@ -2633,23 +2681,15 @@ public class AppOpsService extends IAppOpsService.Stub { * @param code The code of the op * @param uid The uid the of the package * @param packageName The package name for which to get the state for * @param isPrivileged Whether the package is privileged or not (only used if {@code edit * == true}) * @param edit Iff {@code true} create the {@link Op} object if not yet created * @param verifyUid Iff {@code true} check that the package belongs to the uid * @param isPrivileged Whether the package is privileged or not (only used if {@code verifyUid * == false}) * * @return The {@link Op state} of the op */ private @Nullable Op getOpLocked(int code, int uid, @NonNull String packageName, boolean edit, boolean verifyUid, boolean isPrivileged) { Ops ops; if (verifyUid) { ops = getOpsRawLocked(uid, packageName, edit, false /* uidMismatchExpected */); } else { ops = getOpsRawNoVerifyLocked(uid, packageName, edit, isPrivileged); } private @Nullable Op getOpLocked(int code, int uid, @NonNull String packageName, boolean isPrivileged, boolean edit) { Ops ops = getOpsRawNoVerifyLocked(uid, packageName, edit, isPrivileged); if (ops == null) { return null; } Loading Loading @@ -2679,7 +2719,8 @@ public class AppOpsService extends IAppOpsService.Stub { return pmi.isPackageSuspended(packageName, UserHandle.getUserId(uid)); } private boolean isOpRestrictedLocked(int uid, int code, String packageName) { private boolean isOpRestrictedLocked(int uid, int code, String packageName, boolean isPrivileged) { int userHandle = UserHandle.getUserId(uid); final int restrictionSetCount = mOpUserRestrictions.size(); Loading @@ -2691,8 +2732,8 @@ public class AppOpsService extends IAppOpsService.Stub { if (AppOpsManager.opAllowSystemBypassRestriction(code)) { // If we are the system, bypass user restrictions for certain codes synchronized (this) { Ops ops = getOpsRawLocked(uid, packageName, true /* edit */, false /* uidMismatchExpected */); Ops ops = getOpsRawLocked(uid, packageName, isPrivileged, true /* edit */); if ((ops != null) && ops.isPrivileged) { return false; } Loading Loading @@ -3063,7 +3104,7 @@ public class AppOpsService extends IAppOpsService.Stub { out.attribute(null, "n", Integer.toString(pkg.getUid())); synchronized (this) { Ops ops = getOpsRawLocked(pkg.getUid(), pkg.getPackageName(), false /* edit */, false /* uidMismatchExpected */); false /* isPrivileged */, false /* edit */); // Should always be present as the list of PackageOps is generated // from Ops. if (ops != null) { Loading Loading @@ -4641,19 +4682,9 @@ public class AppOpsService extends IAppOpsService.Stub { } } @Override public void setUidMode(int code, int uid, int mode) { AppOpsService.this.setUidMode(code, uid, mode); } @Override public void setAllPkgModesToDefault(int code, int uid) { AppOpsService.this.setAllPkgModesToDefault(code, uid); } @Override public @Mode int checkOperationUnchecked(int code, int uid, @NonNull String packageName) { return AppOpsService.this.checkOperationUnchecked(code, uid, packageName, true, false); } } }
services/tests/servicestests/src/com/android/server/pm/ModuleInfoProviderTest.java +5 −4 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.pm; import android.content.Context; import android.content.pm.ModuleInfo; import android.content.pm.PackageManager; import android.test.InstrumentationTestCase; import com.android.frameworks.servicestests.R; Loading @@ -28,7 +29,7 @@ public class ModuleInfoProviderTest extends InstrumentationTestCase { public void testSuccessfulParse() { ModuleInfoProvider provider = getProvider(R.xml.well_formed_metadata); List<ModuleInfo> mi = provider.getInstalledModules(0); List<ModuleInfo> mi = provider.getInstalledModules(PackageManager.MATCH_ALL); assertEquals(2, mi.size()); Collections.sort(mi, (ModuleInfo m1, ModuleInfo m2) -> Loading @@ -49,18 +50,18 @@ public class ModuleInfoProviderTest extends InstrumentationTestCase { public void testParseFailure_incorrectTopLevelElement() { ModuleInfoProvider provider = getProvider(R.xml.unparseable_metadata1); assertEquals(0, provider.getInstalledModules(0).size()); assertEquals(0, provider.getInstalledModules(PackageManager.MATCH_ALL).size()); } public void testParseFailure_incorrectModuleElement() { ModuleInfoProvider provider = getProvider(R.xml.unparseable_metadata2); assertEquals(0, provider.getInstalledModules(0).size()); assertEquals(0, provider.getInstalledModules(PackageManager.MATCH_ALL).size()); } public void testParse_unknownAttributesIgnored() { ModuleInfoProvider provider = getProvider(R.xml.well_formed_metadata); List<ModuleInfo> mi = provider.getInstalledModules(0); List<ModuleInfo> mi = provider.getInstalledModules(PackageManager.MATCH_ALL); assertEquals(2, mi.size()); ModuleInfo mi1 = provider.getModuleInfo("com.android.module1", 0); Loading