Merge changes from topic "encryptedstore_java_api"
* changes:
Encryptedstore: Use microdroid specific mke2fs target
Resizing encryptedstore is incompatible
Enable transferring VM with encryptedstore enabled
Mount encrypted storage with dedicated context
Expose encryptedstore feature to system apps
diff --git a/encryptedstore/src/main.rs b/encryptedstore/src/main.rs
index 9c8311d..7140ae2 100644
--- a/encryptedstore/src/main.rs
+++ b/encryptedstore/src/main.rs
@@ -137,7 +137,10 @@
fn mount(source: &Path, mountpoint: &Path) -> Result<()> {
create_dir_all(mountpoint).context(format!("Failed to create {:?}", &mountpoint))?;
- let mount_options = CString::new("").unwrap();
+ let mount_options = CString::new(
+ "fscontext=u:object_r:encryptedstore_fs:s0,context=u:object_r:encryptedstore_file:s0",
+ )
+ .unwrap();
let source = CString::new(source.as_os_str().as_bytes())?;
let mountpoint = CString::new(mountpoint.as_os_str().as_bytes())?;
let fstype = CString::new("ext4").unwrap();
diff --git a/javalib/api/system-current.txt b/javalib/api/system-current.txt
index fb7c98c..c98c62e 100644
--- a/javalib/api/system-current.txt
+++ b/javalib/api/system-current.txt
@@ -58,10 +58,12 @@
public final class VirtualMachineConfig {
method @NonNull public String getApkPath();
method @NonNull public int getDebugLevel();
+ method @IntRange(from=0) public long getEncryptedStorageKib();
method @IntRange(from=0) public int getMemoryMib();
method @IntRange(from=1) public int getNumCpus();
method @Nullable public String getPayloadBinaryPath();
method public boolean isCompatibleWith(@NonNull android.system.virtualmachine.VirtualMachineConfig);
+ method public boolean isEncryptedStorageEnabled();
method public boolean isProtectedVm();
field public static final int DEBUG_LEVEL_FULL = 1; // 0x1
field public static final int DEBUG_LEVEL_NONE = 0; // 0x0
@@ -72,6 +74,7 @@
method @NonNull public android.system.virtualmachine.VirtualMachineConfig build();
method @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setApkPath(@NonNull String);
method @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setDebugLevel(int);
+ method @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setEncryptedStorageKib(@IntRange(from=0) long);
method @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setMemoryMib(@IntRange(from=0) int);
method @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setNumCpus(@IntRange(from=1) int);
method @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setPayloadBinaryPath(@NonNull String);
diff --git a/javalib/src/android/system/virtualmachine/VirtualMachine.java b/javalib/src/android/system/virtualmachine/VirtualMachine.java
index b8be703..504d3c7 100644
--- a/javalib/src/android/system/virtualmachine/VirtualMachine.java
+++ b/javalib/src/android/system/virtualmachine/VirtualMachine.java
@@ -169,6 +169,9 @@
/** Size of the instance image. 10 MB. */
private static final long INSTANCE_FILE_SIZE = 10 * 1024 * 1024;
+ /** Name of the file backing the encrypted storage */
+ private static final String ENCRYPTED_STORE_FILE = "storage.img";
+
/** The package which owns this VM. */
@NonNull private final String mPackageName;
@@ -191,6 +194,9 @@
/** Path to the idsig file for this VM. */
@NonNull private final File mIdsigFilePath;
+ /** File that backs the encrypted storage - Will be null if not enabled. */
+ @Nullable private final File mEncryptedStoreFilePath;
+
/**
* Unmodifiable list of extra apks. Apks are specified by the vm config, and corresponding
* idsigs are to be generated.
@@ -324,6 +330,10 @@
mExtraApks = setupExtraApks(context, config, thisVmDir);
mMemoryManagementCallbacks = new MemoryManagementCallbacks();
mContext = context;
+ mEncryptedStoreFilePath =
+ (config.isEncryptedStorageEnabled())
+ ? new File(thisVmDir, ENCRYPTED_STORE_FILE)
+ : null;
}
/**
@@ -354,6 +364,16 @@
throw new VirtualMachineException("failed to create instance image", e);
}
vm.importInstanceFrom(vmDescriptor.getInstanceImgFd());
+
+ if (vmDescriptor.getEncryptedStoreFd() != null) {
+ try {
+ vm.mEncryptedStoreFilePath.createNewFile();
+ } catch (IOException e) {
+ throw new VirtualMachineException(
+ "failed to create encrypted storage image", e);
+ }
+ vm.importEncryptedStoreFrom(vmDescriptor.getEncryptedStoreFd());
+ }
return vm;
} catch (VirtualMachineException | RuntimeException e) {
// If anything goes wrong, delete any files created so far and the VM's directory
@@ -386,6 +406,14 @@
} catch (IOException e) {
throw new VirtualMachineException("failed to create instance image", e);
}
+ if (config.isEncryptedStorageEnabled()) {
+ try {
+ vm.mEncryptedStoreFilePath.createNewFile();
+ } catch (IOException e) {
+ throw new VirtualMachineException(
+ "failed to create encrypted storage image", e);
+ }
+ }
IVirtualizationService service =
IVirtualizationService.Stub.asInterface(
@@ -403,6 +431,22 @@
} catch (ServiceSpecificException | IllegalArgumentException e) {
throw new VirtualMachineException("failed to create instance partition", e);
}
+
+ if (config.isEncryptedStorageEnabled()) {
+ try {
+ service.initializeWritablePartition(
+ ParcelFileDescriptor.open(vm.mEncryptedStoreFilePath, MODE_READ_WRITE),
+ config.getEncryptedStorageKib() * 1024L,
+ PartitionType.ENCRYPTEDSTORE);
+ } catch (FileNotFoundException e) {
+ throw new VirtualMachineException("encrypted storage image missing", e);
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ } catch (ServiceSpecificException | IllegalArgumentException e) {
+ throw new VirtualMachineException(
+ "failed to create encrypted storage partition", e);
+ }
+ }
return vm;
} catch (VirtualMachineException | RuntimeException e) {
// If anything goes wrong, delete any files created so far and the VM's directory
@@ -432,7 +476,9 @@
if (!vm.mInstanceFilePath.exists()) {
throw new VirtualMachineException("instance image missing");
}
-
+ if (config.isEncryptedStorageEnabled() && !vm.mEncryptedStoreFilePath.exists()) {
+ throw new VirtualMachineException("Storage image missing");
+ }
return vm;
}
@@ -681,8 +727,12 @@
// Re-open idsig file in read-only mode
appConfig.idsig = ParcelFileDescriptor.open(mIdsigFilePath, MODE_READ_ONLY);
- appConfig.instanceImage = ParcelFileDescriptor.open(mInstanceFilePath,
- MODE_READ_WRITE);
+ appConfig.instanceImage =
+ ParcelFileDescriptor.open(mInstanceFilePath, MODE_READ_WRITE);
+ if (mEncryptedStoreFilePath != null) {
+ appConfig.encryptedStorageImage =
+ ParcelFileDescriptor.open(mEncryptedStoreFilePath, MODE_READ_WRITE);
+ }
List<ParcelFileDescriptor> extraIdsigs = new ArrayList<>();
for (ExtraApkSpec extraApk : mExtraApks) {
extraIdsigs.add(ParcelFileDescriptor.open(extraApk.idsig, MODE_READ_ONLY));
@@ -1017,7 +1067,10 @@
try {
return new VirtualMachineDescriptor(
ParcelFileDescriptor.open(mConfigFilePath, MODE_READ_ONLY),
- ParcelFileDescriptor.open(mInstanceFilePath, MODE_READ_ONLY));
+ ParcelFileDescriptor.open(mInstanceFilePath, MODE_READ_ONLY),
+ mEncryptedStoreFilePath != null
+ ? ParcelFileDescriptor.open(mEncryptedStoreFilePath, MODE_READ_ONLY)
+ : null);
} catch (IOException e) {
throw new VirtualMachineException(e);
}
@@ -1183,4 +1236,14 @@
throw new VirtualMachineException("failed to transfer instance image", e);
}
}
+
+ private void importEncryptedStoreFrom(@NonNull ParcelFileDescriptor encryptedStoreFd)
+ throws VirtualMachineException {
+ try (FileChannel storeOutput = new FileOutputStream(mEncryptedStoreFilePath).getChannel();
+ FileChannel storeInput = new AutoCloseInputStream(encryptedStoreFd).getChannel()) {
+ storeOutput.transferFrom(storeInput, /*position=*/ 0, storeInput.size());
+ } catch (IOException e) {
+ throw new VirtualMachineException("failed to transfer encryptedstore image", e);
+ }
+ }
}
diff --git a/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java b/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java
index a9e062a..459b614 100644
--- a/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java
+++ b/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java
@@ -65,6 +65,7 @@
private static final String KEY_PROTECTED_VM = "protectedVm";
private static final String KEY_MEMORY_MIB = "memoryMib";
private static final String KEY_NUM_CPUS = "numCpus";
+ private static final String KEY_ENCRYPTED_STORAGE_KIB = "encryptedStorageKib";
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@@ -120,6 +121,9 @@
*/
@Nullable private final String mPayloadBinaryPath;
+ /** The size of storage in KB. 0 indicates that encryptedStorage is not required */
+ private final long mEncryptedStorageKib;
+
private VirtualMachineConfig(
@NonNull String apkPath,
@Nullable String payloadConfigPath,
@@ -127,7 +131,8 @@
@DebugLevel int debugLevel,
boolean protectedVm,
int memoryMib,
- int numCpus) {
+ int numCpus,
+ long encryptedStorageKib) {
requireNonNull(apkPath);
if (!apkPath.startsWith("/")) {
throw new IllegalArgumentException("APK path must be an absolute path");
@@ -167,6 +172,9 @@
throw new UnsupportedOperationException(
"Unprotected VMs are not supported on this device.");
}
+ if (encryptedStorageKib < 0) {
+ throw new IllegalArgumentException("Encrypted Storage size cannot be negative");
+ }
mApkPath = apkPath;
mPayloadConfigPath = payloadConfigPath;
@@ -175,6 +183,7 @@
mProtectedVm = protectedVm;
mMemoryMib = memoryMib;
mNumCpus = numCpus;
+ mEncryptedStorageKib = encryptedStorageKib;
}
/** Loads a config from a file. */
@@ -226,9 +235,17 @@
boolean protectedVm = b.getBoolean(KEY_PROTECTED_VM);
int memoryMib = b.getInt(KEY_MEMORY_MIB);
int numCpus = b.getInt(KEY_NUM_CPUS);
+ long encryptedStorageKib = b.getLong(KEY_ENCRYPTED_STORAGE_KIB);
- return new VirtualMachineConfig(apkPath, payloadConfigPath, payloadBinaryPath, debugLevel,
- protectedVm, memoryMib, numCpus);
+ return new VirtualMachineConfig(
+ apkPath,
+ payloadConfigPath,
+ payloadBinaryPath,
+ debugLevel,
+ protectedVm,
+ memoryMib,
+ numCpus,
+ encryptedStorageKib);
}
/** Persists this config to a file. */
@@ -253,6 +270,9 @@
if (mMemoryMib > 0) {
b.putInt(KEY_MEMORY_MIB, mMemoryMib);
}
+ if (mEncryptedStorageKib > 0) {
+ b.putLong(KEY_ENCRYPTED_STORAGE_KIB, mEncryptedStorageKib);
+ }
b.writeToStream(output);
}
@@ -337,6 +357,28 @@
}
/**
+ * Returns whether encrypted storage is enabled or not.
+ *
+ * @hide
+ */
+ @SystemApi
+ public boolean isEncryptedStorageEnabled() {
+ return mEncryptedStorageKib > 0;
+ }
+
+ /**
+ * Returns the size of encrypted storage (in KB) available in the VM, or 0 if encrypted storage
+ * is not enabled
+ *
+ * @hide
+ */
+ @SystemApi
+ @IntRange(from = 0)
+ public long getEncryptedStorageKib() {
+ return mEncryptedStorageKib;
+ }
+
+ /**
* Tests if this config is compatible with other config. Being compatible means that the configs
* can be interchangeably used for the same virtual machine. Compatible changes includes the
* number of CPUs and the size of the RAM. All other changes (e.g. using a different payload,
@@ -348,6 +390,7 @@
public boolean isCompatibleWith(@NonNull VirtualMachineConfig other) {
return this.mDebugLevel == other.mDebugLevel
&& this.mProtectedVm == other.mProtectedVm
+ && this.mEncryptedStorageKib == other.mEncryptedStorageKib
&& Objects.equals(this.mPayloadConfigPath, other.mPayloadConfigPath)
&& Objects.equals(this.mPayloadBinaryPath, other.mPayloadBinaryPath)
&& this.mApkPath.equals(other.mApkPath);
@@ -405,6 +448,7 @@
private boolean mProtectedVmSet;
private int mMemoryMib;
private int mNumCpus;
+ private long mEncryptedStorageKib;
/**
* Creates a builder for the given context.
@@ -416,6 +460,7 @@
mContext = requireNonNull(context, "context must not be null");
mDebugLevel = DEBUG_LEVEL_NONE;
mNumCpus = 1;
+ mEncryptedStorageKib = 0;
}
/**
@@ -433,8 +478,14 @@
}
return new VirtualMachineConfig(
- apkPath, mPayloadConfigPath, mPayloadBinaryPath, mDebugLevel, mProtectedVm,
- mMemoryMib, mNumCpus);
+ apkPath,
+ mPayloadConfigPath,
+ mPayloadBinaryPath,
+ mDebugLevel,
+ mProtectedVm,
+ mMemoryMib,
+ mNumCpus,
+ mEncryptedStorageKib);
}
/**
@@ -530,5 +581,27 @@
mNumCpus = num;
return this;
}
+
+ /**
+ * Sets the size (in KB) of encrypted storage available to the VM.
+ *
+ * <p>The storage is encrypted with a key deterministically derived from the VM identity
+ *
+ * <p>The encrypted storage is persistent across VM reboots as well as device reboots. The
+ * backing file (containing encrypted data) is stored in the app's private data directory.
+ *
+ * <p>Note - There is no integrity guarantee or rollback protection on the storage in case
+ * the encrypted data is modified.
+ *
+ * <p>Deleting the VM will delete the encrypted data - there is no way to recover that data.
+ *
+ * @hide
+ */
+ @SystemApi
+ @NonNull
+ public Builder setEncryptedStorageKib(@IntRange(from = 0) long encryptedStorageKib) {
+ mEncryptedStorageKib = encryptedStorageKib;
+ return this;
+ }
}
}
diff --git a/javalib/src/android/system/virtualmachine/VirtualMachineDescriptor.java b/javalib/src/android/system/virtualmachine/VirtualMachineDescriptor.java
index edaf5b4..c9718aa 100644
--- a/javalib/src/android/system/virtualmachine/VirtualMachineDescriptor.java
+++ b/javalib/src/android/system/virtualmachine/VirtualMachineDescriptor.java
@@ -19,6 +19,7 @@
import static java.util.Objects.requireNonNull;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
@@ -37,7 +38,9 @@
public final class VirtualMachineDescriptor implements Parcelable {
@NonNull private final ParcelFileDescriptor mConfigFd;
@NonNull private final ParcelFileDescriptor mInstanceImgFd;
- // TODO(b/243129654): Add trusted storage fd once it is available.
+ // File descriptor of the image backing the encrypted storage - Will be null if encrypted
+ // storage is not enabled. */
+ @Nullable private final ParcelFileDescriptor mEncryptedStoreFd;
@Override
public int describeContents() {
@@ -48,6 +51,7 @@
public void writeToParcel(@NonNull Parcel out, int flags) {
mConfigFd.writeToParcel(out, flags);
mInstanceImgFd.writeToParcel(out, flags);
+ if (mEncryptedStoreFd != null) mEncryptedStoreFd.writeToParcel(out, flags);
}
@NonNull
@@ -78,14 +82,27 @@
return mInstanceImgFd;
}
+ /**
+ * @return File descriptor of image backing the encrypted storage.
+ * <p>This method will return null if encrypted storage is not enabled.
+ */
+ @Nullable
+ ParcelFileDescriptor getEncryptedStoreFd() {
+ return mEncryptedStoreFd;
+ }
+
VirtualMachineDescriptor(
- @NonNull ParcelFileDescriptor configFd, @NonNull ParcelFileDescriptor instanceImgFd) {
+ @NonNull ParcelFileDescriptor configFd,
+ @NonNull ParcelFileDescriptor instanceImgFd,
+ @Nullable ParcelFileDescriptor encryptedStoreFd) {
mConfigFd = configFd;
mInstanceImgFd = instanceImgFd;
+ mEncryptedStoreFd = encryptedStoreFd;
}
private VirtualMachineDescriptor(Parcel in) {
mConfigFd = requireNonNull(in.readFileDescriptor());
mInstanceImgFd = requireNonNull(in.readFileDescriptor());
+ mEncryptedStoreFd = in.readFileDescriptor();
}
}
diff --git a/microdroid/Android.bp b/microdroid/Android.bp
index 028ac1f..2669a32 100644
--- a/microdroid/Android.bp
+++ b/microdroid/Android.bp
@@ -83,7 +83,7 @@
"microdroid_manifest",
"microdroid_plat_sepolicy_and_mapping.sha256",
"microdroid_property_contexts",
- "mke2fs",
+ "mke2fs.microdroid",
// TODO(b/195425111) these should be added automatically
"libcrypto", // used by many (init_second_stage, microdroid_manager, toybox, etc)
diff --git a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
index 8b0d6d2..2cd4e51 100644
--- a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
+++ b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
@@ -264,8 +264,9 @@
@Test
@CddTest(requirements = {"9.17/C-1-1"})
public void vmConfigUnitTests() {
- VirtualMachineConfig minimal =
- newVmConfigBuilder().setPayloadBinaryPath("binary/path").build();
+
+ VirtualMachineConfig.Builder minimalBuilder = newVmConfigBuilder();
+ VirtualMachineConfig minimal = minimalBuilder.setPayloadBinaryPath("binary/path").build();
assertThat(minimal.getApkPath()).isEqualTo(getContext().getPackageCodePath());
assertThat(minimal.getDebugLevel()).isEqualTo(DEBUG_LEVEL_NONE);
@@ -274,6 +275,8 @@
assertThat(minimal.getPayloadBinaryPath()).isEqualTo("binary/path");
assertThat(minimal.getPayloadConfigPath()).isNull();
assertThat(minimal.isProtectedVm()).isEqualTo(isProtectedVm());
+ assertThat(minimal.isEncryptedStorageEnabled()).isFalse();
+ assertThat(minimal.getEncryptedStorageKib()).isEqualTo(0);
int maxCpus = Runtime.getRuntime().availableProcessors();
VirtualMachineConfig.Builder maximalBuilder =
@@ -282,7 +285,8 @@
.setApkPath("/apk/path")
.setNumCpus(maxCpus)
.setDebugLevel(DEBUG_LEVEL_FULL)
- .setMemoryMib(42);
+ .setMemoryMib(42)
+ .setEncryptedStorageKib(1024);
VirtualMachineConfig maximal = maximalBuilder.build();
assertThat(maximal.getApkPath()).isEqualTo("/apk/path");
@@ -292,6 +296,8 @@
assertThat(maximal.getPayloadBinaryPath()).isNull();
assertThat(maximal.getPayloadConfigPath()).isEqualTo("config/path");
assertThat(maximal.isProtectedVm()).isEqualTo(isProtectedVm());
+ assertThat(maximal.isEncryptedStorageEnabled()).isTrue();
+ assertThat(maximal.getEncryptedStorageKib()).isEqualTo(1024);
assertThat(minimal.isCompatibleWith(maximal)).isFalse();
assertThat(minimal.isCompatibleWith(minimal)).isTrue();
@@ -299,6 +305,10 @@
VirtualMachineConfig compatible = maximalBuilder.setNumCpus(1).setMemoryMib(99).build();
assertThat(compatible.isCompatibleWith(maximal)).isTrue();
+
+ // Assert that different encrypted storage size would imply the configs are incompatible
+ VirtualMachineConfig incompatible = minimalBuilder.setEncryptedStorageKib(1048).build();
+ assertThat(incompatible.isCompatibleWith(minimal)).isFalse();
}
@Test
@@ -927,13 +937,28 @@
}
@Test
- public void importedVmIsEqualToTheOriginalVm() throws Exception {
+ @CddTest(requirements = {"9.17/C-1-1", "9.17/C-2-1"})
+ public void importedVmIsEqualToTheOriginalVm_WithoutStorage() throws Exception {
+ TestResults testResults = importedVmIsEqualToTheOriginalVm(false);
+ assertThat(testResults.mEncryptedStoragePath).isEqualTo("");
+ }
+
+ @Test
+ @CddTest(requirements = {"9.17/C-1-1", "9.17/C-2-1"})
+ public void importedVmIsEqualToTheOriginalVm_WithStorage() throws Exception {
+ TestResults testResults = importedVmIsEqualToTheOriginalVm(true);
+ assertThat(testResults.mEncryptedStoragePath).isEqualTo("/mnt/encryptedstore");
+ }
+
+ private TestResults importedVmIsEqualToTheOriginalVm(boolean encryptedStoreEnabled)
+ throws Exception {
// Arrange
- VirtualMachineConfig config =
+ VirtualMachineConfig.Builder builder =
newVmConfigBuilder()
.setPayloadBinaryPath("MicrodroidTestNativeLib.so")
- .setDebugLevel(DEBUG_LEVEL_FULL)
- .build();
+ .setDebugLevel(DEBUG_LEVEL_FULL);
+ if (encryptedStoreEnabled) builder = builder.setEncryptedStorageKib(4096);
+ VirtualMachineConfig config = builder.build();
String vmNameOrig = "test_vm_orig";
String vmNameImport = "test_vm_import";
VirtualMachine vmOrig = forceCreateNewVirtualMachine(vmNameOrig, config);
@@ -953,12 +978,34 @@
// Asserts
assertFileContentsAreEqualInTwoVms("config.xml", vmNameOrig, vmNameImport);
assertFileContentsAreEqualInTwoVms("instance.img", vmNameOrig, vmNameImport);
+ if (encryptedStoreEnabled) {
+ assertFileContentsAreEqualInTwoVms("storage.img", vmNameOrig, vmNameImport);
+ }
assertThat(vmImport).isNotEqualTo(vmOrig);
vmm.delete(vmNameOrig);
assertThat(vmImport).isEqualTo(vmm.get(vmNameImport));
TestResults testResults = runVmTestService(vmImport);
assertThat(testResults.mException).isNull();
assertThat(testResults.mAddInteger).isEqualTo(123 + 456);
+ return testResults;
+ }
+
+ @Test
+ @CddTest(requirements = {"9.17/C-1-1", "9.17/C-2-1"})
+ public void encryptedStorageAvailable() throws Exception {
+ assumeSupportedKernel();
+
+ VirtualMachineConfig config =
+ newVmConfigBuilder()
+ .setPayloadBinaryPath("MicrodroidTestNativeLib.so")
+ .setMemoryMib(minMemoryRequired())
+ .setEncryptedStorageKib(4096)
+ .setDebugLevel(DEBUG_LEVEL_FULL)
+ .build();
+ VirtualMachine vm = forceCreateNewVirtualMachine("test_vm", config);
+
+ TestResults testResults = runVmTestService(vm);
+ assertThat(testResults.mEncryptedStoragePath).isEqualTo("/mnt/encryptedstore");
}
private void assertFileContentsAreEqualInTwoVms(String fileName, String vmName1, String vmName2)
diff --git a/virtualizationservice/src/aidl.rs b/virtualizationservice/src/aidl.rs
index 7d24a32..3e4323d 100644
--- a/virtualizationservice/src/aidl.rs
+++ b/virtualizationservice/src/aidl.rs
@@ -881,8 +881,9 @@
// Return whether a partition is exempt from selinux label checks, because we know that it does
// not contain code and is likely to be generated in an app-writable directory.
fn is_safe_app_partition(label: &str) -> bool {
- // See make_payload_disk in payload.rs.
+ // See add_microdroid_system_images & add_microdroid_payload_images in payload.rs.
label == "vm-instance"
+ || label == "encryptedstore"
|| label == "microdroid-apk-idsig"
|| label == "payload-metadata"
|| label.starts_with("extra-idsig-")
@@ -898,7 +899,7 @@
match ctx.selinux_type()? {
| "system_file" // immutable dm-verity protected partition
| "apk_data_file" // APKs of an installed app
- | "staging_data_file" // updated/staged APEX imagess
+ | "staging_data_file" // updated/staged APEX images
| "shell_data_file" // test files created via adb shell
=> Ok(()),
_ => bail!("Label {} is not allowed", ctx),