Merge "Update kernel to builds 9170280"
diff --git a/authfs/tests/java/src/com/android/fs/AuthFsHostTest.java b/authfs/tests/java/src/com/android/fs/AuthFsHostTest.java
index 0eb1257..2deb490 100644
--- a/authfs/tests/java/src/com/android/fs/AuthFsHostTest.java
+++ b/authfs/tests/java/src/com/android/fs/AuthFsHostTest.java
@@ -65,8 +65,6 @@
private static final String DIGEST_4M =
"sha256-f18a268d565348fb4bbf11f10480b198f98f2922eb711de149857b3cecf98a8d";
- private static final int VMADDR_CID_HOST = 2;
-
private static CommandRunner sAndroid;
private static CommandRunner sMicrodroid;
@@ -91,10 +89,7 @@
runFdServerOnAndroid(
"--open-ro 3:input.4m --open-ro 4:input.4m.fsv_meta --open-ro 6:input.4m",
"--ro-fds 3:4 --ro-fds 6");
-
- runAuthFsOnMicrodroid(
- "--remote-ro-file-unverified 6 --remote-ro-file 3:" + DIGEST_4M + " --cid "
- + VMADDR_CID_HOST);
+ runAuthFsOnMicrodroid("--remote-ro-file-unverified 6 --remote-ro-file 3:" + DIGEST_4M);
// Action
String actualHashUnverified4m = computeFileHash(sMicrodroid, MOUNT_DIR + "/6");
@@ -117,8 +112,7 @@
+ " 6:input.4k1 --open-ro 7:input.4k1.fsv_meta",
"--ro-fds 3:4 --ro-fds 6:7");
runAuthFsOnMicrodroid(
- "--remote-ro-file 3:" + DIGEST_4K + " --remote-ro-file 6:" + DIGEST_4K1 + " --cid "
- + VMADDR_CID_HOST);
+ "--remote-ro-file 3:" + DIGEST_4K + " --remote-ro-file 6:" + DIGEST_4K1);
// Action
String actualHash4k = computeFileHash(sMicrodroid, MOUNT_DIR + "/3");
@@ -138,7 +132,7 @@
runFdServerOnAndroid(
"--open-ro 3:input.4m --open-ro 4:input.4m.fsv_meta.bad_merkle",
"--ro-fds 3:4");
- runAuthFsOnMicrodroid("--remote-ro-file 3:" + DIGEST_4M + " --cid " + VMADDR_CID_HOST);
+ runAuthFsOnMicrodroid("--remote-ro-file 3:" + DIGEST_4M);
// Verify
assertThat(copyFile(sMicrodroid, MOUNT_DIR + "/3", "/dev/null")).isFailed();
@@ -150,8 +144,7 @@
runFdServerOnAndroid("--open-ro 3:input.apk", "--ro-fds 3");
String expectedDigest = sAndroid.run(
FSVERITY_BIN + " digest --compact " + TEST_DIR + "/input.apk");
- runAuthFsOnMicrodroid(
- "--remote-ro-file 3:sha256-" + expectedDigest + " --cid " + VMADDR_CID_HOST);
+ runAuthFsOnMicrodroid("--remote-ro-file 3:sha256-" + expectedDigest);
// Action
String actualHash = computeFileHash(sMicrodroid, MOUNT_DIR + "/3");
@@ -165,7 +158,7 @@
public void testWriteThroughCorrectly() throws Exception {
// Setup
runFdServerOnAndroid("--open-rw 3:" + TEST_OUTPUT_DIR + "/out.file", "--rw-fds 3");
- runAuthFsOnMicrodroid("--remote-new-rw-file 3 --cid " + VMADDR_CID_HOST);
+ runAuthFsOnMicrodroid("--remote-new-rw-file 3");
// Action
String srcPath = "/system/bin/linker64";
@@ -182,7 +175,7 @@
public void testWriteFailedIfDetectsTampering() throws Exception {
// Setup
runFdServerOnAndroid("--open-rw 3:" + TEST_OUTPUT_DIR + "/out.file", "--rw-fds 3");
- runAuthFsOnMicrodroid("--remote-new-rw-file 3 --cid " + VMADDR_CID_HOST);
+ runAuthFsOnMicrodroid("--remote-new-rw-file 3");
String srcPath = "/system/bin/linker64";
String destPath = MOUNT_DIR + "/3";
@@ -223,7 +216,7 @@
public void testReadFailedIfDetectsTampering() throws Exception {
// Setup
runFdServerOnAndroid("--open-rw 3:" + TEST_OUTPUT_DIR + "/out.file", "--rw-fds 3");
- runAuthFsOnMicrodroid("--remote-new-rw-file 3 --cid " + VMADDR_CID_HOST);
+ runAuthFsOnMicrodroid("--remote-new-rw-file 3");
String srcPath = "/system/bin/linker64";
String destPath = MOUNT_DIR + "/3";
@@ -251,7 +244,7 @@
public void testResizeFailedIfDetectsTampering() throws Exception {
// Setup
runFdServerOnAndroid("--open-rw 3:" + TEST_OUTPUT_DIR + "/out.file", "--rw-fds 3");
- runAuthFsOnMicrodroid("--remote-new-rw-file 3 --cid " + VMADDR_CID_HOST);
+ runAuthFsOnMicrodroid("--remote-new-rw-file 3");
String outputPath = MOUNT_DIR + "/3";
String backendPath = TEST_OUTPUT_DIR + "/out.file";
@@ -275,7 +268,7 @@
public void testFileResize() throws Exception {
// Setup
runFdServerOnAndroid("--open-rw 3:" + TEST_OUTPUT_DIR + "/out.file", "--rw-fds 3");
- runAuthFsOnMicrodroid("--remote-new-rw-file 3 --cid " + VMADDR_CID_HOST);
+ runAuthFsOnMicrodroid("--remote-new-rw-file 3");
String outputPath = MOUNT_DIR + "/3";
String backendPath = TEST_OUTPUT_DIR + "/out.file";
@@ -309,7 +302,7 @@
String authfsOutputDir = MOUNT_DIR + "/3";
sAndroid.run("mkdir " + androidOutputDir);
runFdServerOnAndroid("--open-dir 3:" + androidOutputDir, "--rw-dirs 3");
- runAuthFsOnMicrodroid("--remote-new-rw-dir 3 --cid " + VMADDR_CID_HOST);
+ runAuthFsOnMicrodroid("--remote-new-rw-dir 3");
// Action & Verify
// Can create a new file to write.
@@ -338,7 +331,7 @@
String authfsOutputDir = MOUNT_DIR + "/3";
sAndroid.run("mkdir " + androidOutputDir);
runFdServerOnAndroid("--open-dir 3:" + androidOutputDir, "--rw-dirs 3");
- runAuthFsOnMicrodroid("--remote-new-rw-dir 3 --cid " + VMADDR_CID_HOST);
+ runAuthFsOnMicrodroid("--remote-new-rw-dir 3");
// Action
// Can create nested directories and can create a file in one.
@@ -372,7 +365,7 @@
String authfsOutputDir = MOUNT_DIR + "/3";
sAndroid.run("mkdir " + androidOutputDir);
runFdServerOnAndroid("--open-dir 3:" + androidOutputDir, "--rw-dirs 3");
- runAuthFsOnMicrodroid("--remote-new-rw-dir 3 --cid " + VMADDR_CID_HOST);
+ runAuthFsOnMicrodroid("--remote-new-rw-dir 3");
// Action & Verify
sMicrodroid.run("echo -n foo > " + authfsOutputDir + "/file");
@@ -393,7 +386,7 @@
String authfsOutputDir = MOUNT_DIR + "/3";
sAndroid.run("mkdir " + androidOutputDir);
runFdServerOnAndroid("--open-dir 3:" + androidOutputDir, "--rw-dirs 3");
- runAuthFsOnMicrodroid("--remote-new-rw-dir 3 --cid " + VMADDR_CID_HOST);
+ runAuthFsOnMicrodroid("--remote-new-rw-dir 3");
sMicrodroid.run("echo -n foo > " + authfsOutputDir + "/file");
sMicrodroid.run("test -f " + authfsOutputDir + "/file");
@@ -412,7 +405,7 @@
String authfsOutputDir = MOUNT_DIR + "/3";
sAndroid.run("mkdir " + androidOutputDir);
runFdServerOnAndroid("--open-dir 3:" + androidOutputDir, "--rw-dirs 3");
- runAuthFsOnMicrodroid("--remote-new-rw-dir 3 --cid " + VMADDR_CID_HOST);
+ runAuthFsOnMicrodroid("--remote-new-rw-dir 3");
sMicrodroid.run("mkdir -p " + authfsOutputDir + "/dir/dir2");
sMicrodroid.run("echo -n foo > " + authfsOutputDir + "/dir/file");
@@ -438,7 +431,7 @@
String authfsOutputDir = MOUNT_DIR + "/3";
sAndroid.run("mkdir " + androidOutputDir);
runFdServerOnAndroid("--open-dir 3:" + androidOutputDir, "--rw-dirs 3");
- runAuthFsOnMicrodroid("--remote-new-rw-dir 3 --cid " + VMADDR_CID_HOST);
+ runAuthFsOnMicrodroid("--remote-new-rw-dir 3");
sMicrodroid.run("touch " + authfsOutputDir + "/some_file");
sMicrodroid.run("mkdir " + authfsOutputDir + "/some_dir");
@@ -462,7 +455,7 @@
String androidOutputDir = TEST_OUTPUT_DIR + "/dir";
sAndroid.run("mkdir " + androidOutputDir);
runFdServerOnAndroid("--open-dir 3:" + androidOutputDir, "--rw-dirs 3");
- runAuthFsOnMicrodroid("--remote-new-rw-dir 3 --cid " + VMADDR_CID_HOST);
+ runAuthFsOnMicrodroid("--remote-new-rw-dir 3");
// Create a file with some data. Test the existence.
String outputPath = authfsOutputDir + "/out";
@@ -494,8 +487,7 @@
// Setup
String authfsInputDir = MOUNT_DIR + "/3";
runFdServerOnAndroid("--open-dir 3:" + TEST_DIR, "--ro-dirs 3");
- runAuthFsOnMicrodroid("--remote-ro-dir 3:" + INPUT_MANIFEST_PATH + ": --cid "
- + VMADDR_CID_HOST);
+ runAuthFsOnMicrodroid("--remote-ro-dir 3:" + INPUT_MANIFEST_PATH + ":");
// Action
String actualHash = computeFileHash(sMicrodroid, authfsInputDir + "/input.4m");
@@ -510,8 +502,7 @@
// Setup
String authfsInputDir = MOUNT_DIR + "/3";
runFdServerOnAndroid("--open-dir 3:" + TEST_DIR, "--ro-dirs 3");
- runAuthFsOnMicrodroid("--remote-ro-dir 3:" + INPUT_MANIFEST_PATH + ": --cid "
- + VMADDR_CID_HOST);
+ runAuthFsOnMicrodroid("--remote-ro-dir 3:" + INPUT_MANIFEST_PATH + ":");
// Verify
sMicrodroid.run("test -f " + authfsInputDir + "/input.4k");
@@ -523,7 +514,7 @@
public void testReadOutputDirectory() throws Exception {
// Setup
runFdServerOnAndroid("--open-dir 3:" + TEST_OUTPUT_DIR, "--rw-dirs 3");
- runAuthFsOnMicrodroid("--remote-new-rw-dir 3 --cid " + VMADDR_CID_HOST);
+ runAuthFsOnMicrodroid("--remote-new-rw-dir 3");
// Action
String authfsOutputDir = MOUNT_DIR + "/3";
@@ -564,7 +555,7 @@
public void testChmod_File() throws Exception {
// Setup
runFdServerOnAndroid("--open-rw 3:" + TEST_OUTPUT_DIR + "/file", "--rw-fds 3");
- runAuthFsOnMicrodroid("--remote-new-rw-file 3 --cid " + VMADDR_CID_HOST);
+ runAuthFsOnMicrodroid("--remote-new-rw-file 3");
// Action & Verify
// Change mode
@@ -579,7 +570,7 @@
public void testChmod_Dir() throws Exception {
// Setup
runFdServerOnAndroid("--open-dir 3:" + TEST_OUTPUT_DIR, "--rw-dirs 3");
- runAuthFsOnMicrodroid("--remote-new-rw-dir 3 --cid " + VMADDR_CID_HOST);
+ runAuthFsOnMicrodroid("--remote-new-rw-dir 3");
// Action & Verify
String authfsOutputDir = MOUNT_DIR + "/3";
@@ -603,7 +594,7 @@
public void testChmod_FileInOutputDirectory() throws Exception {
// Setup
runFdServerOnAndroid("--open-dir 3:" + TEST_OUTPUT_DIR, "--rw-dirs 3");
- runAuthFsOnMicrodroid("--remote-new-rw-dir 3 --cid " + VMADDR_CID_HOST);
+ runAuthFsOnMicrodroid("--remote-new-rw-dir 3");
// Action & Verify
String authfsOutputDir = MOUNT_DIR + "/3";
@@ -626,7 +617,7 @@
public void testStatfs() throws Exception {
// Setup
runFdServerOnAndroid("--open-dir 3:" + TEST_OUTPUT_DIR, "--rw-dirs 3");
- runAuthFsOnMicrodroid("--remote-new-rw-dir 3 --cid " + VMADDR_CID_HOST);
+ runAuthFsOnMicrodroid("--remote-new-rw-dir 3");
// Verify
// Magic matches. Has only 2 inodes (root and "/3").
diff --git a/authfs/tests/java/src/com/android/fs/AuthFsTestRule.java b/authfs/tests/java/src/com/android/fs/AuthFsTestRule.java
index e6081f7..48c6b22 100644
--- a/authfs/tests/java/src/com/android/fs/AuthFsTestRule.java
+++ b/authfs/tests/java/src/com/android/fs/AuthFsTestRule.java
@@ -82,6 +82,8 @@
/** Plenty of time for authfs to get ready */
private static final int AUTHFS_INIT_TIMEOUT_MS = 3000;
+ private static final int VMADDR_CID_HOST = 2;
+
private static TestInformation sTestInfo;
private static CommandRunner sAndroid;
private static CommandRunner sMicrodroid;
@@ -177,7 +179,7 @@
}
void runAuthFsOnMicrodroid(String flags) {
- String cmd = AUTHFS_BIN + " " + MOUNT_DIR + " " + flags;
+ String cmd = AUTHFS_BIN + " " + MOUNT_DIR + " " + flags + " --cid " + VMADDR_CID_HOST;
AtomicBoolean starting = new AtomicBoolean(true);
Future<?> unusedFuture =
diff --git a/avmd/Android.bp b/avmd/Android.bp
index 6d91b59..0b87a7b 100644
--- a/avmd/Android.bp
+++ b/avmd/Android.bp
@@ -9,8 +9,8 @@
srcs: ["src/lib.rs"],
prefer_rlib: true,
rustlibs: [
+ "libhex",
"libserde",
- "libapexutil_rust", // TODO(b/239413416): Remove this after adding hex
"libapkverify",
],
}
diff --git a/avmd/src/avmd.rs b/avmd/src/avmd.rs
index 05fc201..cb02f39 100644
--- a/avmd/src/avmd.rs
+++ b/avmd/src/avmd.rs
@@ -18,7 +18,6 @@
string::{String, ToString},
vec::Vec,
};
-use apexutil::to_hex_string;
use apkverify::SignatureAlgorithmID;
use core::fmt;
use serde::{Deserialize, Serialize};
@@ -106,7 +105,7 @@
writeln!(f, " VBMeta descriptor:")?;
writeln!(f, " namespace: {}", self.resource.namespace)?;
writeln!(f, " name: {}", self.resource.name)?;
- writeln!(f, " vbmeta digest: {}", to_hex_string(&self.vbmeta_digest))?;
+ writeln!(f, " vbmeta digest: {}", hex::encode(&self.vbmeta_digest))?;
Ok(())
}
}
@@ -132,7 +131,7 @@
writeln!(f, " namespace: {}", self.resource.namespace)?;
writeln!(f, " name: {}", self.resource.name)?;
writeln!(f, " Signing algorithm ID: {:#04x}", self.signature_algorithm_id.to_u32())?;
- writeln!(f, " APK digest: {}", to_hex_string(&self.apk_digest))?;
+ writeln!(f, " APK digest: {}", hex::encode(&self.apk_digest))?;
Ok(())
}
}
diff --git a/libs/apexutil/Android.bp b/libs/apexutil/Android.bp
index 3bdfc5f..4a4a673 100644
--- a/libs/apexutil/Android.bp
+++ b/libs/apexutil/Android.bp
@@ -27,6 +27,9 @@
prefer_rlib: true,
test_suites: ["general-tests"],
data: ["tests/data/*"],
+ rustlibs: [
+ "libhex",
+ ],
target: {
host: {
// TODO(b/204562227): remove once the build does this automatically
diff --git a/libs/apexutil/src/lib.rs b/libs/apexutil/src/lib.rs
index 999f16d..698d93a 100644
--- a/libs/apexutil/src/lib.rs
+++ b/libs/apexutil/src/lib.rs
@@ -101,11 +101,6 @@
Ok(vbmeta.hash().ok_or(ApexVerificationError::ApexPubkeyMistmatch)?.to_vec())
}
-/// Converts the buffer to a Hex String
-pub fn to_hex_string(buf: &[u8]) -> String {
- buf.iter().map(|b| format!("{:02x}", b)).collect()
-}
-
fn get_public_key_and_image_info(apex_file: &File) -> Result<(Vec<u8>, u64, u64), ApexParseError> {
let mut z = ZipArchive::new(apex_file).map_err(|err| match err {
ZipError::Io(err) => ApexParseError::Io(err),
@@ -149,7 +144,7 @@
let res = verify("tests/data/test.apex").unwrap();
// The expected hex is generated when we ran the method the first time.
assert_eq!(
- to_hex_string(&res.root_digest),
+ hex::encode(&res.root_digest),
"fe11ab17da0a3a738b54bdc3a13f6139cbdf91ec32f001f8d4bbbf8938e04e39"
);
}
@@ -158,7 +153,7 @@
fn payload_vbmeta_has_valid_image_hash() {
let result = get_payload_vbmeta_image_hash("tests/data/test.apex").unwrap();
assert_eq!(
- to_hex_string(&result),
+ hex::encode(&result),
"296e32a76544de9da01713e471403ab4667705ad527bb4f1fac0cf61e7ce122d"
);
}
diff --git a/libs/dice/Android.bp b/libs/dice/Android.bp
new file mode 100644
index 0000000..7cb68a5
--- /dev/null
+++ b/libs/dice/Android.bp
@@ -0,0 +1,23 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+rust_library_rlib {
+ name: "libdice_nostd",
+ crate_name: "dice",
+ srcs: ["src/lib.rs"],
+ edition: "2021",
+ no_stdlibs: true,
+ prefer_rlib: true,
+ stdlibs: ["libcore.rust_sysroot"],
+ rustlibs: [
+ "libopen_dice_cbor_bindgen",
+ "libopen_dice_bcc_bindgen",
+ ],
+ whole_static_libs: [
+ "libopen_dice_bcc",
+ "libopen_dice_cbor",
+ "libcrypto_baremetal",
+ ],
+ apex_available: ["com.android.virt"],
+}
diff --git a/libs/dice/src/lib.rs b/libs/dice/src/lib.rs
new file mode 100644
index 0000000..9e39436
--- /dev/null
+++ b/libs/dice/src/lib.rs
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//! Bare metal wrapper around libopen_dice.
+
+#![no_std]
+
+use core::fmt::{self, Debug};
+use open_dice_cbor_bindgen::{
+ DiceHash, DiceResult, DiceResult_kDiceResultBufferTooSmall as DICE_RESULT_BUFFER_TOO_SMALL,
+ DiceResult_kDiceResultInvalidInput as DICE_RESULT_INVALID_INPUT,
+ DiceResult_kDiceResultOk as DICE_RESULT_OK,
+ DiceResult_kDiceResultPlatformError as DICE_RESULT_PLATFORM_ERROR,
+};
+
+const HASH_SIZE: usize = open_dice_cbor_bindgen::DICE_HASH_SIZE as usize;
+
+/// Array type of hashes used by DICE.
+pub type Hash = [u8; HASH_SIZE];
+
+/// Error type used by DICE.
+pub enum Error {
+ /// Provided input was invalid.
+ InvalidInput,
+ /// Provided buffer was too small.
+ BufferTooSmall,
+ /// Unexpected platform error.
+ PlatformError,
+ /// Unexpected return value.
+ Unknown(DiceResult),
+}
+
+impl Debug for Error {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ Error::InvalidInput => write!(f, "invalid input"),
+ Error::BufferTooSmall => write!(f, "buffer too small"),
+ Error::PlatformError => write!(f, "platform error"),
+ Error::Unknown(n) => write!(f, "unknown error: {}", n),
+ }
+ }
+}
+
+fn check_call(ret: DiceResult) -> Result<(), Error> {
+ match ret {
+ DICE_RESULT_OK => Ok(()),
+ DICE_RESULT_INVALID_INPUT => Err(Error::InvalidInput),
+ DICE_RESULT_BUFFER_TOO_SMALL => Err(Error::BufferTooSmall),
+ DICE_RESULT_PLATFORM_ERROR => Err(Error::PlatformError),
+ n => Err(Error::Unknown(n)),
+ }
+}
+
+fn ctx() -> *mut core::ffi::c_void {
+ core::ptr::null_mut()
+}
+
+/// Hash the provided input using DICE's default hash function.
+pub fn hash(bytes: &[u8]) -> Result<Hash, Error> {
+ let mut output: Hash = [0; HASH_SIZE];
+ // SAFETY - DiceHash takes a sized input buffer and writes to a constant-sized output buffer.
+ check_call(unsafe { DiceHash(ctx(), bytes.as_ptr(), bytes.len(), output.as_mut_ptr()) })?;
+ Ok(output)
+}
diff --git a/microdroid/kernel/README.md b/microdroid/kernel/README.md
new file mode 100644
index 0000000..4c6a827
--- /dev/null
+++ b/microdroid/kernel/README.md
@@ -0,0 +1,59 @@
+# Microdroid kernel
+
+This directory contains prebuilt images of the Linux kernel that is used in
+Microdroid. The kernel is built from the same source tree as Generic Kernel
+Image (GKI), but with a different config where most of the config items are
+turned off to make the kernel fast & slim.
+
+## How to build the Microdroid kernels
+
+### Checkout the GKI source code.
+
+```bash
+repo init -u https://android.googlesource.com/kernel/manifest -b android14-5.15
+repo sync
+```
+
+### Build the Microdroid kernels manually
+
+For ARM64
+```bash
+FAST_BUILD=1 BUILD_CONFIG=common-modules/virtual-device/build.config.microdroid.aarch64 build/build.sh
+```
+
+For x86\_64,
+```bash
+FAST_BUILD=1 BUILD_CONFIG=common-modules/virtual-device/build.config.microdroid.x86_64 build/build.sh
+```
+
+Note that `FAST_BUILD=1` is not mandatory, but will make your build much faster.
+
+## How to update Microdroid kernel prebuilts
+
+### For manually built kernels (only for your own development)
+
+Copy the built kernel image to the Android source tree directly, and build the virt APEX.
+
+For ARM64,
+```bash
+cp out/android14-5.15/dist/Image <android_checkout>/packages/modules/Virtualization/microdroid/kernel/arm64/kernel-5.15
+```
+
+For x86\_64,
+```bash
+cp out/android14-5.15/dist/bzImage <android_checkout>/packages/modules/Virtualization/microdroid/kernel/arm64/kernel-5.15
+```
+
+### For official updates
+
+Use the `download_from_ci` script to automatically fetch the built images from
+a specific `<build_id>` and make commits with nice history in the message.
+
+```bash
+cd <android_checkout>/packages/modules/Virtualization
+repo start <topic_name>
+cd <kernel_checkout>
+ANDROID_BUILD_TOP=<android_checkout> ./build/kernel/gki/download_from_ci --update-microdroid -b <bug_id> <build_id>
+cd <android_checkout>/packages/modules/Virtualization
+repo upload .
+```
diff --git a/vmbase/entry.S b/vmbase/entry.S
index 490c2f3..75ab90b 100644
--- a/vmbase/entry.S
+++ b/vmbase/entry.S
@@ -73,6 +73,14 @@
.set .Lsctlrval, .L_SCTLR_ELx_M | .L_SCTLR_ELx_C | .L_SCTLR_ELx_SA | .L_SCTLR_EL1_ITD | .L_SCTLR_EL1_SED
.set .Lsctlrval, .Lsctlrval | .L_SCTLR_ELx_I | .L_SCTLR_EL1_SPAN | .L_SCTLR_EL1_RES1 | .L_SCTLR_EL1_WXN
+/* Bionic-compatible stack protector */
+.section .data.stack_protector, "aw"
+__bionic_tls:
+ .zero 40
+.global __stack_chk_guard
+__stack_chk_guard:
+ .quad 0x23d6d3f3c3b84098 /* TODO: randomize */
+
/**
* This is a generic entry point for an image. It carries out the operations required to prepare the
* loaded image to be run. Specifically, it zeroes the bss section using registers x25 and above,
@@ -150,6 +158,10 @@
adr x30, vector_table_el1
msr vbar_el1, x30
+ /* Set up Bionic-compatible thread-local storage. */
+ adr_l x30, __bionic_tls
+ msr tpidr_el0, x30
+
/* Call into Rust code. */
bl rust_entry
diff --git a/vmbase/example/Android.bp b/vmbase/example/Android.bp
index 4e62090..e9a3f98 100644
--- a/vmbase/example/Android.bp
+++ b/vmbase/example/Android.bp
@@ -11,6 +11,7 @@
rustlibs: [
"libaarch64_paging",
"libbuddy_system_allocator",
+ "libdice_nostd",
"liblog_rust_nostd",
"libvmbase",
],
diff --git a/vmbase/example/src/layout.rs b/vmbase/example/src/layout.rs
index 9cf1a69..463738e 100644
--- a/vmbase/example/src/layout.rs
+++ b/vmbase/example/src/layout.rs
@@ -15,6 +15,7 @@
//! Memory layout.
use aarch64_paging::paging::{MemoryRegion, VirtualAddress};
+use core::arch::asm;
use core::ops::Range;
use vmbase::println;
@@ -106,6 +107,21 @@
);
}
+/// Bionic-compatible thread-local storage entry, at the given offset from TPIDR_EL0.
+pub fn bionic_tls(off: usize) -> u64 {
+ let mut base: usize;
+ unsafe {
+ asm!("mrs {base}, tpidr_el0", base = out(reg) base);
+ let ptr = (base + off) as *const u64;
+ *ptr
+ }
+}
+
+/// Value of __stack_chk_guard.
+pub fn stack_chk_guard() -> u64 {
+ unsafe { __stack_chk_guard }
+}
+
extern "C" {
static dtb_begin: u8;
static dtb_end: u8;
@@ -120,4 +136,5 @@
static bss_end: u8;
static boot_stack_begin: u8;
static boot_stack_end: u8;
+ static __stack_chk_guard: u64;
}
diff --git a/vmbase/example/src/main.rs b/vmbase/example/src/main.rs
index 3c91f97..d6a966c 100644
--- a/vmbase/example/src/main.rs
+++ b/vmbase/example/src/main.rs
@@ -24,7 +24,8 @@
extern crate alloc;
use crate::layout::{
- dtb_range, print_addresses, rodata_range, text_range, writable_region, DEVICE_REGION,
+ bionic_tls, dtb_range, print_addresses, rodata_range, stack_chk_guard, text_range,
+ writable_region, DEVICE_REGION,
};
use aarch64_paging::{idmap::IdMap, paging::Attributes};
use alloc::{vec, vec::Vec};
@@ -55,6 +56,7 @@
print_addresses();
assert_eq!(arg0, dtb_range().start.0 as u64);
check_data();
+ check_stack_guard();
unsafe {
HEAP_ALLOCATOR.lock().init(&mut HEAP as *mut u8 as usize, HEAP.len());
@@ -92,6 +94,14 @@
info!("Activated.");
check_data();
+ check_dice();
+}
+
+fn check_stack_guard() {
+ const BIONIC_TLS_STACK_GRD_OFF: usize = 40;
+
+ info!("Testing stack guard");
+ assert_eq!(bionic_tls(BIONIC_TLS_STACK_GRD_OFF), stack_chk_guard());
}
fn check_data() {
@@ -139,3 +149,18 @@
assert_eq!(vector[2], 42);
info!("Vec seems to work.");
}
+
+fn check_dice() {
+ info!("Testing DICE integration...");
+ let hash = dice::hash("hello world".as_bytes()).expect("DiceHash failed");
+ assert_eq!(
+ hash,
+ [
+ 0x30, 0x9e, 0xcc, 0x48, 0x9c, 0x12, 0xd6, 0xeb, 0x4c, 0xc4, 0x0f, 0x50, 0xc9, 0x02,
+ 0xf2, 0xb4, 0xd0, 0xed, 0x77, 0xee, 0x51, 0x1a, 0x7c, 0x7a, 0x9b, 0xcd, 0x3c, 0xa8,
+ 0x6d, 0x4c, 0xd8, 0x6f, 0x98, 0x9d, 0xd3, 0x5b, 0xc5, 0xff, 0x49, 0x96, 0x70, 0xda,
+ 0x34, 0x25, 0x5b, 0x45, 0xb0, 0xcf, 0xd8, 0x30, 0xe8, 0x1f, 0x60, 0x5d, 0xcf, 0x7d,
+ 0xc5, 0x54, 0x2e, 0x93, 0xae, 0x9c, 0xd7, 0x6f
+ ]
+ );
+}
diff --git a/vmbase/src/lib.rs b/vmbase/src/lib.rs
index 257f415..9c9417a 100644
--- a/vmbase/src/lib.rs
+++ b/vmbase/src/lib.rs
@@ -30,3 +30,8 @@
eprintln!("{}", info);
reboot()
}
+
+#[no_mangle]
+extern "C" fn __stack_chk_fail() -> ! {
+ panic!("stack guard check failed");
+}