Merge "Move enforceCrossUser*Permission() back into PackageManagerService."
This commit is contained in:
@@ -517,7 +517,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
|
||||
String installerAttributionTag, int userId)
|
||||
throws IOException {
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
mPermissionManager.enforceCrossUserPermission(
|
||||
mPm.enforceCrossUserPermission(
|
||||
callingUid, userId, true, true, "createSession");
|
||||
|
||||
if (mPm.isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
|
||||
@@ -912,7 +912,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
|
||||
@Override
|
||||
public ParceledListSlice<SessionInfo> getAllSessions(int userId) {
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
mPermissionManager.enforceCrossUserPermission(
|
||||
mPm.enforceCrossUserPermission(
|
||||
callingUid, userId, true, false, "getAllSessions");
|
||||
|
||||
final List<SessionInfo> result = new ArrayList<>();
|
||||
@@ -930,7 +930,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
|
||||
|
||||
@Override
|
||||
public ParceledListSlice<SessionInfo> getMySessions(String installerPackageName, int userId) {
|
||||
mPermissionManager.enforceCrossUserPermission(
|
||||
mPm.enforceCrossUserPermission(
|
||||
Binder.getCallingUid(), userId, true, false, "getMySessions");
|
||||
mAppOps.checkPackage(Binder.getCallingUid(), installerPackageName);
|
||||
|
||||
@@ -954,7 +954,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
|
||||
public void uninstall(VersionedPackage versionedPackage, String callerPackageName, int flags,
|
||||
IntentSender statusReceiver, int userId) {
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
mPermissionManager.enforceCrossUserPermission(callingUid, userId, true, true, "uninstall");
|
||||
mPm.enforceCrossUserPermission(callingUid, userId, true, true, "uninstall");
|
||||
if ((callingUid != Process.SHELL_UID) && (callingUid != Process.ROOT_UID)) {
|
||||
mAppOps.checkPackage(callingUid, callerPackageName);
|
||||
}
|
||||
@@ -1006,7 +1006,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
|
||||
String callerPackageName, IntentSender statusReceiver, int userId) {
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
mContext.enforceCallingOrSelfPermission(Manifest.permission.DELETE_PACKAGES, null);
|
||||
mPermissionManager.enforceCrossUserPermission(callingUid, userId, true, true, "uninstall");
|
||||
mPm.enforceCrossUserPermission(callingUid, userId, true, true, "uninstall");
|
||||
if ((callingUid != Process.SHELL_UID) && (callingUid != Process.ROOT_UID)) {
|
||||
mAppOps.checkPackage(callingUid, callerPackageName);
|
||||
}
|
||||
@@ -1037,7 +1037,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
|
||||
|
||||
@Override
|
||||
public void registerCallback(IPackageInstallerCallback callback, int userId) {
|
||||
mPermissionManager.enforceCrossUserPermission(
|
||||
mPm.enforceCrossUserPermission(
|
||||
Binder.getCallingUid(), userId, true, false, "registerCallback");
|
||||
registerCallback(callback, eventUserId -> userId == eventUserId);
|
||||
}
|
||||
|
||||
@@ -160,6 +160,7 @@ import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.IntentSender;
|
||||
import android.content.IntentSender.SendIntentException;
|
||||
import android.content.PermissionChecker;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.AuxiliaryResolveInfo;
|
||||
@@ -4631,8 +4632,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
if (!mUserManager.exists(userId)) {
|
||||
throw new SecurityException("User doesn't exist");
|
||||
}
|
||||
mPermissionManager.enforceCrossUserPermission(
|
||||
callingUid, userId, false, false, "checkPackageStartable");
|
||||
enforceCrossUserPermission(callingUid, userId, false, false, "checkPackageStartable");
|
||||
final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
|
||||
synchronized (mLock) {
|
||||
final PackageSetting ps = mSettings.mPackages.get(packageName);
|
||||
@@ -4663,8 +4663,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
public boolean isPackageAvailable(String packageName, int userId) {
|
||||
if (!mUserManager.exists(userId)) return false;
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
|
||||
false /*requireFullPermission*/, false /*checkShell*/, "is package available");
|
||||
enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
|
||||
false /*checkShell*/, "is package available");
|
||||
synchronized (mLock) {
|
||||
AndroidPackage p = mPackages.get(packageName);
|
||||
if (p != null) {
|
||||
@@ -4706,7 +4706,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
int flags, int filterCallingUid, int userId) {
|
||||
if (!mUserManager.exists(userId)) return null;
|
||||
flags = updateFlagsForPackage(flags, userId);
|
||||
mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
|
||||
enforceCrossUserPermission(Binder.getCallingUid(), userId,
|
||||
false /* requireFullPermission */, false /* checkShell */, "get package info");
|
||||
|
||||
// reader
|
||||
@@ -5008,8 +5008,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
if (!mUserManager.exists(userId)) return -1;
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
flags = updateFlagsForPackage(flags, userId);
|
||||
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
|
||||
false /*requireFullPermission*/, false /*checkShell*/, "getPackageUid");
|
||||
enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
|
||||
false /*checkShell*/, "getPackageUid");
|
||||
return getPackageUidInternal(packageName, flags, userId, callingUid);
|
||||
}
|
||||
|
||||
@@ -5041,8 +5041,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
if (!mUserManager.exists(userId)) return null;
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
flags = updateFlagsForPackage(flags, userId);
|
||||
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
|
||||
false /*requireFullPermission*/, false /*checkShell*/, "getPackageGids");
|
||||
enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
|
||||
false /*checkShell*/, "getPackageGids");
|
||||
|
||||
// reader
|
||||
synchronized (mLock) {
|
||||
@@ -5125,7 +5125,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
flags = updateFlagsForApplication(flags, userId);
|
||||
|
||||
if (!isRecentsAccessingChildProfiles(Binder.getCallingUid(), userId)) {
|
||||
mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
|
||||
enforceCrossUserPermission(Binder.getCallingUid(), userId,
|
||||
false /* requireFullPermission */, false /* checkShell */,
|
||||
"get application info");
|
||||
}
|
||||
@@ -5429,8 +5429,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
|
||||
// require the permission to be held; the calling uid and given user id referring
|
||||
// to the same user is not sufficient
|
||||
mPermissionManager.enforceCrossUserPermission(
|
||||
Binder.getCallingUid(), userId, false, false,
|
||||
enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false,
|
||||
!isRecentsAccessingChildProfiles(Binder.getCallingUid(), userId),
|
||||
"MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at "
|
||||
+ Debug.getCallers(5));
|
||||
@@ -5552,7 +5551,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
flags = updateFlagsForComponent(flags, userId);
|
||||
|
||||
if (!isRecentsAccessingChildProfiles(Binder.getCallingUid(), userId)) {
|
||||
mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
|
||||
enforceCrossUserPermission(Binder.getCallingUid(), userId,
|
||||
false /* requireFullPermission */, false /* checkShell */, "get activity info");
|
||||
}
|
||||
|
||||
@@ -5634,8 +5633,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
if (!mUserManager.exists(userId)) return null;
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
flags = updateFlagsForComponent(flags, userId);
|
||||
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
|
||||
false /* requireFullPermission */, false /* checkShell */, "get receiver info");
|
||||
enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
|
||||
false /* checkShell */, "get receiver info");
|
||||
synchronized (mLock) {
|
||||
ParsedActivity a = mComponentResolver.getReceiver(component);
|
||||
if (DEBUG_PACKAGE_INFO) Log.v(
|
||||
@@ -5743,9 +5742,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_SHARED_LIBRARIES,
|
||||
"getDeclaredSharedLibraries");
|
||||
int callingUid = Binder.getCallingUid();
|
||||
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
|
||||
true /* requireFullPermission */, false /* checkShell */,
|
||||
"getDeclaredSharedLibraries");
|
||||
enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
|
||||
false /* checkShell */, "getDeclaredSharedLibraries");
|
||||
|
||||
Preconditions.checkNotNull(packageName, "packageName cannot be null");
|
||||
Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
|
||||
@@ -5859,9 +5857,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
if (!mUserManager.exists(userId)) return null;
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
flags = updateFlagsForComponent(flags, userId);
|
||||
mPermissionManager.enforceCrossUserOrProfilePermission(
|
||||
callingUid, userId, false /* requireFullPermission */, false /* checkShell */,
|
||||
"get service info");
|
||||
enforceCrossUserOrProfilePermission(callingUid, userId, false /* requireFullPermission */,
|
||||
false /* checkShell */, "get service info");
|
||||
synchronized (mLock) {
|
||||
ParsedService s = mComponentResolver.getService(component);
|
||||
if (DEBUG_PACKAGE_INFO) Log.v(
|
||||
@@ -5890,8 +5887,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
if (!mUserManager.exists(userId)) return null;
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
flags = updateFlagsForComponent(flags, userId);
|
||||
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
|
||||
false /* requireFullPermission */, false /* checkShell */, "get provider info");
|
||||
enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
|
||||
false /* checkShell */, "get provider info");
|
||||
synchronized (mLock) {
|
||||
ParsedProvider p = mComponentResolver.getProvider(component);
|
||||
if (DEBUG_PACKAGE_INFO) Log.v(
|
||||
@@ -6028,8 +6025,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
if (!mUserManager.exists(userId)) {
|
||||
return null;
|
||||
}
|
||||
mPermissionManager.enforceCrossUserPermission(
|
||||
callingUid, userId, false, false, "getChangedPackages");
|
||||
enforceCrossUserPermission(callingUid, userId, false, false, "getChangedPackages");
|
||||
synchronized (mLock) {
|
||||
if (sequenceNumber >= mChangedPackagesSequenceNumber) {
|
||||
return null;
|
||||
@@ -6654,8 +6650,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
flags = updateFlagsForResolve(flags, userId, filterCallingUid, resolveForStart,
|
||||
isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId, resolvedType,
|
||||
flags));
|
||||
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
|
||||
false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
|
||||
enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
|
||||
false /*checkShell*/, "resolve intent");
|
||||
|
||||
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
|
||||
final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
|
||||
@@ -7362,7 +7358,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits) {
|
||||
if (!mUserManager.exists(userId)) return Collections.emptyList();
|
||||
final String instantAppPkgName = getInstantAppPackageName(filterCallingUid);
|
||||
mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
|
||||
enforceCrossUserPermission(Binder.getCallingUid(), userId,
|
||||
false /* requireFullPermission */, false /* checkShell */,
|
||||
"query intent activities");
|
||||
final String pkgName = intent.getPackage();
|
||||
@@ -8169,9 +8165,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
flags = updateFlagsForResolve(flags, userId, callingUid, false /*includeInstantApps*/,
|
||||
isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId, resolvedType,
|
||||
flags));
|
||||
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
|
||||
false /*requireFullPermission*/, false /*checkShell*/,
|
||||
"query intent activity options");
|
||||
enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
|
||||
false /*checkShell*/, "query intent activity options");
|
||||
final String resultsAction = intent.getAction();
|
||||
|
||||
final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
|
||||
@@ -8350,9 +8345,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
String resolvedType, int flags, int userId, boolean allowDynamicSplits) {
|
||||
if (!mUserManager.exists(userId)) return Collections.emptyList();
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
|
||||
false /*requireFullPermission*/, false /*checkShell*/,
|
||||
"query intent receivers");
|
||||
enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
|
||||
false /*checkShell*/, "query intent receivers");
|
||||
final String instantAppPkgName = getInstantAppPackageName(callingUid);
|
||||
flags = updateFlagsForResolve(flags, userId, callingUid, false /*includeInstantApps*/,
|
||||
isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId, resolvedType,
|
||||
@@ -8472,7 +8466,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
String resolvedType, int flags, int userId, int callingUid,
|
||||
boolean includeInstantApps) {
|
||||
if (!mUserManager.exists(userId)) return Collections.emptyList();
|
||||
mPermissionManager.enforceCrossUserOrProfilePermission(callingUid,
|
||||
enforceCrossUserOrProfilePermission(callingUid,
|
||||
userId,
|
||||
false /*requireFullPermission*/,
|
||||
false /*checkShell*/,
|
||||
@@ -8756,9 +8750,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
final boolean listApex = (flags & MATCH_APEX) != 0;
|
||||
final boolean listFactory = (flags & MATCH_FACTORY_ONLY) != 0;
|
||||
|
||||
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
|
||||
false /* requireFullPermission */, false /* checkShell */,
|
||||
"get installed packages");
|
||||
enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
|
||||
false /* checkShell */, "get installed packages");
|
||||
|
||||
// writer
|
||||
synchronized (mLock) {
|
||||
@@ -8868,9 +8861,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
String[] permissions, int flags, int userId) {
|
||||
if (!mUserManager.exists(userId)) return ParceledListSlice.emptyList();
|
||||
flags = updateFlagsForPackage(flags, userId);
|
||||
mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
|
||||
true /* requireFullPermission */, false /* checkShell */,
|
||||
"get packages holding permissions");
|
||||
enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */,
|
||||
false /* checkShell */, "get packages holding permissions");
|
||||
final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
|
||||
|
||||
// writer
|
||||
@@ -8912,7 +8904,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
flags = updateFlagsForApplication(flags, userId);
|
||||
final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
|
||||
|
||||
mPermissionManager.enforceCrossUserPermission(
|
||||
enforceCrossUserPermission(
|
||||
callingUid,
|
||||
userId,
|
||||
false /* requireFullPermission */,
|
||||
@@ -8986,9 +8978,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
|
||||
"getEphemeralApplications");
|
||||
}
|
||||
mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
|
||||
true /* requireFullPermission */, false /* checkShell */,
|
||||
"getEphemeralApplications");
|
||||
enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */,
|
||||
false /* checkShell */, "getEphemeralApplications");
|
||||
synchronized (mLock) {
|
||||
List<InstantAppInfo> instantApps = mInstantAppRegistry
|
||||
.getInstantAppsLPr(userId);
|
||||
@@ -9002,9 +8993,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
@Override
|
||||
public boolean isInstantApp(String packageName, int userId) {
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
|
||||
true /* requireFullPermission */, false /* checkShell */,
|
||||
"isInstantApp");
|
||||
enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
|
||||
false /* checkShell */, "isInstantApp");
|
||||
|
||||
return isInstantAppInternal(packageName, userId, callingUid);
|
||||
}
|
||||
@@ -9038,9 +9028,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
return null;
|
||||
}
|
||||
|
||||
mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
|
||||
true /* requireFullPermission */, false /* checkShell */,
|
||||
"getInstantAppCookie");
|
||||
enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */,
|
||||
false /* checkShell */, "getInstantAppCookie");
|
||||
if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
|
||||
return null;
|
||||
}
|
||||
@@ -9056,9 +9045,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
return true;
|
||||
}
|
||||
|
||||
mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
|
||||
true /* requireFullPermission */, true /* checkShell */,
|
||||
"setInstantAppCookie");
|
||||
enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */,
|
||||
true /* checkShell */, "setInstantAppCookie");
|
||||
if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
|
||||
return false;
|
||||
}
|
||||
@@ -9078,9 +9066,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
|
||||
"getInstantAppIcon");
|
||||
}
|
||||
mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
|
||||
true /* requireFullPermission */, false /* checkShell */,
|
||||
"getInstantAppIcon");
|
||||
enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */,
|
||||
false /* checkShell */, "getInstantAppIcon");
|
||||
|
||||
synchronized (mLock) {
|
||||
return mInstantAppRegistry.getInstantAppIconLPw(
|
||||
@@ -9156,8 +9143,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
}
|
||||
}
|
||||
if (!checkedGrants) {
|
||||
mPermissionManager.enforceCrossUserPermission(
|
||||
callingUid, userId, false, false, "resolveContentProvider");
|
||||
enforceCrossUserPermission(callingUid, userId, false, false, "resolveContentProvider");
|
||||
}
|
||||
if (providerInfo == null) {
|
||||
return null;
|
||||
@@ -9842,6 +9828,171 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enforces the request is from the system or an app that has INTERACT_ACROSS_USERS
|
||||
* or INTERACT_ACROSS_USERS_FULL permissions, if the {@code userId} is not for the caller.
|
||||
*
|
||||
* @param checkShell whether to prevent shell from access if there's a debugging restriction
|
||||
* @param message the message to log on security exception
|
||||
*/
|
||||
void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
|
||||
boolean requireFullPermission, boolean checkShell, String message) {
|
||||
enforceCrossUserPermission(callingUid, userId, requireFullPermission, checkShell, false,
|
||||
message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enforces the request is from the system or an app that has INTERACT_ACROSS_USERS
|
||||
* or INTERACT_ACROSS_USERS_FULL permissions, if the {@code userId} is not for the caller.
|
||||
*
|
||||
* @param checkShell whether to prevent shell from access if there's a debugging restriction
|
||||
* @param requirePermissionWhenSameUser When {@code true}, still require the cross user
|
||||
* permission to be held even if the callingUid and userId
|
||||
* reference the same user.
|
||||
* @param message the message to log on security exception
|
||||
*/
|
||||
private void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
|
||||
boolean requireFullPermission, boolean checkShell,
|
||||
boolean requirePermissionWhenSameUser, String message) {
|
||||
if (userId < 0) {
|
||||
throw new IllegalArgumentException("Invalid userId " + userId);
|
||||
}
|
||||
if (checkShell) {
|
||||
PackageManagerServiceUtils.enforceShellRestriction(mInjector.getUserManagerInternal(),
|
||||
UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
|
||||
}
|
||||
final int callingUserId = UserHandle.getUserId(callingUid);
|
||||
if (hasCrossUserPermission(
|
||||
callingUid, callingUserId, userId, requireFullPermission,
|
||||
requirePermissionWhenSameUser)) {
|
||||
return;
|
||||
}
|
||||
String errorMessage = buildInvalidCrossUserPermissionMessage(
|
||||
callingUid, userId, message, requireFullPermission);
|
||||
Slog.w(TAG, errorMessage);
|
||||
throw new SecurityException(errorMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the request is from the system or an app that has the appropriate cross-user
|
||||
* permissions defined as follows:
|
||||
* <ul>
|
||||
* <li>INTERACT_ACROSS_USERS_FULL if {@code requireFullPermission} is true.</li>
|
||||
* <li>INTERACT_ACROSS_USERS if the given {@code userId} is in a different profile group
|
||||
* to the caller.</li>
|
||||
* <li>Otherwise, INTERACT_ACROSS_PROFILES if the given {@code userId} is in the same profile
|
||||
* group as the caller.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param checkShell whether to prevent shell from access if there's a debugging restriction
|
||||
* @param message the message to log on security exception
|
||||
*/
|
||||
private void enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId,
|
||||
boolean requireFullPermission, boolean checkShell, String message) {
|
||||
if (userId < 0) {
|
||||
throw new IllegalArgumentException("Invalid userId " + userId);
|
||||
}
|
||||
if (checkShell) {
|
||||
PackageManagerServiceUtils.enforceShellRestriction(mInjector.getUserManagerInternal(),
|
||||
UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
|
||||
}
|
||||
final int callingUserId = UserHandle.getUserId(callingUid);
|
||||
if (hasCrossUserPermission(callingUid, callingUserId, userId, requireFullPermission,
|
||||
/*requirePermissionWhenSameUser= */ false)) {
|
||||
return;
|
||||
}
|
||||
final boolean isSameProfileGroup = isSameProfileGroup(callingUserId, userId);
|
||||
if (isSameProfileGroup && PermissionChecker.checkPermissionForPreflight(
|
||||
mContext,
|
||||
android.Manifest.permission.INTERACT_ACROSS_PROFILES,
|
||||
PermissionChecker.PID_UNKNOWN,
|
||||
callingUid,
|
||||
mPmInternal.getPackage(callingUid).getPackageName())
|
||||
== PermissionChecker.PERMISSION_GRANTED) {
|
||||
return;
|
||||
}
|
||||
String errorMessage = buildInvalidCrossUserOrProfilePermissionMessage(
|
||||
callingUid, userId, message, requireFullPermission, isSameProfileGroup);
|
||||
Slog.w(TAG, errorMessage);
|
||||
throw new SecurityException(errorMessage);
|
||||
}
|
||||
|
||||
private boolean hasCrossUserPermission(
|
||||
int callingUid, int callingUserId, int userId, boolean requireFullPermission,
|
||||
boolean requirePermissionWhenSameUser) {
|
||||
if (!requirePermissionWhenSameUser && userId == callingUserId) {
|
||||
return true;
|
||||
}
|
||||
if (callingUid == Process.SYSTEM_UID || callingUid == Process.ROOT_UID) {
|
||||
return true;
|
||||
}
|
||||
if (requireFullPermission) {
|
||||
return hasPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL);
|
||||
}
|
||||
return hasPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
|
||||
|| hasPermission(Manifest.permission.INTERACT_ACROSS_USERS);
|
||||
}
|
||||
|
||||
private boolean hasPermission(String permission) {
|
||||
return mContext.checkCallingOrSelfPermission(permission)
|
||||
== PackageManager.PERMISSION_GRANTED;
|
||||
}
|
||||
|
||||
private boolean isSameProfileGroup(@UserIdInt int callerUserId, @UserIdInt int userId) {
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
return UserManagerService.getInstance().isSameProfileGroup(callerUserId, userId);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
private static String buildInvalidCrossUserPermissionMessage(int callingUid,
|
||||
@UserIdInt int userId, String message, boolean requireFullPermission) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
if (message != null) {
|
||||
builder.append(message);
|
||||
builder.append(": ");
|
||||
}
|
||||
builder.append("UID ");
|
||||
builder.append(callingUid);
|
||||
builder.append(" requires ");
|
||||
builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
|
||||
if (!requireFullPermission) {
|
||||
builder.append(" or ");
|
||||
builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
|
||||
}
|
||||
builder.append(" to access user ");
|
||||
builder.append(userId);
|
||||
builder.append(".");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private static String buildInvalidCrossUserOrProfilePermissionMessage(int callingUid,
|
||||
@UserIdInt int userId, String message, boolean requireFullPermission,
|
||||
boolean isSameProfileGroup) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
if (message != null) {
|
||||
builder.append(message);
|
||||
builder.append(": ");
|
||||
}
|
||||
builder.append("UID ");
|
||||
builder.append(callingUid);
|
||||
builder.append(" requires ");
|
||||
builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
|
||||
if (!requireFullPermission) {
|
||||
builder.append(" or ");
|
||||
builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
|
||||
if (isSameProfileGroup) {
|
||||
builder.append(" or ");
|
||||
builder.append(android.Manifest.permission.INTERACT_ACROSS_PROFILES);
|
||||
}
|
||||
}
|
||||
builder.append(" to access user ");
|
||||
builder.append(".");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performFstrimIfNeeded() {
|
||||
enforceSystemOrRoot("Only the system can request fstrim");
|
||||
@@ -13270,9 +13421,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
|
||||
PackageSetting pkgSetting;
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
|
||||
true /* requireFullPermission */, true /* checkShell */,
|
||||
"setApplicationHiddenSetting for user " + userId);
|
||||
enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
|
||||
true /* checkShell */, "setApplicationHiddenSetting for user " + userId);
|
||||
|
||||
if (hidden && isPackageDeviceAdmin(packageName, userId)) {
|
||||
Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
|
||||
@@ -13458,9 +13608,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
|
||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
|
||||
true /* requireFullPermission */, false /* checkShell */,
|
||||
"getApplicationHidden for user " + userId);
|
||||
enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
|
||||
false /* checkShell */, "getApplicationHidden for user " + userId);
|
||||
PackageSetting ps;
|
||||
final long callingId = Binder.clearCallingIdentity();
|
||||
try {
|
||||
@@ -13510,9 +13659,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
+ android.Manifest.permission.INSTALL_PACKAGES + ".");
|
||||
}
|
||||
PackageSetting pkgSetting;
|
||||
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
|
||||
true /* requireFullPermission */, true /* checkShell */,
|
||||
"installExistingPackage for user " + userId);
|
||||
enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
|
||||
true /* checkShell */, "installExistingPackage for user " + userId);
|
||||
if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
|
||||
return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
|
||||
}
|
||||
@@ -13877,9 +14025,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
@Override
|
||||
public boolean isPackageSuspendedForUser(String packageName, int userId) {
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
|
||||
true /* requireFullPermission */, false /* checkShell */,
|
||||
"isPackageSuspendedForUser for user " + userId);
|
||||
enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
|
||||
false /* checkShell */, "isPackageSuspendedForUser for user " + userId);
|
||||
synchronized (mLock) {
|
||||
final PackageSetting ps = mSettings.mPackages.get(packageName);
|
||||
if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
|
||||
@@ -19986,8 +20133,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
android.Manifest.permission.CLEAR_APP_USER_DATA, null);
|
||||
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
|
||||
true /* requireFullPermission */, false /* checkShell */, "clear application data");
|
||||
enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
|
||||
false /* checkShell */, "clear application data");
|
||||
|
||||
final boolean filterApp;
|
||||
synchronized (mLock) {
|
||||
@@ -20140,9 +20287,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
mContext.enforceCallingOrSelfPermission(
|
||||
android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES, null);
|
||||
}
|
||||
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
|
||||
/* requireFullPermission= */ true, /* checkShell= */ false,
|
||||
"delete application cache files");
|
||||
enforceCrossUserPermission(callingUid, userId, /* requireFullPermission= */ true,
|
||||
/* checkShell= */ false, "delete application cache files");
|
||||
final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
|
||||
android.Manifest.permission.ACCESS_INSTANT_APPS);
|
||||
|
||||
@@ -20268,8 +20414,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
String opname, boolean removeExisting) {
|
||||
// writer
|
||||
int callingUid = Binder.getCallingUid();
|
||||
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
|
||||
true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
|
||||
enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
|
||||
false /* checkShell */, "add preferred activity");
|
||||
if (mContext.checkCallingOrSelfPermission(
|
||||
android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
|
||||
!= PackageManager.PERMISSION_GRANTED) {
|
||||
@@ -20343,9 +20489,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
}
|
||||
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
|
||||
true /* requireFullPermission */, false /* checkShell */,
|
||||
"replace preferred activity");
|
||||
enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
|
||||
false /* checkShell */, "replace preferred activity");
|
||||
if (mContext.checkCallingOrSelfPermission(
|
||||
android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
|
||||
!= PackageManager.PERMISSION_GRANTED) {
|
||||
@@ -21554,8 +21699,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
permission = mContext.checkCallingOrSelfPermission(
|
||||
android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
|
||||
}
|
||||
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
|
||||
false /* requireFullPermission */, true /* checkShell */, "set enabled");
|
||||
enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
|
||||
true /* checkShell */, "set enabled");
|
||||
final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
|
||||
boolean sendNow = false;
|
||||
boolean isApp = (className == null);
|
||||
@@ -21780,7 +21925,7 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
if (!mUserManager.exists(userId)) {
|
||||
return;
|
||||
}
|
||||
mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
|
||||
enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
|
||||
false /* checkShell */, "flushPackageRestrictions");
|
||||
synchronized (mLock) {
|
||||
flushPackageRestrictionsAsUserInternalLocked(userId);
|
||||
@@ -21845,8 +21990,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
final int permission = mContext.checkCallingOrSelfPermission(
|
||||
android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
|
||||
final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
|
||||
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
|
||||
true /* requireFullPermission */, true /* checkShell */, "stop package");
|
||||
enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
|
||||
true /* checkShell */, "stop package");
|
||||
// writer
|
||||
synchronized (mLock) {
|
||||
final PackageSetting ps = mSettings.mPackages.get(packageName);
|
||||
@@ -21993,8 +22138,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
public int getApplicationEnabledSetting(String packageName, int userId) {
|
||||
if (!mUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
|
||||
int callingUid = Binder.getCallingUid();
|
||||
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
|
||||
false /* requireFullPermission */, false /* checkShell */, "get enabled");
|
||||
enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
|
||||
false /* checkShell */, "get enabled");
|
||||
// reader
|
||||
synchronized (mLock) {
|
||||
try {
|
||||
@@ -22014,8 +22159,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
if (component == null) return COMPONENT_ENABLED_STATE_DEFAULT;
|
||||
if (!mUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
|
||||
int callingUid = Binder.getCallingUid();
|
||||
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
|
||||
false /*requireFullPermission*/, false /*checkShell*/, "getComponentEnabled");
|
||||
enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
|
||||
false /*checkShell*/, "getComponentEnabled");
|
||||
synchronized (mLock) {
|
||||
try {
|
||||
if (shouldFilterApplicationLocked(
|
||||
@@ -26110,9 +26255,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
@Override
|
||||
public int getInstallReason(String packageName, int userId) {
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
|
||||
true /* requireFullPermission */, false /* checkShell */,
|
||||
"get install reason");
|
||||
enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
|
||||
false /* checkShell */, "get install reason");
|
||||
synchronized (mLock) {
|
||||
final PackageSetting ps = mSettings.mPackages.get(packageName);
|
||||
if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
|
||||
@@ -26194,9 +26338,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
public String getInstantAppAndroidId(String packageName, int userId) {
|
||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS,
|
||||
"getInstantAppAndroidId");
|
||||
mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
|
||||
true /* requireFullPermission */, false /* checkShell */,
|
||||
"getInstantAppAndroidId");
|
||||
enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */,
|
||||
false /* checkShell */, "getInstantAppAndroidId");
|
||||
// Make sure the target is an Instant App.
|
||||
if (!isInstantApp(packageName, userId)) {
|
||||
return null;
|
||||
@@ -26312,8 +26455,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
final int callingAppId = UserHandle.getAppId(callingUid);
|
||||
|
||||
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
|
||||
true /*requireFullPermission*/, true /*checkShell*/, "setHarmfulAppInfo");
|
||||
enforceCrossUserPermission(callingUid, userId, true /*requireFullPermission*/,
|
||||
true /*checkShell*/, "setHarmfulAppInfo");
|
||||
|
||||
if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID &&
|
||||
checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid) != PERMISSION_GRANTED) {
|
||||
@@ -26333,8 +26476,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
final int callingAppId = UserHandle.getAppId(callingUid);
|
||||
|
||||
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
|
||||
true /*requireFullPermission*/, true /*checkShell*/, "getHarmfulAppInfo");
|
||||
enforceCrossUserPermission(callingUid, userId, true /*requireFullPermission*/,
|
||||
true /*checkShell*/, "getHarmfulAppInfo");
|
||||
|
||||
if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID &&
|
||||
checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid) != PERMISSION_GRANTED) {
|
||||
@@ -26352,8 +26495,8 @@ public class PackageManagerService extends IPackageManager.Stub
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
final int callingAppId = UserHandle.getAppId(callingUid);
|
||||
|
||||
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
|
||||
false /*requireFullPermission*/, true /*checkShell*/, "isPackageStateProtected");
|
||||
enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
|
||||
true /*checkShell*/, "isPackageStateProtected");
|
||||
|
||||
if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID
|
||||
&& checkUidPermission(MANAGE_DEVICE_ADMINS, callingUid) != PERMISSION_GRANTED) {
|
||||
|
||||
@@ -77,7 +77,6 @@ import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.PermissionChecker;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
@@ -96,6 +95,7 @@ import android.content.pm.permission.SplitPermissionInfoParcelable;
|
||||
import android.metrics.LogMaker;
|
||||
import android.os.Binder;
|
||||
import android.os.Build;
|
||||
import android.os.Debug;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.Looper;
|
||||
@@ -754,7 +754,6 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
||||
enforceCrossUserPermission(callingUid, userId,
|
||||
true, // requireFullPermission
|
||||
false, // checkShell
|
||||
false, // requirePermissionWhenSameUser
|
||||
"getPermissionFlags");
|
||||
|
||||
final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
|
||||
@@ -841,7 +840,6 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
||||
enforceCrossUserPermission(callingUid, userId,
|
||||
true, // requireFullPermission
|
||||
true, // checkShell
|
||||
false, // requirePermissionWhenSameUser
|
||||
"updatePermissionFlags");
|
||||
|
||||
if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0 && !overridePolicy) {
|
||||
@@ -951,7 +949,6 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
||||
enforceCrossUserPermission(callingUid, userId,
|
||||
true, // requireFullPermission
|
||||
true, // checkShell
|
||||
false, // requirePermissionWhenSameUser
|
||||
"updatePermissionFlagsForAllApps");
|
||||
|
||||
// Only the system can change system fixed flags.
|
||||
@@ -1555,7 +1552,6 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
||||
enforceCrossUserPermission(callingUid, userId,
|
||||
true, // requireFullPermission
|
||||
true, // checkShell
|
||||
false, // requirePermissionWhenSameUser
|
||||
"grantRuntimePermission");
|
||||
|
||||
final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
|
||||
@@ -1722,7 +1718,6 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
||||
enforceCrossUserPermission(callingUid, userId,
|
||||
true, // requireFullPermission
|
||||
true, // checkShell
|
||||
false, // requirePermissionWhenSameUser
|
||||
"revokeRuntimePermission");
|
||||
|
||||
final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
|
||||
@@ -4494,25 +4489,22 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
|
||||
* or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
|
||||
* Enforces the request is from the system or an app that has INTERACT_ACROSS_USERS
|
||||
* or INTERACT_ACROSS_USERS_FULL permissions, if the {@code userId} is not for the caller.
|
||||
*
|
||||
* @param checkShell whether to prevent shell from access if there's a debugging restriction
|
||||
* @param message the message to log on security exception
|
||||
*/
|
||||
private void enforceCrossUserPermission(int callingUid, @UserIdInt int userId,
|
||||
boolean requireFullPermission, boolean checkShell,
|
||||
boolean requirePermissionWhenSameUser, String message) {
|
||||
boolean requireFullPermission, boolean checkShell, @Nullable String message) {
|
||||
if (userId < 0) {
|
||||
throw new IllegalArgumentException("Invalid userId " + userId);
|
||||
}
|
||||
if (checkShell) {
|
||||
PackageManagerServiceUtils.enforceShellRestriction(mUserManagerInt,
|
||||
UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
|
||||
enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
|
||||
}
|
||||
final int callingUserId = UserHandle.getUserId(callingUid);
|
||||
if (hasCrossUserPermission(
|
||||
callingUid, callingUserId, userId, requireFullPermission,
|
||||
requirePermissionWhenSameUser)) {
|
||||
if (checkCrossUserPermission(callingUid, callingUserId, userId, requireFullPermission)) {
|
||||
return;
|
||||
}
|
||||
String errorMessage = buildInvalidCrossUserPermissionMessage(
|
||||
@@ -4522,82 +4514,45 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the request is from the system or an app that has the appropriate cross-user
|
||||
* permissions defined as follows:
|
||||
* <ul>
|
||||
* <li>INTERACT_ACROSS_USERS_FULL if {@code requireFullPermission} is true.</li>
|
||||
* <li>INTERACT_ACROSS_USERS if the given {@userId} is in a different profile group
|
||||
* to the caller.</li>
|
||||
* <li>Otherwise, INTERACT_ACROSS_PROFILES if the given {@userId} is in the same profile group
|
||||
* as the caller.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param checkShell whether to prevent shell from access if there's a debugging restriction
|
||||
* @param message the message to log on security exception
|
||||
* Enforces that if the caller is shell, it does not have the provided user restriction.
|
||||
*/
|
||||
private void enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId,
|
||||
boolean requireFullPermission, boolean checkShell,
|
||||
String message) {
|
||||
if (userId < 0) {
|
||||
throw new IllegalArgumentException("Invalid userId " + userId);
|
||||
private void enforceShellRestriction(@NonNull String restriction, int callingUid,
|
||||
@UserIdInt int userId) {
|
||||
if (callingUid == Process.SHELL_UID) {
|
||||
if (userId >= 0 && mUserManagerInt.hasUserRestriction(restriction, userId)) {
|
||||
throw new SecurityException("Shell does not have permission to access user "
|
||||
+ userId);
|
||||
} else if (userId < 0) {
|
||||
Slog.e(LOG_TAG, "Unable to check shell permission for user "
|
||||
+ userId + "\n\t" + Debug.getCallers(3));
|
||||
}
|
||||
}
|
||||
if (checkShell) {
|
||||
PackageManagerServiceUtils.enforceShellRestriction(mUserManagerInt,
|
||||
UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
|
||||
}
|
||||
final int callingUserId = UserHandle.getUserId(callingUid);
|
||||
if (hasCrossUserPermission(callingUid, callingUserId, userId, requireFullPermission,
|
||||
/*requirePermissionWhenSameUser= */ false)) {
|
||||
return;
|
||||
}
|
||||
final boolean isSameProfileGroup = isSameProfileGroup(callingUserId, userId);
|
||||
if (isSameProfileGroup && PermissionChecker.checkPermissionForPreflight(
|
||||
mContext,
|
||||
android.Manifest.permission.INTERACT_ACROSS_PROFILES,
|
||||
PermissionChecker.PID_UNKNOWN,
|
||||
callingUid,
|
||||
mPackageManagerInt.getPackage(callingUid).getPackageName())
|
||||
== PermissionChecker.PERMISSION_GRANTED) {
|
||||
return;
|
||||
}
|
||||
String errorMessage = buildInvalidCrossUserOrProfilePermissionMessage(
|
||||
callingUid, userId, message, requireFullPermission, isSameProfileGroup);
|
||||
Slog.w(TAG, errorMessage);
|
||||
throw new SecurityException(errorMessage);
|
||||
}
|
||||
|
||||
private boolean hasCrossUserPermission(
|
||||
int callingUid, int callingUserId, int userId, boolean requireFullPermission,
|
||||
boolean requirePermissionWhenSameUser) {
|
||||
if (!requirePermissionWhenSameUser && userId == callingUserId) {
|
||||
private boolean checkCrossUserPermission(int callingUid, @UserIdInt int callingUserId,
|
||||
@UserIdInt int userId, boolean requireFullPermission) {
|
||||
if (userId == callingUserId) {
|
||||
return true;
|
||||
}
|
||||
if (callingUid == Process.SYSTEM_UID || callingUid == Process.ROOT_UID) {
|
||||
return true;
|
||||
}
|
||||
if (requireFullPermission) {
|
||||
return hasPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL);
|
||||
return checkCallingOrSelfPermission(
|
||||
android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
|
||||
}
|
||||
return hasPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
|
||||
|| hasPermission(Manifest.permission.INTERACT_ACROSS_USERS);
|
||||
return checkCallingOrSelfPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
|
||||
|| checkCallingOrSelfPermission(android.Manifest.permission.INTERACT_ACROSS_USERS);
|
||||
}
|
||||
|
||||
private boolean hasPermission(String permission) {
|
||||
private boolean checkCallingOrSelfPermission(String permission) {
|
||||
return mContext.checkCallingOrSelfPermission(permission)
|
||||
== PackageManager.PERMISSION_GRANTED;
|
||||
}
|
||||
|
||||
private boolean isSameProfileGroup(@UserIdInt int callerUserId, @UserIdInt int userId) {
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
return UserManagerService.getInstance().isSameProfileGroup(callerUserId, userId);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private static String buildInvalidCrossUserPermissionMessage(int callingUid,
|
||||
@UserIdInt int userId, String message, boolean requireFullPermission) {
|
||||
@UserIdInt int userId, @Nullable String message, boolean requireFullPermission) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
if (message != null) {
|
||||
builder.append(message);
|
||||
@@ -4617,31 +4572,6 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private static String buildInvalidCrossUserOrProfilePermissionMessage(int callingUid,
|
||||
@UserIdInt int userId, String message, boolean requireFullPermission,
|
||||
boolean isSameProfileGroup) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
if (message != null) {
|
||||
builder.append(message);
|
||||
builder.append(": ");
|
||||
}
|
||||
builder.append("UID ");
|
||||
builder.append(callingUid);
|
||||
builder.append(" requires ");
|
||||
builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
|
||||
if (!requireFullPermission) {
|
||||
builder.append(" or ");
|
||||
builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
|
||||
if (isSameProfileGroup) {
|
||||
builder.append(" or ");
|
||||
builder.append(android.Manifest.permission.INTERACT_ACROSS_PROFILES);
|
||||
}
|
||||
}
|
||||
builder.append(" to access user ");
|
||||
builder.append(".");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private int calculateCurrentPermissionFootprintLocked(@NonNull Permission permissionTree) {
|
||||
int size = 0;
|
||||
@@ -5140,30 +5070,6 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
||||
Preconditions.checkArgumentNonNegative(userId, "userId");
|
||||
mPackageManagerInt.forEachPackage(pkg -> resetRuntimePermissionsInternal(pkg, userId));
|
||||
}
|
||||
@Override
|
||||
public void enforceCrossUserPermission(int callingUid, int userId,
|
||||
boolean requireFullPermission, boolean checkShell, String message) {
|
||||
PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
|
||||
requireFullPermission, checkShell, false, message);
|
||||
}
|
||||
@Override
|
||||
public void enforceCrossUserPermission(int callingUid, int userId,
|
||||
boolean requireFullPermission, boolean checkShell,
|
||||
boolean requirePermissionWhenSameUser, String message) {
|
||||
PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
|
||||
requireFullPermission, checkShell, requirePermissionWhenSameUser, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enforceCrossUserOrProfilePermission(int callingUid, int userId,
|
||||
boolean requireFullPermission, boolean checkShell, String message) {
|
||||
PermissionManagerService.this.enforceCrossUserOrProfilePermission(
|
||||
callingUid,
|
||||
userId,
|
||||
requireFullPermission,
|
||||
checkShell,
|
||||
message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Permission getPermissionTEMP(String permName) {
|
||||
|
||||
@@ -393,32 +393,6 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager
|
||||
@NonNull
|
||||
public abstract String[] getAppOpPermissionPackages(@NonNull String permissionName);
|
||||
|
||||
/**
|
||||
* Enforces the request is from the system or an app that has INTERACT_ACROSS_USERS
|
||||
* or INTERACT_ACROSS_USERS_FULL permissions, if the {@code userid} is not for the caller.
|
||||
* @param checkShell whether to prevent shell from access if there's a debugging restriction
|
||||
* @param message the message to log on security exception
|
||||
*/
|
||||
public abstract void enforceCrossUserPermission(int callingUid, int userId,
|
||||
boolean requireFullPermission, boolean checkShell, @NonNull String message);
|
||||
|
||||
/**
|
||||
* Similar to {@link #enforceCrossUserPermission(int, int, boolean, boolean, String)}
|
||||
* but also allows INTERACT_ACROSS_PROFILES permission if calling user and {@code userId} are
|
||||
* in the same profile group.
|
||||
*/
|
||||
public abstract void enforceCrossUserOrProfilePermission(int callingUid, int userId,
|
||||
boolean requireFullPermission, boolean checkShell, @NonNull String message);
|
||||
|
||||
/**
|
||||
* @see #enforceCrossUserPermission(int, int, boolean, boolean, String)
|
||||
* @param requirePermissionWhenSameUser When {@code true}, still require the cross user
|
||||
* permission to be held even if the callingUid and userId reference the same user.
|
||||
*/
|
||||
public abstract void enforceCrossUserPermission(int callingUid, int userId,
|
||||
boolean requireFullPermission, boolean checkShell,
|
||||
boolean requirePermissionWhenSameUser, @NonNull String message);
|
||||
|
||||
/** HACK HACK methods to allow for partial migration of data to the PermissionManager class */
|
||||
@Nullable
|
||||
public abstract Permission getPermissionTEMP(@NonNull String permName);
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.server.pm.test.override
|
||||
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.pm.parsing.component.ParsedActivity
|
||||
import android.os.Binder
|
||||
import android.os.UserHandle
|
||||
@@ -31,7 +32,6 @@ import com.android.server.pm.UserManagerService
|
||||
import com.android.server.pm.parsing.pkg.AndroidPackage
|
||||
import com.android.server.pm.parsing.pkg.PackageImpl
|
||||
import com.android.server.pm.parsing.pkg.ParsedPackage
|
||||
import com.android.server.pm.permission.PermissionManagerServiceInternal
|
||||
import com.android.server.pm.test.override.PackageManagerComponentLabelIconOverrideTest.Companion.Params.AppType
|
||||
import com.android.server.testutils.TestHandler
|
||||
import com.android.server.testutils.mock
|
||||
@@ -45,11 +45,8 @@ import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.Parameterized
|
||||
import org.mockito.Mockito
|
||||
import org.mockito.Mockito.any
|
||||
import org.mockito.Mockito.anyBoolean
|
||||
import org.mockito.Mockito.anyInt
|
||||
import org.mockito.Mockito.anyString
|
||||
import org.mockito.Mockito.clearInvocations
|
||||
import org.mockito.Mockito.intThat
|
||||
import org.mockito.Mockito.never
|
||||
@@ -321,10 +318,6 @@ class PackageManagerComponentLabelIconOverrideTest {
|
||||
whenever(this.exists(intThat(matcher))) { true }
|
||||
whenever(this.isUserUnlockingOrUnlocked(intThat(matcher))) { true }
|
||||
}
|
||||
val mockPermissionManagerService: PermissionManagerServiceInternal = mockThrowOnUnmocked {
|
||||
whenever(this.enforceCrossUserPermission(anyInt(), anyInt(), anyBoolean(), anyBoolean(),
|
||||
anyString())) { }
|
||||
}
|
||||
val mockActivityTaskManager: ActivityTaskManagerInternal = mockThrowOnUnmocked {
|
||||
whenever(this.isCallerRecents(anyInt())) { false }
|
||||
}
|
||||
@@ -335,15 +328,19 @@ class PackageManagerComponentLabelIconOverrideTest {
|
||||
val mockContext: Context = mockThrowOnUnmocked {
|
||||
whenever(this.getString(
|
||||
com.android.internal.R.string.config_overrideComponentUiPackage)) { VALID_PKG }
|
||||
whenever(this.checkCallingOrSelfPermission(
|
||||
android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)) {
|
||||
PackageManager.PERMISSION_GRANTED
|
||||
}
|
||||
}
|
||||
val mockInjector: PackageManagerService.Injector = mock {
|
||||
whenever(this.lock) { Object() }
|
||||
whenever(this.componentResolver) { mockComponentResolver }
|
||||
whenever(this.userManagerService) { mockUserManagerService }
|
||||
whenever(this.permissionManagerServiceInternal) { mockPermissionManagerService }
|
||||
whenever(this.settings) { mockSettings }
|
||||
whenever(this.getLocalService(ActivityTaskManagerInternal::class.java)) {
|
||||
mockActivityTaskManager}
|
||||
mockActivityTaskManager
|
||||
}
|
||||
whenever(this.appsFilter) { mockAppsFilter }
|
||||
whenever(this.context) { mockContext }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user