Merge "Revert "Revert "pm: SharedUserId: Assign seinfo using actual targetSdkVersion""" into pi-dev

This commit is contained in:
TreeHugger Robot
2018-03-07 22:20:46 +00:00
committed by Android (Google) Code Review
4 changed files with 85 additions and 36 deletions

View File

@@ -763,15 +763,13 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
public String[] resourceDirs; public String[] resourceDirs;
/** /**
* String retrieved from the seinfo tag found in selinux policy. This value * String retrieved from the seinfo tag found in selinux policy. This value can be set through
* can be overridden with a value set through the mac_permissions.xml policy * the mac_permissions.xml policy construct. This value is used for setting an SELinux security
* construct. This value is useful in setting an SELinux security context on * context on the process as well as its data directory.
* the process as well as its data directory. The String default is being used
* here to represent a catchall label when no policy matches.
* *
* {@hide} * {@hide}
*/ */
public String seInfo = "default"; public String seInfo;
/** /**
* The seinfo tag generated per-user. This value may change based upon the * The seinfo tag generated per-user. This value may change based upon the

View File

@@ -2980,6 +2980,9 @@ public class PackageManagerService extends IPackageManager.Stub
} }
} }
} }
// Adjust seInfo to ensure apps which share a sharedUserId are placed in the same
// SELinux domain.
setting.fixSeInfoLocked();
} }
// Now that we know all the packages we are keeping, // Now that we know all the packages we are keeping,
@@ -10376,20 +10379,24 @@ public class PackageManagerService extends IPackageManager.Stub
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
} }
// SELinux sandboxes become more restrictive as targetSdkVersion increases. // Apps which share a sharedUserId must be placed in the same selinux domain. If this
// To ensure that apps with sharedUserId are placed in the same selinux domain // package is the first app installed as this shared user, set seInfoTargetSdkVersion to its
// without breaking any assumptions about access, put them into the least // targetSdkVersion. These are later adjusted in PackageManagerService's constructor to be
// restrictive targetSdkVersion=25 domain. // the lowest targetSdkVersion of all apps within the shared user, which corresponds to the
// TODO(b/72290969): Base this on the actual targetSdkVersion(s) of the apps within the // least restrictive selinux domain.
// sharedUserSetting, instead of defaulting to the least restrictive domain. // NOTE: As new packages are installed / updated, the shared user's seinfoTargetSdkVersion
final int targetSdk = (sharedUserSetting != null) ? 25 // will NOT be modified until next boot, even if a lower targetSdkVersion is used. This
: pkg.applicationInfo.targetSdkVersion; // ensures that all packages continue to run in the same selinux domain.
final int targetSdkVersion =
((sharedUserSetting != null) && (sharedUserSetting.packages.size() != 0)) ?
sharedUserSetting.seInfoTargetSdkVersion : pkg.applicationInfo.targetSdkVersion;
// TODO(b/71593002): isPrivileged for sharedUser and appInfo should never be out of sync. // TODO(b/71593002): isPrivileged for sharedUser and appInfo should never be out of sync.
// They currently can be if the sharedUser apps are signed with the platform key. // They currently can be if the sharedUser apps are signed with the platform key.
final boolean isPrivileged = (sharedUserSetting != null) ? final boolean isPrivileged = (sharedUserSetting != null) ?
sharedUserSetting.isPrivileged() | pkg.isPrivileged() : pkg.isPrivileged(); sharedUserSetting.isPrivileged() | pkg.isPrivileged() : pkg.isPrivileged();
SELinuxMMAC.assignSeInfoValue(pkg, isPrivileged, targetSdk); pkg.applicationInfo.seInfo = SELinuxMMAC.getSeInfo(pkg, isPrivileged,
pkg.applicationInfo.targetSandboxVersion, targetSdkVersion);
pkg.mExtras = pkgSetting; pkg.mExtras = pkgSetting;
pkg.applicationInfo.processName = fixProcessName( pkg.applicationInfo.processName = fixProcessName(

View File

@@ -64,6 +64,8 @@ public final class SELinuxMMAC {
/** Required MAC permissions files */ /** Required MAC permissions files */
private static List<File> sMacPermissions = new ArrayList<>(); private static List<File> sMacPermissions = new ArrayList<>();
private static final String DEFAULT_SEINFO = "default";
// Append privapp to existing seinfo label // Append privapp to existing seinfo label
private static final String PRIVILEGED_APP_STR = ":privapp"; private static final String PRIVILEGED_APP_STR = ":privapp";
@@ -307,45 +309,56 @@ public final class SELinuxMMAC {
} }
/** /**
* Applies a security label to a package based on an seinfo tag taken from a matched * Selects a security label to a package based on input parameters and the seinfo tag taken
* policy. All signature based policy stanzas are consulted and, if no match is * from a matched policy. All signature based policy stanzas are consulted and, if no match
* found, the default seinfo label of 'default' (set in ApplicationInfo object) is * is found, the default seinfo label of 'default' is used. The security label is attached to
* used. The security label is attached to the ApplicationInfo instance of the package * the ApplicationInfo instance of the package.
* in the event that a matching policy was found.
* *
* @param pkg object representing the package to be labeled. * @param pkg object representing the package to be labeled.
* @param isPrivileged boolean.
* @param targetSandboxVersion int.
* @param targetSdkVersion int. If this pkg runs as a sharedUser, targetSdkVersion is the
* greater of: lowest targetSdk for all pkgs in the sharedUser, or
* MINIMUM_TARGETSDKVERSION.
* @return String representing the resulting seinfo.
*/ */
public static void assignSeInfoValue(PackageParser.Package pkg, boolean isPrivileged, public static String getSeInfo(PackageParser.Package pkg, boolean isPrivileged,
int targetSdkVersion) { int targetSandboxVersion, int targetSdkVersion) {
String seInfo = null;
synchronized (sPolicies) { synchronized (sPolicies) {
if (!sPolicyRead) { if (!sPolicyRead) {
if (DEBUG_POLICY) { if (DEBUG_POLICY) {
Slog.d(TAG, "Policy not read"); Slog.d(TAG, "Policy not read");
} }
return; } else {
}
for (Policy policy : sPolicies) { for (Policy policy : sPolicies) {
String seInfo = policy.getMatchedSeInfo(pkg); seInfo = policy.getMatchedSeInfo(pkg);
if (seInfo != null) { if (seInfo != null) {
pkg.applicationInfo.seInfo = seInfo;
break; break;
} }
} }
} }
if (pkg.applicationInfo.targetSandboxVersion == 2)
pkg.applicationInfo.seInfo += SANDBOX_V2_STR;
if (isPrivileged) {
pkg.applicationInfo.seInfo += PRIVILEGED_APP_STR;
} }
pkg.applicationInfo.seInfo += TARGETSDKVERSION_STR + targetSdkVersion; if (seInfo == null) {
seInfo = DEFAULT_SEINFO;
}
if (targetSandboxVersion == 2) {
seInfo += SANDBOX_V2_STR;
}
if (isPrivileged) {
seInfo += PRIVILEGED_APP_STR;
}
seInfo += TARGETSDKVERSION_STR + targetSdkVersion;
if (DEBUG_POLICY_INSTALL) { if (DEBUG_POLICY_INSTALL) {
Slog.i(TAG, "package (" + pkg.packageName + ") labeled with " + Slog.i(TAG, "package (" + pkg.packageName + ") labeled with " +
"seinfo=" + pkg.applicationInfo.seInfo); "seinfo=" + seInfo);
} }
return seInfo;
} }
} }

