diff options
Diffstat (limited to 'services/core/java/com/android')
3 files changed, 24 insertions, 5 deletions
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java index b205d24fb90..9412213de32 100644 --- a/services/core/java/com/android/server/AppOpsService.java +++ b/services/core/java/com/android/server/AppOpsService.java @@ -76,6 +76,7 @@ import com.android.internal.os.Zygote; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.XmlUtils; +import com.android.server.am.ActivityManagerService; import com.android.server.PermissionDialogReqQueue.PermissionDialogReq; import libcore.util.EmptyArray; @@ -100,6 +101,7 @@ public class AppOpsService extends IAppOpsService.Stub { final boolean mStrictEnable; AppOpsPolicy mPolicy; private PowerManager mPowerManager; + private final ActivityManagerService mActivityManagerService; private static final int[] PRIVACY_GUARD_OP_STATES = new int[] { AppOpsManager.OP_COARSE_LOCATION, @@ -278,11 +280,12 @@ public class AppOpsService extends IAppOpsService.Stub { } } - public AppOpsService(File storagePath, Handler handler) { + public AppOpsService(File storagePath, Handler handler, ActivityManagerService service) { mFile = new AtomicFile(storagePath); mHandler = handler; mLooper = Looper.myLooper(); mStrictEnable = AppOpsManager.isStrictEnable(); + mActivityManagerService = service; readState(); } @@ -1046,6 +1049,7 @@ public class AppOpsService extends IAppOpsService.Stub { private int noteOperationUnchecked(int code, int uid, String packageName, int proxyUid, String proxyPackageName) { final PermissionDialogReq req; + final boolean isInteractive = mPowerManager != null ? mPowerManager.isInteractive() : false; synchronized (this) { Ops ops = getOpsLocked(uid, packageName, true); if (ops == null) { @@ -1097,7 +1101,7 @@ public class AppOpsService extends IAppOpsService.Stub { return AppOpsManager.MODE_ALLOWED; } else { - if (Looper.myLooper() == mLooper) { + if (Looper.myLooper() == mLooper || Thread.holdsLock(mActivityManagerService)) { Log.e(TAG, "noteOperation: This method will deadlock if called from the main thread. (Code: " + code @@ -1130,7 +1134,6 @@ public class AppOpsService extends IAppOpsService.Stub { // we move them to the back of the line. NOTE: these values are magic, and may need // tuning. Ideally we'd want a ringbuffer or token bucket here to do proper rate // limiting. - final boolean isInteractive = mPowerManager.isInteractive(); if (isInteractive && (ops.uidState.pkgOps.size() < AppOpsPolicy.RATE_LIMIT_OPS_TOTAL_PKG_COUNT && op.noteOpCount < AppOpsPolicy.RATE_LIMIT_OP_COUNT @@ -1217,7 +1220,7 @@ public class AppOpsService extends IAppOpsService.Stub { broadcastOpIfNeeded(code); return AppOpsManager.MODE_ALLOWED; } else { - if (Looper.myLooper() == mLooper) { + if (Looper.myLooper() == mLooper || Thread.holdsLock(mActivityManagerService)) { Log.e(TAG, "startOperation: This method will deadlock if called from the main thread. (Code: " + code diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 37156204e30..6c076d06f21 100755 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -2561,7 +2561,7 @@ public final class ActivityManagerService extends ActivityManagerNative mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); - mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); + mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler, this); mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 920a8500bea..21d3b4be1f5 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -415,6 +415,8 @@ public class PackageManagerService extends IPackageManager.Stub { */ private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW; + static final String PLATFORM_PACKAGE_NAME = "android"; + static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer"; static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName( @@ -13467,6 +13469,20 @@ public class PackageManagerService extends IPackageManager.Stub { + perm.info.name + "; ignoring new declaration"); pkg.permissions.remove(i); } + } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) { + // Prevent apps to change protection level to dangerous from any other + // type as this would allow a privilege escalation where an app adds a + // normal/signature permission in other app's group and later redefines + // it as dangerous leading to the group auto-grant. + if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE) + == PermissionInfo.PROTECTION_DANGEROUS) { + if (bp != null && !bp.isRuntime()) { + Slog.w(TAG, "Package " + pkg.packageName + " trying to change a " + + "non-runtime permission " + perm.info.name + + " to runtime; keeping old protection level"); + perm.info.protectionLevel = bp.protectionLevel; + } + } } } } |