Add preinstalled partition to seinfo
Bug: 280547417 Test: boot pixel and cuttlefish Test: atest SELinuxMMACTest (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:8bbec9acb7cfdccd37ae622eeef2933684efc7d7) Merged-In: I0b407ad8b95278453d5b917e0da7024b245062b9 Change-Id: I0b407ad8b95278453d5b917e0da7024b245062b9
This commit is contained in:
committed by
Cherrypicker Worker
parent
8d4af1031c
commit
d2f1a64991
@@ -83,6 +83,8 @@ public final class SELinuxMMAC {
|
|||||||
// Append targetSdkVersion=n to existing seinfo label where n is the app's targetSdkVersion
|
// Append targetSdkVersion=n to existing seinfo label where n is the app's targetSdkVersion
|
||||||
private static final String TARGETSDKVERSION_STR = ":targetSdkVersion=";
|
private static final String TARGETSDKVERSION_STR = ":targetSdkVersion=";
|
||||||
|
|
||||||
|
private static final String PARTITION_STR = ":partition=";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows opt-in to the latest targetSdkVersion enforced changes without changing target SDK.
|
* Allows opt-in to the latest targetSdkVersion enforced changes without changing target SDK.
|
||||||
* Turning this change on for an app targeting the latest SDK or higher is a no-op.
|
* Turning this change on for an app targeting the latest SDK or higher is a no-op.
|
||||||
@@ -373,13 +375,31 @@ public final class SELinuxMMAC {
|
|||||||
return pkg.getTargetSdkVersion();
|
return pkg.getTargetSdkVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String getPartition(PackageState state) {
|
||||||
|
if (state.isSystemExt()) {
|
||||||
|
return "system_ext";
|
||||||
|
} else if (state.isProduct()) {
|
||||||
|
return "product";
|
||||||
|
} else if (state.isVendor()) {
|
||||||
|
return "vendor";
|
||||||
|
} else if (state.isOem()) {
|
||||||
|
return "oem";
|
||||||
|
} else if (state.isOdm()) {
|
||||||
|
return "odm";
|
||||||
|
} else if (state.isSystem()) {
|
||||||
|
return "system";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Selects a security label to a package based on input parameters and the seinfo tag taken
|
* Selects a security label to a package based on input parameters and the seinfo tag taken
|
||||||
* from a matched policy. All signature based policy stanzas are consulted and, if no match
|
* from a matched policy. All signature based policy stanzas are consulted and, if no match
|
||||||
* is found, the default seinfo label of 'default' is used. The security label is attached to
|
* is found, the default seinfo label of 'default' is used. The security label is attached to
|
||||||
* the ApplicationInfo instance of the package.
|
* the ApplicationInfo instance of the package.
|
||||||
*
|
*
|
||||||
* @param pkg object representing the package to be labeled.
|
* @param packageState {@link PackageState} object representing the package to be labeled.
|
||||||
|
* @param pkg {@link AndroidPackage} object representing the package to be labeled.
|
||||||
* @param sharedUser if the app shares a sharedUserId, then this has the shared setting.
|
* @param sharedUser if the app shares a sharedUserId, then this has the shared setting.
|
||||||
* @param compatibility the PlatformCompat service to ask about state of compat changes.
|
* @param compatibility the PlatformCompat service to ask about state of compat changes.
|
||||||
* @return String representing the resulting seinfo.
|
* @return String representing the resulting seinfo.
|
||||||
@@ -393,7 +413,7 @@ public final class SELinuxMMAC {
|
|||||||
final boolean isPrivileged =
|
final boolean isPrivileged =
|
||||||
(sharedUser != null) ? sharedUser.isPrivileged() | packageState.isPrivileged()
|
(sharedUser != null) ? sharedUser.isPrivileged() | packageState.isPrivileged()
|
||||||
: packageState.isPrivileged();
|
: packageState.isPrivileged();
|
||||||
return getSeInfo(pkg, isPrivileged, targetSdkVersion);
|
return getSeInfo(packageState, pkg, isPrivileged, targetSdkVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -402,15 +422,16 @@ public final class SELinuxMMAC {
|
|||||||
* is found, the default seinfo label of 'default' is used. The security label is attached to
|
* is found, the default seinfo label of 'default' is used. The security label is attached to
|
||||||
* the ApplicationInfo instance of the package.
|
* the ApplicationInfo instance of the package.
|
||||||
*
|
*
|
||||||
* @param pkg object representing the package to be labeled.
|
* @param packageState {@link PackageState} object representing the package to be labeled.
|
||||||
|
* @param pkg {@link AndroidPackage} object representing the package to be labeled.
|
||||||
* @param isPrivileged boolean.
|
* @param isPrivileged boolean.
|
||||||
* @param targetSdkVersion int. If this pkg runs as a sharedUser, targetSdkVersion is the
|
* @param targetSdkVersion int. If this pkg runs as a sharedUser, targetSdkVersion is the
|
||||||
* greater of: lowest targetSdk for all pkgs in the sharedUser, or
|
* greater of: lowest targetSdk for all pkgs in the sharedUser, or
|
||||||
* MINIMUM_TARGETSDKVERSION.
|
* MINIMUM_TARGETSDKVERSION.
|
||||||
* @return String representing the resulting seinfo.
|
* @return String representing the resulting seinfo.
|
||||||
*/
|
*/
|
||||||
public static String getSeInfo(AndroidPackage pkg, boolean isPrivileged,
|
public static String getSeInfo(PackageState packageState, AndroidPackage pkg,
|
||||||
int targetSdkVersion) {
|
boolean isPrivileged, int targetSdkVersion) {
|
||||||
String seInfo = null;
|
String seInfo = null;
|
||||||
synchronized (sPolicies) {
|
synchronized (sPolicies) {
|
||||||
if (!sPolicyRead) {
|
if (!sPolicyRead) {
|
||||||
@@ -437,8 +458,13 @@ public final class SELinuxMMAC {
|
|||||||
|
|
||||||
seInfo += TARGETSDKVERSION_STR + targetSdkVersion;
|
seInfo += TARGETSDKVERSION_STR + targetSdkVersion;
|
||||||
|
|
||||||
|
String partition = getPartition(packageState);
|
||||||
|
if (!partition.isEmpty()) {
|
||||||
|
seInfo += PARTITION_STR + partition;
|
||||||
|
}
|
||||||
|
|
||||||
if (DEBUG_POLICY_INSTALL) {
|
if (DEBUG_POLICY_INSTALL) {
|
||||||
Slog.i(TAG, "package (" + pkg.getPackageName() + ") labeled with "
|
Slog.i(TAG, "package (" + packageState.getPackageName() + ") labeled with "
|
||||||
+ "seinfo=" + seInfo);
|
+ "seinfo=" + seInfo);
|
||||||
}
|
}
|
||||||
return seInfo;
|
return seInfo;
|
||||||
|
|||||||
@@ -285,7 +285,7 @@ public final class SharedUserSetting extends SettingBase implements SharedUserAp
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final boolean isPrivileged = isPrivileged() | ps.isPrivileged();
|
final boolean isPrivileged = isPrivileged() | ps.isPrivileged();
|
||||||
ps.getPkgState().setOverrideSeInfo(SELinuxMMAC.getSeInfo(ps.getPkg(), isPrivileged,
|
ps.getPkgState().setOverrideSeInfo(SELinuxMMAC.getSeInfo(ps, ps.getPkg(), isPrivileged,
|
||||||
seInfoTargetSdkVersion));
|
seInfoTargetSdkVersion));
|
||||||
onChanged();
|
onChanged();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ package com.android.server.pm;
|
|||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.core.Is.is;
|
import static org.hamcrest.core.Is.is;
|
||||||
|
import static org.hamcrest.core.IsNot.not;
|
||||||
|
import static org.hamcrest.core.StringContains.containsString;
|
||||||
import static org.mockito.ArgumentMatchers.argThat;
|
import static org.mockito.ArgumentMatchers.argThat;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
@@ -53,7 +55,7 @@ public class SELinuxMMACTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getSeInfoOptInToLatest() {
|
public void getSeInfoOptInToLatest() {
|
||||||
var packageState = makePackageState(Build.VERSION_CODES.P);
|
var packageState = new PackageStateBuilder(Build.VERSION_CODES.P).build();
|
||||||
when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_LATEST_CHANGES),
|
when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_LATEST_CHANGES),
|
||||||
argThat(argument -> argument.packageName.equals(packageState.getPackageName()))))
|
argThat(argument -> argument.packageName.equals(packageState.getPackageName()))))
|
||||||
.thenReturn(true);
|
.thenReturn(true);
|
||||||
@@ -64,7 +66,7 @@ public class SELinuxMMACTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getSeInfoOptInToR() {
|
public void getSeInfoOptInToR() {
|
||||||
var packageState = makePackageState(Build.VERSION_CODES.P);
|
var packageState = new PackageStateBuilder(Build.VERSION_CODES.P).build();
|
||||||
when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_R_CHANGES),
|
when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_R_CHANGES),
|
||||||
argThat(argument -> argument.packageName.equals(packageState.getPackageName()))))
|
argThat(argument -> argument.packageName.equals(packageState.getPackageName()))))
|
||||||
.thenReturn(true);
|
.thenReturn(true);
|
||||||
@@ -75,7 +77,7 @@ public class SELinuxMMACTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getSeInfoNoOptIn() {
|
public void getSeInfoNoOptIn() {
|
||||||
var packageState = makePackageState(Build.VERSION_CODES.P);
|
var packageState = new PackageStateBuilder(Build.VERSION_CODES.P).build();
|
||||||
when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_LATEST_CHANGES),
|
when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_LATEST_CHANGES),
|
||||||
argThat(argument -> argument.packageName.equals(packageState.getPackageName()))))
|
argThat(argument -> argument.packageName.equals(packageState.getPackageName()))))
|
||||||
.thenReturn(false);
|
.thenReturn(false);
|
||||||
@@ -86,7 +88,7 @@ public class SELinuxMMACTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getSeInfoNoOptInButAlreadyLatest() {
|
public void getSeInfoNoOptInButAlreadyLatest() {
|
||||||
var packageState = makePackageState(LATEST_OPT_IN_VERSION);
|
var packageState = new PackageStateBuilder(LATEST_OPT_IN_VERSION).build();
|
||||||
when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_LATEST_CHANGES),
|
when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_LATEST_CHANGES),
|
||||||
argThat(argument -> argument.packageName.equals(packageState.getPackageName()))))
|
argThat(argument -> argument.packageName.equals(packageState.getPackageName()))))
|
||||||
.thenReturn(false);
|
.thenReturn(false);
|
||||||
@@ -97,7 +99,7 @@ public class SELinuxMMACTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getSeInfoTargetingCurDevelopment() {
|
public void getSeInfoTargetingCurDevelopment() {
|
||||||
var packageState = makePackageState(Build.VERSION_CODES.CUR_DEVELOPMENT);
|
var packageState = new PackageStateBuilder(Build.VERSION_CODES.CUR_DEVELOPMENT).build();
|
||||||
when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_LATEST_CHANGES),
|
when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_LATEST_CHANGES),
|
||||||
argThat(argument -> argument.packageName.equals(packageState.getPackageName()))))
|
argThat(argument -> argument.packageName.equals(packageState.getPackageName()))))
|
||||||
.thenReturn(true);
|
.thenReturn(true);
|
||||||
@@ -108,7 +110,7 @@ public class SELinuxMMACTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getSeInfoNoOptInButAlreadyR() {
|
public void getSeInfoNoOptInButAlreadyR() {
|
||||||
var packageState = makePackageState(R_OPT_IN_VERSION);
|
var packageState = new PackageStateBuilder(R_OPT_IN_VERSION).build();
|
||||||
when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_R_CHANGES),
|
when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_R_CHANGES),
|
||||||
argThat(argument -> argument.packageName.equals(packageState.getPackageName()))))
|
argThat(argument -> argument.packageName.equals(packageState.getPackageName()))))
|
||||||
.thenReturn(false);
|
.thenReturn(false);
|
||||||
@@ -119,7 +121,7 @@ public class SELinuxMMACTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getSeInfoOptInRButLater() {
|
public void getSeInfoOptInRButLater() {
|
||||||
var packageState = makePackageState(R_OPT_IN_VERSION + 1);
|
var packageState = new PackageStateBuilder(R_OPT_IN_VERSION + 1).build();
|
||||||
when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_R_CHANGES),
|
when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_R_CHANGES),
|
||||||
argThat(argument -> argument.packageName.equals(packageState.getPackageName()))))
|
argThat(argument -> argument.packageName.equals(packageState.getPackageName()))))
|
||||||
.thenReturn(true);
|
.thenReturn(true);
|
||||||
@@ -128,15 +130,114 @@ public class SELinuxMMACTest {
|
|||||||
is("default:targetSdkVersion=" + (R_OPT_IN_VERSION + 1)));
|
is("default:targetSdkVersion=" + (R_OPT_IN_VERSION + 1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private PackageState makePackageState(int targetSdkVersion) {
|
@Test
|
||||||
|
public void getSeInfoPreinstalledToSystem() {
|
||||||
|
var packageState = new PackageStateBuilder(Build.VERSION_CODES.CUR_DEVELOPMENT)
|
||||||
|
.setSystem(true).build();
|
||||||
|
when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_LATEST_CHANGES),
|
||||||
|
argThat(argument -> argument.packageName.equals(packageState.getPackageName()))))
|
||||||
|
.thenReturn(true);
|
||||||
|
assertThat(SELinuxMMAC.getSeInfo(packageState, packageState.getAndroidPackage(), null,
|
||||||
|
mMockCompatibility),
|
||||||
|
containsString(":partition=system"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getSeInfoPreinstalledToSystemExt() {
|
||||||
|
var packageState = new PackageStateBuilder(Build.VERSION_CODES.CUR_DEVELOPMENT)
|
||||||
|
.setSystem(true).setSystemExt(true).build();
|
||||||
|
when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_LATEST_CHANGES),
|
||||||
|
argThat(argument -> argument.packageName.equals(packageState.getPackageName()))))
|
||||||
|
.thenReturn(true);
|
||||||
|
assertThat(SELinuxMMAC.getSeInfo(packageState, packageState.getAndroidPackage(), null,
|
||||||
|
mMockCompatibility),
|
||||||
|
containsString(":partition=system_ext"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getSeInfoPreinstalledToProduct() {
|
||||||
|
var packageState = new PackageStateBuilder(Build.VERSION_CODES.CUR_DEVELOPMENT)
|
||||||
|
.setSystem(true).setProduct(true).build();
|
||||||
|
when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_LATEST_CHANGES),
|
||||||
|
argThat(argument -> argument.packageName.equals(packageState.getPackageName()))))
|
||||||
|
.thenReturn(true);
|
||||||
|
assertThat(SELinuxMMAC.getSeInfo(packageState, packageState.getAndroidPackage(), null,
|
||||||
|
mMockCompatibility),
|
||||||
|
containsString(":partition=product"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getSeInfoPreinstalledToVendor() {
|
||||||
|
var packageState = new PackageStateBuilder(Build.VERSION_CODES.CUR_DEVELOPMENT)
|
||||||
|
.setSystem(true).setVendor(true).build();
|
||||||
|
when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_LATEST_CHANGES),
|
||||||
|
argThat(argument -> argument.packageName.equals(packageState.getPackageName()))))
|
||||||
|
.thenReturn(true);
|
||||||
|
assertThat(SELinuxMMAC.getSeInfo(packageState, packageState.getAndroidPackage(), null,
|
||||||
|
mMockCompatibility),
|
||||||
|
containsString(":partition=vendor"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getSeInfoNotPreinstalled() {
|
||||||
|
var packageState = new PackageStateBuilder(Build.VERSION_CODES.CUR_DEVELOPMENT).build();
|
||||||
|
when(mMockCompatibility.isChangeEnabledInternal(eq(SELinuxMMAC.SELINUX_LATEST_CHANGES),
|
||||||
|
argThat(argument -> argument.packageName.equals(packageState.getPackageName()))))
|
||||||
|
.thenReturn(true);
|
||||||
|
assertThat(SELinuxMMAC.getSeInfo(packageState, packageState.getAndroidPackage(), null,
|
||||||
|
mMockCompatibility),
|
||||||
|
not(containsString(":partition=")));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class PackageStateBuilder {
|
||||||
|
private final int mTargetSdkVersion;
|
||||||
|
private boolean mIsSystem = false;
|
||||||
|
private boolean mIsSystemExt = false;
|
||||||
|
private boolean mIsProduct = false;
|
||||||
|
private boolean mIsVendor = false;
|
||||||
|
|
||||||
|
PackageStateBuilder(int targetSdkVersion) {
|
||||||
|
mTargetSdkVersion = targetSdkVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
PackageStateBuilder setSystem(boolean isSystem) {
|
||||||
|
mIsSystem = isSystem;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
PackageStateBuilder setSystemExt(boolean isSystemExt) {
|
||||||
|
mIsSystemExt = isSystemExt;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
PackageStateBuilder setProduct(boolean isProduct) {
|
||||||
|
mIsProduct = isProduct;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
PackageStateBuilder setVendor(boolean isVendor) {
|
||||||
|
mIsVendor = isVendor;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
PackageState build() {
|
||||||
var packageState = Mockito.mock(PackageState.class);
|
var packageState = Mockito.mock(PackageState.class);
|
||||||
when(packageState.getPackageName()).thenReturn(PACKAGE_NAME);
|
when(packageState.getPackageName()).thenReturn(PACKAGE_NAME);
|
||||||
when(packageState.getAndroidPackage()).thenReturn(
|
when(packageState.getAndroidPackage()).thenReturn(
|
||||||
((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME)
|
((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME)
|
||||||
.setTargetSdkVersion(targetSdkVersion)
|
.setTargetSdkVersion(mTargetSdkVersion)
|
||||||
.hideAsParsed())
|
.hideAsParsed())
|
||||||
.hideAsFinal()
|
.hideAsFinal()
|
||||||
);
|
);
|
||||||
|
when(packageState.isSystem()).thenReturn(mIsSystem);
|
||||||
|
when(packageState.isSystemExt()).thenReturn(mIsSystemExt);
|
||||||
|
when(packageState.isProduct()).thenReturn(mIsProduct);
|
||||||
|
when(packageState.isVendor()).thenReturn(mIsVendor);
|
||||||
return packageState;
|
return packageState;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user