View File

@@ -39,6 +39,10 @@ public final class SharedUserSetting extends SettingBase {
int uidFlags; int uidFlags;
int uidPrivateFlags; int uidPrivateFlags;
// The lowest targetSdkVersion of all apps in the sharedUserSetting, used to assign seinfo so
// that all apps within the sharedUser run in the same selinux context.
int seInfoTargetSdkVersion;
final ArraySet<PackageSetting> packages = new ArraySet<PackageSetting>(); final ArraySet<PackageSetting> packages = new ArraySet<PackageSetting>();
final PackageSignatures signatures = new PackageSignatures(); final PackageSignatures signatures = new PackageSignatures();
@@ -84,6 +88,11 @@ public final class SharedUserSetting extends SettingBase {
} }
void addPackage(PackageSetting packageSetting) { void addPackage(PackageSetting packageSetting) {
// If this is the first package added to this shared user, temporarily (until next boot) use
// its targetSdkVersion when assigning seInfo for the shared user.
if ((packages.size() == 0) && (packageSetting.pkg != null)) {
seInfoTargetSdkVersion = packageSetting.pkg.applicationInfo.targetSdkVersion;
}
if (packages.add(packageSetting)) { if (packages.add(packageSetting)) {
setFlags(this.pkgFlags | packageSetting.pkgFlags); setFlags(this.pkgFlags | packageSetting.pkgFlags);
setPrivateFlags(this.pkgPrivateFlags | packageSetting.pkgPrivateFlags); setPrivateFlags(this.pkgPrivateFlags | packageSetting.pkgPrivateFlags);
@@ -107,4 +116,26 @@ public final class SharedUserSetting extends SettingBase {
public boolean isPrivileged() { public boolean isPrivileged() {
return (this.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; return (this.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
} }
/**
* Determine the targetSdkVersion for a sharedUser and update pkg.applicationInfo.seInfo
* to ensure that all apps within the sharedUser share an SELinux domain. Use the lowest
* targetSdkVersion of all apps within the shared user, which corresponds to the least
* restrictive selinux domain.
*/
public void fixSeInfoLocked() {
final List<PackageParser.Package> pkgList = getPackages();
for (PackageParser.Package pkg : pkgList) {
if (pkg.applicationInfo.targetSdkVersion < seInfoTargetSdkVersion) {
seInfoTargetSdkVersion = pkg.applicationInfo.targetSdkVersion;
}
}
for (PackageParser.Package pkg : pkgList) {
final boolean isPrivileged = isPrivileged() | pkg.isPrivileged();
pkg.applicationInfo.seInfo = SELinuxMMAC.getSeInfo(pkg, isPrivileged,
pkg.applicationInfo.targetSandboxVersion, seInfoTargetSdkVersion);
}
}
} }