summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apex/blobstore/service/java/com/android/server/blob/BlobAccessMode.java10
-rw-r--r--services/core/java/android/content/pm/PackageManagerInternal.java12
-rw-r--r--services/core/java/com/android/server/firewall/IntentFirewall.java12
-rw-r--r--services/core/java/com/android/server/pm/Computer.java2
-rw-r--r--services/core/java/com/android/server/pm/ComputerEngine.java37
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerInternalBase.java5
6 files changed, 62 insertions, 16 deletions
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobAccessMode.java b/apex/blobstore/service/java/com/android/server/blob/BlobAccessMode.java
index 83ef21e7528b..b0c295c331d7 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobAccessMode.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobAccessMode.java
@@ -24,6 +24,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
import android.os.Binder;
import android.os.UserHandle;
import android.util.ArraySet;
@@ -32,6 +33,7 @@ import android.util.DebugUtils;
import android.util.IndentingPrintWriter;
import com.android.internal.util.XmlUtils;
+import com.android.server.LocalServices;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -108,7 +110,7 @@ class BlobAccessMode {
}
if ((mAccessType & ACCESS_TYPE_SAME_SIGNATURE) != 0) {
- if (checkSignatures(context, callingUid, committerUid)) {
+ if (checkSignatures(callingUid, committerUid)) {
return true;
}
}
@@ -133,11 +135,11 @@ class BlobAccessMode {
/**
* Compare signatures for two packages of different users.
*/
- private boolean checkSignatures(Context context, int uid1, int uid2) {
+ private boolean checkSignatures(int uid1, int uid2) {
final long token = Binder.clearCallingIdentity();
try {
- return context.getPackageManager().checkSignatures(uid1, uid2)
- == PackageManager.SIGNATURE_MATCH;
+ return LocalServices.getService(PackageManagerInternal.class)
+ .checkUidSignaturesForAllUsers(uid1, uid2) == PackageManager.SIGNATURE_MATCH;
} finally {
Binder.restoreCallingIdentity(token);
}
diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java
index c45a87174924..9b2c10f6130c 100644
--- a/services/core/java/android/content/pm/PackageManagerInternal.java
+++ b/services/core/java/android/content/pm/PackageManagerInternal.java
@@ -28,6 +28,7 @@ import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.IntentSender;
+import android.content.pm.PackageManager.SignatureResult;
import android.content.pm.SigningDetails.CertCapabilities;
import android.content.pm.overlay.OverlayPaths;
import android.os.Bundle;
@@ -1279,4 +1280,15 @@ public abstract class PackageManagerInternal {
public abstract void shutdown();
public abstract DynamicCodeLogger getDynamicCodeLogger();
+
+ /**
+ * Compare the signatures of two packages that are installed in different users.
+ *
+ * @param uid1 First UID whose signature will be compared.
+ * @param uid2 Second UID whose signature will be compared.
+ * @return {@link PackageManager#SIGNATURE_MATCH} if signatures are matched.
+ * @throws SecurityException if the caller does not hold the
+ * {@link android.Manifest.permission#INTERACT_ACROSS_USERS}.
+ */
+ public abstract @SignatureResult int checkUidSignaturesForAllUsers(int uid1, int uid2);
}
diff --git a/services/core/java/com/android/server/firewall/IntentFirewall.java b/services/core/java/com/android/server/firewall/IntentFirewall.java
index bb8a74493a16..c8a3ee6b1be6 100644
--- a/services/core/java/com/android/server/firewall/IntentFirewall.java
+++ b/services/core/java/com/android/server/firewall/IntentFirewall.java
@@ -25,6 +25,7 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
+import android.os.Binder;
import android.os.Environment;
import android.os.FileObserver;
import android.os.Handler;
@@ -623,12 +624,13 @@ public class IntentFirewall {
}
boolean signaturesMatch(int uid1, int uid2) {
+ final long token = Binder.clearCallingIdentity();
try {
- IPackageManager pm = AppGlobals.getPackageManager();
- return pm.checkUidSignatures(uid1, uid2) == PackageManager.SIGNATURE_MATCH;
- } catch (RemoteException ex) {
- Slog.e(TAG, "Remote exception while checking signatures", ex);
- return false;
+ // Compare signatures of two packages for different users.
+ return LocalServices.getService(PackageManagerInternal.class)
+ .checkUidSignaturesForAllUsers(uid1, uid2) == PackageManager.SIGNATURE_MATCH;
+ } finally {
+ Binder.restoreCallingIdentity(token);
}
}
diff --git a/services/core/java/com/android/server/pm/Computer.java b/services/core/java/com/android/server/pm/Computer.java
index bcffd65d3424..2657be3a97d9 100644
--- a/services/core/java/com/android/server/pm/Computer.java
+++ b/services/core/java/com/android/server/pm/Computer.java
@@ -397,6 +397,8 @@ public interface Computer extends PackageDataSnapshot {
int checkUidSignatures(int uid1, int uid2);
+ int checkUidSignaturesForAllUsers(int uid1, int uid2);
+
boolean hasSigningCertificate(@NonNull String packageName, @NonNull byte[] certificate,
@PackageManager.CertificateInputType int type);
diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java
index edbaba5faa2d..6e772b23bf1b 100644
--- a/services/core/java/com/android/server/pm/ComputerEngine.java
+++ b/services/core/java/com/android/server/pm/ComputerEngine.java
@@ -4263,31 +4263,52 @@ public class ComputerEngine implements Computer {
@Override
public int checkUidSignatures(int uid1, int uid2) {
final int callingUid = Binder.getCallingUid();
- final SigningDetails p1SigningDetails = getSigningDetailsAndFilterAccess(uid1, callingUid);
- final SigningDetails p2SigningDetails = getSigningDetailsAndFilterAccess(uid2, callingUid);
+ final int callingUserId = UserHandle.getUserId(callingUid);
+ final SigningDetails p1SigningDetails =
+ getSigningDetailsAndFilterAccess(uid1, callingUid, callingUserId);
+ final SigningDetails p2SigningDetails =
+ getSigningDetailsAndFilterAccess(uid2, callingUid, callingUserId);
if (p1SigningDetails == null || p2SigningDetails == null) {
return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
}
return checkSignaturesInternal(p1SigningDetails, p2SigningDetails);
}
- private SigningDetails getSigningDetailsAndFilterAccess(int uid, int callingUid) {
+ @Override
+ public int checkUidSignaturesForAllUsers(int uid1, int uid2) {
+ final int callingUid = Binder.getCallingUid();
+ final int userId1 = UserHandle.getUserId(uid1);
+ final int userId2 = UserHandle.getUserId(uid2);
+ enforceCrossUserPermission(callingUid, userId1, false /* requireFullPermission */,
+ false /* checkShell */, "checkUidSignaturesForAllUsers");
+ enforceCrossUserPermission(callingUid, userId2, false /* requireFullPermission */,
+ false /* checkShell */, "checkUidSignaturesForAllUsers");
+ final SigningDetails p1SigningDetails =
+ getSigningDetailsAndFilterAccess(uid1, callingUid, userId1);
+ final SigningDetails p2SigningDetails =
+ getSigningDetailsAndFilterAccess(uid2, callingUid, userId2);
+ if (p1SigningDetails == null || p2SigningDetails == null) {
+ return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
+ }
+ return checkSignaturesInternal(p1SigningDetails, p2SigningDetails);
+ }
+
+ private SigningDetails getSigningDetailsAndFilterAccess(int uid, int callingUid, int userId) {
// Map to base uids.
final int appId = UserHandle.getAppId(uid);
- final int callingUserId = UserHandle.getUserId(callingUid);
final Object obj = mSettings.getSettingBase(appId);
if (obj == null) {
return null;
}
if (obj instanceof SharedUserSetting) {
final SharedUserSetting sus = (SharedUserSetting) obj;
- if (shouldFilterApplicationIncludingUninstalled(sus, callingUid, callingUserId)) {
+ if (shouldFilterApplicationIncludingUninstalled(sus, callingUid, userId)) {
return null;
}
return sus.signatures.mSigningDetails;
} else if (obj instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) obj;
- if (shouldFilterApplicationIncludingUninstalled(ps, callingUid, callingUserId)) {
+ if (shouldFilterApplicationIncludingUninstalled(ps, callingUid, userId)) {
return null;
}
return ps.getSigningDetails();
@@ -4356,7 +4377,9 @@ public class ComputerEngine implements Computer {
public boolean hasUidSigningCertificate(int uid, @NonNull byte[] certificate,
@PackageManager.CertificateInputType int type) {
final int callingUid = Binder.getCallingUid();
- final SigningDetails signingDetails = getSigningDetailsAndFilterAccess(uid, callingUid);
+ final int callingUserId = UserHandle.getUserId(callingUid);
+ final SigningDetails signingDetails =
+ getSigningDetailsAndFilterAccess(uid, callingUid, callingUserId);
if (signingDetails == null) {
return false;
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerInternalBase.java b/services/core/java/com/android/server/pm/PackageManagerInternalBase.java
index 4a3b79e41de1..a224b2258d54 100644
--- a/services/core/java/com/android/server/pm/PackageManagerInternalBase.java
+++ b/services/core/java/com/android/server/pm/PackageManagerInternalBase.java
@@ -721,6 +721,11 @@ abstract class PackageManagerInternalBase extends PackageManagerInternal {
return snapshot().isUidPrivileged(uid);
}
+ @Override
+ public int checkUidSignaturesForAllUsers(int uid1, int uid2) {
+ return snapshot().checkUidSignaturesForAllUsers(uid1, uid2);
+ }
+
@NonNull
@Override
@Deprecated