summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Nate Myren <ntmyren@google.com> 2021-05-07 11:16:08 -0700
committer Nate Myren <ntmyren@google.com> 2021-05-11 15:29:18 -0700
commit10b5c81409d5e952b527ea792389b603bc20d492 (patch)
tree94357a737212c962c280e01d0c3fefbabdfd8a5a
parent3d46ae52dccb4c519fb3ab733d6b82b5c83b67de (diff)
Ensure that proxy operations look for attribution tag in proxy's pkg
When calling note/startProxyOp, we should look for both attribution tags, proxy and proxied, in the proxy app. Log an error, instead of throwing, when we find the proxied attribution tag in the proxy app Bug: 187313675 Test: manual Change-Id: I8a5db05b9728c0bb92f334fbac9baa7ef62fe619
-rw-r--r--services/core/java/com/android/server/appop/AppOpsService.java70
1 files changed, 50 insertions, 20 deletions
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 99b0d81285f0..a3669e2adb9e 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -3161,7 +3161,7 @@ public class AppOpsService extends IAppOpsService.Stub {
boolean shouldCollectMessage) {
RestrictionBypass bypass;
try {
- bypass = verifyAndGetBypass(uid, packageName, attributionTag);
+ bypass = verifyAndGetBypass(uid, packageName, attributionTag, proxyPackageName);
} catch (SecurityException e) {
Slog.e(TAG, "noteOperation", e);
return new SyncNotedAppOp(AppOpsManager.MODE_ERRORED, code, attributionTag,
@@ -3653,7 +3653,7 @@ public class AppOpsService extends IAppOpsService.Stub {
boolean shouldCollectMessage, boolean dryRun) {
RestrictionBypass bypass;
try {
- bypass = verifyAndGetBypass(uid, packageName, attributionTag);
+ bypass = verifyAndGetBypass(uid, packageName, attributionTag, proxyPackageName);
} catch (SecurityException e) {
Slog.e(TAG, "startOperation", e);
return new SyncNotedAppOp(AppOpsManager.MODE_ERRORED, code, attributionTag,
@@ -4187,17 +4187,26 @@ public class AppOpsService extends IAppOpsService.Stub {
}
/**
+ * @see verifyAndGetBypass(int, String, String, String)
+ */
+ private @Nullable RestrictionBypass verifyAndGetBypass(int uid, String packageName,
+ @Nullable String attributionTag) {
+ return verifyAndGetBypass(uid, packageName, attributionTag, null);
+ }
+
+ /**
* Verify that package belongs to uid and return the {@link RestrictionBypass bypass
* description} for the package.
*
* @param uid The uid the package belongs to
* @param packageName The package the might belong to the uid
* @param attributionTag attribution tag or {@code null} if no need to verify
+ * @param proxyPackageName The proxy package, from which the attribution tag is to be pulled
*
* @return {@code true} iff the package is privileged
*/
private @Nullable RestrictionBypass verifyAndGetBypass(int uid, String packageName,
- @Nullable String attributionTag) {
+ @Nullable String attributionTag, @Nullable String proxyPackageName) {
if (uid == Process.ROOT_UID) {
// For backwards compatibility, don't check package name for root UID.
return null;
@@ -4235,34 +4244,36 @@ public class AppOpsService extends IAppOpsService.Stub {
final long ident = Binder.clearCallingIdentity();
try {
boolean isAttributionTagValid = false;
- AndroidPackage pkg = LocalServices.getService(PackageManagerInternal.class)
- .getPackage(packageName);
+ PackageManagerInternal pmInt = LocalServices.getService(PackageManagerInternal.class);
+ AndroidPackage pkg = pmInt.getPackage(packageName);
if (pkg != null) {
- if (attributionTag == null) {
- isAttributionTagValid = true;
- } else {
- if (pkg.getAttributions() != null) {
- int numAttributions = pkg.getAttributions().size();
- for (int i = 0; i < numAttributions; i++) {
- if (pkg.getAttributions().get(i).tag.equals(attributionTag)) {
- isAttributionTagValid = true;
- }
- }
- }
- }
+ isAttributionTagValid = isAttributionInPackage(pkg, attributionTag);
pkgUid = UserHandle.getUid(userId, UserHandle.getAppId(pkg.getUid()));
bypass = getBypassforPackage(pkg);
}
if (!isAttributionTagValid) {
- String msg = "attributionTag " + attributionTag + " not declared in"
- + " manifest of " + packageName;
+ AndroidPackage proxyPkg = proxyPackageName != null
+ ? pmInt.getPackage(proxyPackageName) : null;
+ boolean foundInProxy = isAttributionInPackage(proxyPkg, attributionTag);
+ String msg;
+ if (pkg != null && foundInProxy) {
+ msg = "attributionTag " + attributionTag + " declared in manifest of the proxy"
+ + " package " + proxyPackageName + ", this is not advised";
+ } else if (pkg != null) {
+ msg = "attributionTag " + attributionTag + " not declared in manifest of "
+ + packageName;
+ } else {
+ msg = "package " + packageName + " not found, can't check for "
+ + "attributionTag " + attributionTag;
+ }
+
try {
if (mPlatformCompat.isChangeEnabledByPackageName(
SECURITY_EXCEPTION_ON_INVALID_ATTRIBUTION_TAG_CHANGE, packageName,
userId) && mPlatformCompat.isChangeEnabledByUid(
SECURITY_EXCEPTION_ON_INVALID_ATTRIBUTION_TAG_CHANGE,
- callingUid)) {
+ callingUid) && !foundInProxy) {
throw new SecurityException(msg);
} else {
Slog.e(TAG, msg);
@@ -4282,6 +4293,25 @@ public class AppOpsService extends IAppOpsService.Stub {
return bypass;
}
+ private boolean isAttributionInPackage(@Nullable AndroidPackage pkg,
+ @Nullable String attributionTag) {
+ if (pkg == null) {
+ return false;
+ } else if (attributionTag == null) {
+ return true;
+ }
+ if (pkg.getAttributions() != null) {
+ int numAttributions = pkg.getAttributions().size();
+ for (int i = 0; i < numAttributions; i++) {
+ if (pkg.getAttributions().get(i).tag.equals(attributionTag)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
/**
* Get (and potentially create) ops.
*