Final changes to protect the API surface

This is it. The last set of changes to protect instant apps
from full apps.

Bug: 35871369
Test: cts-tradefed run commandAndExit cts-dev -m CtsAppSecurityHostTestCases -t android.appsecurity.cts.EphemeralTest
Test: Manual; install instant app and ensure it runs
Change-Id: If71385bcc9a5637590fbd99b0ffcd5ed8809509c
This commit is contained in:
Todd Kennedy
2017-06-02 07:38:20 -07:00
parent 6e96251d92
commit 4e4769c120

View File

@@ -2186,12 +2186,12 @@ public class PackageManagerService extends IPackageManager.Stub
private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
String[] grantedPermissions) {
SettingBase sb = (SettingBase) pkg.mExtras;
if (sb == null) {
PackageSetting ps = (PackageSetting) pkg.mExtras;
if (ps == null) {
return;
}
PermissionsState permissionsState = sb.getPermissionsState();
PermissionsState permissionsState = ps.getPermissionsState();
final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
| PackageManager.FLAG_PERMISSION_POLICY_FIXED;
@@ -4878,9 +4878,13 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
private void updateSequenceNumberLP(String packageName, int[] userList) {
private void updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList) {
for (int i = userList.length - 1; i >= 0; --i) {
final int userId = userList[i];
// don't add instant app to the list of updates
if (pkgSetting.getInstantApp(userId)) {
continue;
}
SparseArray<String> changedPackages = mChangedPackages.get(userId);
if (changedPackages == null) {
changedPackages = new SparseArray<>();
@@ -4891,12 +4895,12 @@ public class PackageManagerService extends IPackageManager.Stub
sequenceNumbers = new HashMap<>();
mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
}
final Integer sequenceNumber = sequenceNumbers.get(packageName);
final Integer sequenceNumber = sequenceNumbers.get(pkgSetting.name);
if (sequenceNumber != null) {
changedPackages.remove(sequenceNumber);
}
changedPackages.put(mChangedPackagesSequenceNumber, packageName);
sequenceNumbers.put(packageName, mChangedPackagesSequenceNumber);
changedPackages.put(mChangedPackagesSequenceNumber, pkgSetting.name);
sequenceNumbers.put(pkgSetting.name, mChangedPackagesSequenceNumber);
}
mChangedPackagesSequenceNumber++;
}
@@ -5338,7 +5342,7 @@ public class PackageManagerService extends IPackageManager.Stub
"grantRuntimePermission");
final int uid;
final SettingBase sb;
final PackageSetting ps;
synchronized (mPackages) {
final PackageParser.Package pkg = mPackages.get(packageName);
@@ -5349,12 +5353,9 @@ public class PackageManagerService extends IPackageManager.Stub
if (bp == null) {
throw new IllegalArgumentException("Unknown permission: " + name);
}
sb = (SettingBase) pkg.mExtras;
if (sb == null) {
throw new IllegalArgumentException("Unknown package: " + packageName);
}
if (sb instanceof PackageSetting
&& filterAppAccessLPr((PackageSetting) sb, callingUid, userId)) {
ps = (PackageSetting) pkg.mExtras;
if (ps == null
|| filterAppAccessLPr(ps, callingUid, userId)) {
throw new IllegalArgumentException("Unknown package: " + packageName);
}
@@ -5372,7 +5373,7 @@ public class PackageManagerService extends IPackageManager.Stub
uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
final PermissionsState permissionsState = sb.getPermissionsState();
final PermissionsState permissionsState = ps.getPermissionsState();
final int flags = permissionsState.getPermissionFlags(name, userId);
if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
@@ -5394,7 +5395,6 @@ public class PackageManagerService extends IPackageManager.Stub
return;
}
final PackageSetting ps = mSettings.mPackages.get(packageName);
if (ps.getInstantApp(userId) && !bp.isInstant()) {
throw new SecurityException("Cannot grant non-ephemeral permission"
+ name + " for package " + packageName);
@@ -5478,7 +5478,11 @@ public class PackageManagerService extends IPackageManager.Stub
if (pkg == null) {
throw new IllegalArgumentException("Unknown package: " + packageName);
}
final PackageSetting ps = (PackageSetting) pkg.mExtras;
if (ps == null
|| filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
throw new IllegalArgumentException("Unknown package: " + packageName);
}
final BasePermission bp = mSettings.mPermissions.get(name);
if (bp == null) {
throw new IllegalArgumentException("Unknown permission: " + name);
@@ -5496,12 +5500,7 @@ public class PackageManagerService extends IPackageManager.Stub
return;
}
SettingBase sb = (SettingBase) pkg.mExtras;
if (sb == null) {
throw new IllegalArgumentException("Unknown package: " + packageName);
}
final PermissionsState permissionsState = sb.getPermissionsState();
final PermissionsState permissionsState = ps.getPermissionsState();
final int flags = permissionsState.getPermissionFlags(name, userId);
if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
@@ -5654,15 +5653,12 @@ public class PackageManagerService extends IPackageManager.Stub
if (bp == null) {
return 0;
}
final SettingBase sb = (SettingBase) pkg.mExtras;
if (sb == null) {
final PackageSetting ps = (PackageSetting) pkg.mExtras;
if (ps == null
|| filterAppAccessLPr(ps, callingUid, userId)) {
return 0;
}
if (sb instanceof PackageSetting
&& filterAppAccessLPr((PackageSetting) sb, callingUid, userId)) {
return 0;
}
PermissionsState permissionsState = sb.getPermissionsState();
PermissionsState permissionsState = ps.getPermissionsState();
return permissionsState.getPermissionFlags(name, userId);
}
}
@@ -5676,7 +5672,8 @@ public class PackageManagerService extends IPackageManager.Stub
enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
enforceCrossUserPermission(Binder.getCallingUid(), userId,
final int callingUid = Binder.getCallingUid();
enforceCrossUserPermission(callingUid, userId,
true /* requireFullPermission */, true /* checkShell */,
"updatePermissionFlags");
@@ -5694,18 +5691,18 @@ public class PackageManagerService extends IPackageManager.Stub
if (pkg == null) {
throw new IllegalArgumentException("Unknown package: " + packageName);
}
final PackageSetting ps = (PackageSetting) pkg.mExtras;
if (ps == null
|| filterAppAccessLPr(ps, callingUid, userId)) {
throw new IllegalArgumentException("Unknown package: " + packageName);
}
final BasePermission bp = mSettings.mPermissions.get(name);
if (bp == null) {
throw new IllegalArgumentException("Unknown permission: " + name);
}
SettingBase sb = (SettingBase) pkg.mExtras;
if (sb == null) {
throw new IllegalArgumentException("Unknown package: " + packageName);
}
PermissionsState permissionsState = sb.getPermissionsState();
PermissionsState permissionsState = ps.getPermissionsState();
boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
@@ -5749,11 +5746,11 @@ public class PackageManagerService extends IPackageManager.Stub
final int packageCount = mPackages.size();
for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
SettingBase sb = (SettingBase) pkg.mExtras;
if (sb == null) {
final PackageSetting ps = (PackageSetting) pkg.mExtras;
if (ps == null) {
continue;
}
PermissionsState permissionsState = sb.getPermissionsState();
PermissionsState permissionsState = ps.getPermissionsState();
changed |= permissionsState.updatePermissionFlagsForAllPermissions(
userId, flagMask, flagValues);
}
@@ -9546,6 +9543,8 @@ public class PackageManagerService extends IPackageManager.Stub
public void reconcileSecondaryDexFiles(String packageName) {
if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
return;
} else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
return;
}
mDexManager.reconcileSecondaryDexFiles(packageName);
}
@@ -14323,8 +14322,8 @@ public class PackageManagerService extends IPackageManager.Stub
int userId) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
PackageSetting pkgSetting;
final int uid = Binder.getCallingUid();
enforceCrossUserPermission(uid, userId,
final int callingUid = Binder.getCallingUid();
enforceCrossUserPermission(callingUid, userId,
true /* requireFullPermission */, true /* checkShell */,
"setApplicationHiddenSetting for user " + userId);
@@ -14343,6 +14342,9 @@ public class PackageManagerService extends IPackageManager.Stub
if (pkgSetting == null) {
return false;
}
if (filterAppAccessLPr(pkgSetting, callingUid, userId)) {
return false;
}
// Do not allow "android" is being disabled
if ("android".equals(packageName)) {
Slog.w(TAG, "Cannot hide package: android");
@@ -14359,7 +14361,7 @@ public class PackageManagerService extends IPackageManager.Stub
return false;
}
// Only allow protected packages to hide themselves.
if (hidden && !UserHandle.isSameApp(uid, pkgSetting.appId)
if (hidden && !UserHandle.isSameApp(callingUid, pkgSetting.appId)
&& mProtectedPackages.isPackageStateProtected(userId, packageName)) {
Slog.w(TAG, "Not hiding protected package: " + packageName);
return false;
@@ -14476,6 +14478,20 @@ public class PackageManagerService extends IPackageManager.Stub
if (pkgSetting == null) {
return PackageManager.INSTALL_FAILED_INVALID_URI;
}
if (!canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) {
// only allow the existing package to be used if it's installed as a full
// application for at least one user
boolean installAllowed = false;
for (int checkUserId : sUserManager.getUserIds()) {
installAllowed = !pkgSetting.getInstantApp(checkUserId);
if (installAllowed) {
break;
}
}
if (!installAllowed) {
return PackageManager.INSTALL_FAILED_INVALID_URI;
}
}
if (!pkgSetting.getInstalled(userId)) {
pkgSetting.setInstalled(true, userId);
pkgSetting.setHidden(false, userId);
@@ -14499,7 +14515,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
sendPackageAddedForUser(packageName, pkgSetting, userId);
synchronized (mPackages) {
updateSequenceNumberLP(packageName, new int[]{ userId });
updateSequenceNumberLP(pkgSetting, new int[]{ userId });
}
}
} finally {
@@ -14545,7 +14561,8 @@ public class PackageManagerService extends IPackageManager.Stub
public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
int userId) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
enforceCrossUserPermission(Binder.getCallingUid(), userId,
final int callingUid = Binder.getCallingUid();
enforceCrossUserPermission(callingUid, userId,
true /* requireFullPermission */, true /* checkShell */,
"setPackagesSuspended for user " + userId);
@@ -14566,7 +14583,8 @@ public class PackageManagerService extends IPackageManager.Stub
final int appId;
synchronized (mPackages) {
final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
if (pkgSetting == null) {
if (pkgSetting == null
|| filterAppAccessLPr(pkgSetting, callingUid, userId)) {
Slog.w(TAG, "Could not find package setting for package \"" + packageName
+ "\". Skipping suspending/un-suspending.");
unactionedPackages.add(packageName);
@@ -14976,6 +14994,10 @@ public class PackageManagerService extends IPackageManager.Stub
boolean result = false;
synchronized (mPackages) {
final PackageSetting ps = mSettings.mPackages.get(packageName);
if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
return false;
}
result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
}
if (result) {
@@ -15076,7 +15098,9 @@ public class PackageManagerService extends IPackageManager.Stub
// writer
synchronized (mPackages) {
PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
if (targetPackageSetting == null) {
if (targetPackageSetting == null
|| filterAppAccessLPr(
targetPackageSetting, callingUid, UserHandle.getUserId(callingUid))) {
throw new IllegalArgumentException("Unknown target package: " + targetPackage);
}
@@ -15157,7 +15181,9 @@ public class PackageManagerService extends IPackageManager.Stub
if (ps == null) {
throw new IllegalArgumentException("Unknown target package " + packageName);
}
if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
throw new IllegalArgumentException("Unknown target package " + packageName);
}
if (!Objects.equals(callerPackageName, ps.installerPackageName)) {
throw new IllegalArgumentException("Calling package " + callerPackageName
+ " is not installer for " + packageName);
@@ -18178,7 +18204,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
updateSequenceNumberLP(pkgName, res.newUsers);
updateSequenceNumberLP(ps, res.newUsers);
updateInstantAppInstallerLocked(pkgName);
}
}
@@ -18779,7 +18805,7 @@ public class PackageManagerService extends IPackageManager.Stub
if (pkg != null) {
mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers);
}
updateSequenceNumberLP(packageName, info.removedUsers);
updateSequenceNumberLP(uninstalledPs, info.removedUsers);
updateInstantAppInstallerLocked(packageName);
}
}
@@ -21135,7 +21161,8 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
// Limit who can change which apps
if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) {
// Don't allow apps that don't have permission to modify other apps
if (!allowedByPermission) {
if (!allowedByPermission
|| filterAppAccessLPr(pkgSetting, callingUid, userId)) {
throw new SecurityException(
"Attempt to change component state; "
+ "pid=" + Binder.getCallingPid()
@@ -21222,7 +21249,7 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
}
}
scheduleWritePackageRestrictionsLocked(userId);
updateSequenceNumberLP(packageName, new int[] { userId });
updateSequenceNumberLP(pkgSetting, new int[] { userId });
final long callingId = Binder.clearCallingIdentity();
try {
updateInstantAppInstallerLocked(packageName);
@@ -21319,8 +21346,10 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
true /* requireFullPermission */, true /* checkShell */, "stop package");
// writer
synchronized (mPackages) {
if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
allowedByPermission, callingUid, userId)) {
final PackageSetting ps = mSettings.mPackages.get(packageName);
if (!filterAppAccessLPr(ps, callingUid, userId)
&& mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
allowedByPermission, callingUid, userId)) {
scheduleWritePackageRestrictionsLocked(userId);
}
}
@@ -21328,11 +21357,16 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
@Override
public String getInstallerPackageName(String packageName) {
if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
final int callingUid = Binder.getCallingUid();
if (getInstantAppPackageName(callingUid) != null) {
return null;
}
// reader
synchronized (mPackages) {
final PackageSetting ps = mSettings.mPackages.get(packageName);
if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
return null;
}
return mSettings.getInstallerPackageNameLPr(packageName);
}
}
@@ -24081,7 +24115,8 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
@Override
public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
final int callingUid = Binder.getCallingUid();
if (getInstantAppPackageName(callingUid) != null) {
return false;
}
if (packageName == null || ks == null) {
@@ -24089,7 +24124,9 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
}
synchronized(mPackages) {
final PackageParser.Package pkg = mPackages.get(packageName);
if (pkg == null) {
if (pkg == null
|| filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
UserHandle.getUserId(callingUid))) {
Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
throw new IllegalArgumentException("Unknown package: " + packageName);
}
@@ -24104,7 +24141,8 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
@Override
public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
final int callingUid = Binder.getCallingUid();
if (getInstantAppPackageName(callingUid) != null) {
return false;
}
if (packageName == null || ks == null) {
@@ -24112,7 +24150,9 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
}
synchronized(mPackages) {
final PackageParser.Package pkg = mPackages.get(packageName);
if (pkg == null) {
if (pkg == null
|| filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
UserHandle.getUserId(callingUid))) {
Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
throw new IllegalArgumentException("Unknown package: " + packageName);
}