summaryrefslogtreecommitdiffstats
path: root/services/core
diff options
context:
space:
mode:
Diffstat (limited to 'services/core')
-rw-r--r--services/core/java/com/android/server/AppOpsService.java11
-rwxr-xr-xservices/core/java/com/android/server/am/ActivityManagerService.java2
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java16
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;
+ }
+ }
}
}
}