Merge changes I89908434,I9e77925f
* changes:
pvmfw: Integrate verify_payload
vmbase: Add support for fputs(), stdout, stderr
diff --git a/pvmfw/Android.bp b/pvmfw/Android.bp
index ed3ef8d..f5e214e 100644
--- a/pvmfw/Android.bp
+++ b/pvmfw/Android.bp
@@ -18,6 +18,7 @@
"libfdtpci",
"liblibfdt",
"liblog_rust_nostd",
+ "libpvmfw_avb_nostd",
"libpvmfw_embedded_key",
"libtinyvec_nostd",
"libvirtio_drivers",
diff --git a/pvmfw/src/entry.rs b/pvmfw/src/entry.rs
index e979a95..1b35c79 100644
--- a/pvmfw/src/entry.rs
+++ b/pvmfw/src/entry.rs
@@ -47,7 +47,6 @@
/// The provided ramdisk was invalid.
InvalidRamdisk,
/// Failed to verify the payload.
- #[allow(dead_code)]
PayloadVerificationError,
}
diff --git a/pvmfw/src/main.rs b/pvmfw/src/main.rs
index 4d1ddfe..b0177bf 100644
--- a/pvmfw/src/main.rs
+++ b/pvmfw/src/main.rs
@@ -34,7 +34,7 @@
mod smccc;
use crate::{
- avb::PUBLIC_KEY, // Keep the public key here otherwise the signing script will be broken.
+ avb::PUBLIC_KEY,
entry::RebootReason,
memory::MemoryTracker,
pci::{find_virtio_devices, map_mmio},
@@ -43,6 +43,7 @@
use fdtpci::{PciError, PciInfo};
use libfdt::Fdt;
use log::{debug, error, info, trace};
+use pvmfw_avb::verify_payload;
fn main(
fdt: &Fdt,
@@ -71,6 +72,11 @@
let mut pci_root = unsafe { pci_info.make_pci_root() };
find_virtio_devices(&mut pci_root).map_err(handle_pci_error)?;
+ verify_payload(signed_kernel, PUBLIC_KEY).map_err(|e| {
+ error!("Failed to verify the payload: {e}");
+ RebootReason::PayloadVerificationError
+ })?;
+
info!("Starting payload...");
Ok(())
}
diff --git a/vmbase/src/bionic.rs b/vmbase/src/bionic.rs
index b4a2f7b..6f88cf6 100644
--- a/vmbase/src/bionic.rs
+++ b/vmbase/src/bionic.rs
@@ -16,11 +16,17 @@
use core::ffi::c_char;
use core::ffi::c_int;
+use core::ffi::c_void;
use core::ffi::CStr;
+use core::slice;
+use core::str;
+use crate::console;
use crate::eprintln;
use crate::linker;
+const EOF: c_int = -1;
+
/// Reference to __stack_chk_guard.
pub static STACK_CHK_GUARD: &u64 = unsafe { &linker::__stack_chk_guard };
@@ -43,6 +49,11 @@
&mut ERRNO as *mut _
}
+fn set_errno(value: c_int) {
+ // SAFETY - vmbase is currently single-threaded.
+ unsafe { ERRNO = value };
+}
+
/// Reports a fatal error detected by Bionic.
///
/// # Safety
@@ -62,3 +73,56 @@
eprintln!("FATAL BIONIC ERROR: {prefix}: \"{format}\" (unformatted)");
}
}
+
+#[repr(usize)]
+/// Arbitrary token FILE pseudo-pointers used by C to refer to the default streams.
+enum File {
+ Stdout = 0x7670cf00,
+ Stderr = 0x9d118200,
+}
+
+impl TryFrom<usize> for File {
+ type Error = &'static str;
+
+ fn try_from(value: usize) -> Result<Self, Self::Error> {
+ match value {
+ x if x == File::Stdout as _ => Ok(File::Stdout),
+ x if x == File::Stderr as _ => Ok(File::Stderr),
+ _ => Err("Received Invalid FILE* from C"),
+ }
+ }
+}
+
+#[no_mangle]
+static stdout: File = File::Stdout;
+#[no_mangle]
+static stderr: File = File::Stderr;
+
+#[no_mangle]
+extern "C" fn fputs(c_str: *const c_char, stream: usize) -> c_int {
+ // SAFETY - Just like libc, we need to assume that `s` is a valid NULL-terminated string.
+ let c_str = unsafe { CStr::from_ptr(c_str) };
+
+ if let (Ok(s), Ok(_)) = (c_str.to_str(), File::try_from(stream)) {
+ console::write_str(s);
+ 0
+ } else {
+ set_errno(EOF);
+ EOF
+ }
+}
+
+#[no_mangle]
+extern "C" fn fwrite(ptr: *const c_void, size: usize, nmemb: usize, stream: usize) -> usize {
+ let length = size.saturating_mul(nmemb);
+
+ // SAFETY - Just like libc, we need to assume that `ptr` is valid.
+ let bytes = unsafe { slice::from_raw_parts(ptr as *const u8, length) };
+
+ if let (Ok(s), Ok(_)) = (str::from_utf8(bytes), File::try_from(stream)) {
+ console::write_str(s);
+ length
+ } else {
+ 0
+ }
+}