summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYecheng Zhao <zyecheng@google.com>2024-04-10 21:50:57 +0000
committerYecheng Zhao <zyecheng@google.com>2024-04-10 23:14:36 +0000
commite1061624d04c39a420f180fbefee5931b64dd69c (patch)
tree099a1bf552604143268efbf2aa23f60b76462227
parent836d997de6a4b173814fc3777841b8d8dc6d8338 (diff)
downloadlibbootloader-e1061624d04c39a420f180fbefee5931b64dd69c.tar.gz
Move avb sysdeps implementation into libavb
Move avb implementation into libavb so that it can be reused in both test and EFI environment. If this proves to be good and useful enough, we can consider further moving them upstream. Change-Id: Ie53bea6517f987f08b98c95ae152f8c6952ca60c
-rw-r--r--gbl/efi/BUILD1
-rw-r--r--gbl/efi/src/avb.rs101
-rw-r--r--gbl/libavb/BUILD9
-rw-r--r--gbl/libavb/src/lib.rs154
4 files changed, 167 insertions, 98 deletions
diff --git a/gbl/efi/BUILD b/gbl/efi/BUILD
index f8e8a10..73f9683 100644
--- a/gbl/efi/BUILD
+++ b/gbl/efi/BUILD
@@ -44,6 +44,7 @@ rust_binary(
deps = [
"@avb",
"@avb//:avb_crypto_ops_sha_impl_staticlib",
+ "@gbl//libavb:sysdeps",
"@gbl//libboot",
"@gbl//libbootconfig",
"@gbl//libbootimg",
diff --git a/gbl/efi/src/avb.rs b/gbl/efi/src/avb.rs
index 049f0f0..5a80000 100644
--- a/gbl/efi/src/avb.rs
+++ b/gbl/efi/src/avb.rs
@@ -16,15 +16,14 @@
// is mainly for use by the boot demo. Eventually, these backends will be implemented from the
// `GblOps` interface in libgbl, where EFI services will be one level lower as its backend instead.
-use core::cmp::{min, Ord};
-use core::ffi::CStr;
-
use crate::utils::EfiMultiBlockDevices;
use avb::{IoError, IoResult, Ops, PublicKeyForPartitionInfo};
-use efi::{efi_free, efi_malloc};
+use core::ffi::CStr;
use gbl_storage::AsMultiBlockDevices;
use uuid::Uuid;
+extern crate avb_sysdeps;
+
pub struct GblEfiAvbOps<'a, 'b> {
gpt_dev: &'b mut EfiMultiBlockDevices<'a>,
preloaded_partitions: Option<&'b [(&'b str, &'b [u8])]>,
@@ -156,97 +155,3 @@ impl<'b> Ops<'b> for GblEfiAvbOps<'_, 'b> {
unimplemented!();
}
}
-
-#[no_mangle]
-pub extern "C" fn avb_abort() -> ! {
- panic!("avb_abort");
-}
-
-#[no_mangle]
-pub extern "C" fn avb_malloc_(size: usize) -> *mut core::ffi::c_void {
- efi_malloc(size) as *mut _
-}
-
-#[no_mangle]
-pub extern "C" fn avb_free(ptr: *mut core::ffi::c_void) {
- efi_free(ptr as *mut _);
-}
-
-#[no_mangle]
-pub extern "C" fn avb_strlen(s: *const core::ffi::c_char) -> usize {
- // SAFETY: libavb guarantees to pass valid NULL-terminated strings to this function. The
- // returned reference is only used to compute string length.
- unsafe { CStr::from_ptr(s as *const _) }.to_bytes().len()
-}
-
-#[no_mangle]
-pub extern "C" fn avb_div_by_10(dividend: *mut u64) -> u32 {
- // SAFETY: libavb guarantees to pass valid pointer to u64 integer here
- let val = unsafe { &mut *dividend };
- let rem = *val % 10;
- *val /= 10;
- rem.try_into().unwrap()
-}
-
-#[no_mangle]
-pub extern "C" fn avb_memcpy(
- dest: *mut core::ffi::c_void,
- src: *const core::ffi::c_void,
- n: usize,
-) -> *mut core::ffi::c_void {
- // SAFETY: libavb guarantees to pass valid pointers.
- unsafe { (src.cast::<u8>()).copy_to(dest as *mut _, n) };
- dest
-}
-
-#[no_mangle]
-pub extern "C" fn avb_memcmp(
- src1: *const core::ffi::c_void,
- src2: *const core::ffi::c_void,
- n: usize,
-) -> core::ffi::c_int {
- // SAFETY: libavb guarantees to pass valid pointers. References are only used within function.
- let (lhs, rhs) = unsafe {
- (
- core::slice::from_raw_parts(src1 as *const u8, n),
- core::slice::from_raw_parts(src2 as *const u8, n),
- )
- };
- Ord::cmp(lhs, rhs) as i32
-}
-
-#[no_mangle]
-pub extern "C" fn avb_strcmp(
- s1: *const core::ffi::c_char,
- s2: *const core::ffi::c_char,
-) -> core::ffi::c_int {
- // SAFETY: libavb guarantees to pass valid NULL-terminated strings. References are only used
- // within function.
- let (lhs, rhs) = unsafe { (CStr::from_ptr(s1 as *const _), CStr::from_ptr(s2 as *const _)) };
- Ord::cmp(lhs, rhs) as i32
-}
-
-#[no_mangle]
-pub extern "C" fn avb_strncmp(
- s1: *const core::ffi::c_char,
- s2: *const core::ffi::c_char,
- n: usize,
-) -> core::ffi::c_int {
- // SAFETY: libavb guarantees to pass valid NULL-terminated strings. References are only used
- // within function.
- let (lhs, rhs) = unsafe { (CStr::from_ptr(s1 as *const _), CStr::from_ptr(s2 as *const _)) };
- let cmp_size = min(min(lhs.to_bytes().len(), rhs.to_bytes().len()), n);
- Ord::cmp(&lhs.to_bytes()[..cmp_size], &rhs.to_bytes()[..cmp_size]) as i32
-}
-
-#[no_mangle]
-pub extern "C" fn avb_memset(
- dest: *mut core::ffi::c_void,
- c: core::ffi::c_int,
- n: usize,
-) -> *mut core::ffi::c_void {
- // SAFETY: libavb guarantees to pass valid buffer. Reference is only used within function.
- let arr = unsafe { core::slice::from_raw_parts_mut(dest as *mut u8, n) };
- arr.fill(c as u8);
- dest
-}
diff --git a/gbl/libavb/BUILD b/gbl/libavb/BUILD
index 277329b..2d05993 100644
--- a/gbl/libavb/BUILD
+++ b/gbl/libavb/BUILD
@@ -12,6 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+load("@rules_rust//rust:defs.bzl", "rust_library")
+
package(
default_visibility = ["//visibility:public"],
)
@@ -23,3 +25,10 @@ cc_library(
hdrs = ["deps/include/inttypes.h"],
includes = ["./deps/include"],
)
+
+rust_library(
+ name = "sysdeps",
+ srcs = glob(["**/*.rs"]),
+ crate_name = "avb_sysdeps",
+ edition = "2021",
+)
diff --git a/gbl/libavb/src/lib.rs b/gbl/libavb/src/lib.rs
new file mode 100644
index 0000000..fc2d987
--- /dev/null
+++ b/gbl/libavb/src/lib.rs
@@ -0,0 +1,154 @@
+// Copyright 2024, 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.
+
+//! This file provides one possible implementation of the sysdeps functions for libavb.
+//! Global allocator is required.
+
+#![cfg_attr(not(test), no_std)]
+
+extern crate alloc;
+use alloc::alloc::{alloc, dealloc};
+use core::{
+ alloc::Layout,
+ cmp::{min, Ord},
+ ffi::CStr,
+ mem::size_of,
+ ptr::{null_mut, NonNull},
+};
+
+/// `avb_malloc_()` requires allocation to be word aligned.
+const AVB_MALLOC_ALIGNMENT: usize = 2;
+
+#[no_mangle]
+pub extern "C" fn avb_abort() -> ! {
+ panic!("avb_abort");
+}
+
+#[no_mangle]
+pub extern "C" fn avb_malloc_(size: usize) -> *mut core::ffi::c_void {
+ (|| {
+ // Allocate extra to store the size value.
+ let size = size_of::<usize>().checked_add(size)?;
+ // SAFETY:
+ // * On success, `alloc` guarantees to allocate enough memory.
+ // * `size.to_le_bytes().as_ptr()` is guaranteed valid memory.
+ // * Alignment is 1 for bytes copy.
+ unsafe {
+ let ptr =
+ NonNull::new(alloc(Layout::from_size_align(size, AVB_MALLOC_ALIGNMENT).ok()?))?;
+ ptr.as_ptr().copy_from(size.to_le_bytes().as_ptr(), size_of::<usize>());
+ let ptr = ptr.as_ptr().add(size_of::<usize>());
+ Some(ptr)
+ }
+ })()
+ .unwrap_or(null_mut()) as _
+}
+
+#[no_mangle]
+pub extern "C" fn avb_free(ptr: *mut core::ffi::c_void) {
+ assert_ne!(ptr, null_mut());
+ let mut ptr = ptr as *mut u8;
+ let mut size_bytes = [0u8; size_of::<usize>()];
+ // SAFETY:
+ // * `ptr` is allocated by `avb_malloc_` and guarantees to have enough memory for a preceding
+ // usize value and payload.
+ // * `size_bytes.as_mut_ptr()` is a valid memory location.
+ // * Alignment is 1 for bytes copy.
+ unsafe {
+ ptr = ptr.sub(size_of::<usize>());
+ ptr.copy_to(size_bytes.as_mut_ptr(), size_of::<usize>())
+ };
+ let size = usize::from_le_bytes(size_bytes);
+ // SAFETY: Call to global allocator.
+ unsafe { dealloc(ptr, Layout::from_size_align(size, AVB_MALLOC_ALIGNMENT).unwrap()) };
+}
+
+#[no_mangle]
+pub extern "C" fn avb_strlen(s: *const core::ffi::c_char) -> usize {
+ // SAFETY: libavb guarantees to pass valid NULL-terminated strings to this function. The
+ // returned reference is only used to compute string length.
+ unsafe { CStr::from_ptr(s as *const _) }.to_bytes().len()
+}
+
+#[no_mangle]
+pub extern "C" fn avb_div_by_10(dividend: *mut u64) -> u32 {
+ // SAFETY: libavb guarantees to pass valid pointer to u64 integer here
+ let val = unsafe { &mut *dividend };
+ let rem = *val % 10;
+ *val /= 10;
+ rem.try_into().unwrap()
+}
+
+#[no_mangle]
+pub extern "C" fn avb_memcpy(
+ dest: *mut core::ffi::c_void,
+ src: *const core::ffi::c_void,
+ n: usize,
+) -> *mut core::ffi::c_void {
+ // SAFETY: libavb guarantees to pass valid pointers.
+ unsafe { (src.cast::<u8>()).copy_to(dest as *mut _, n) };
+ dest
+}
+
+#[no_mangle]
+pub extern "C" fn avb_memcmp(
+ src1: *const core::ffi::c_void,
+ src2: *const core::ffi::c_void,
+ n: usize,
+) -> core::ffi::c_int {
+ // SAFETY: libavb guarantees to pass valid pointers. References are only used within function.
+ let (lhs, rhs) = unsafe {
+ (
+ core::slice::from_raw_parts(src1 as *const u8, n),
+ core::slice::from_raw_parts(src2 as *const u8, n),
+ )
+ };
+ Ord::cmp(lhs, rhs) as i32
+}
+
+#[no_mangle]
+pub extern "C" fn avb_strcmp(
+ s1: *const core::ffi::c_char,
+ s2: *const core::ffi::c_char,
+) -> core::ffi::c_int {
+ // SAFETY: libavb guarantees to pass valid NULL-terminated strings. References are only used
+ // within function.
+ let (lhs, rhs) = unsafe { (CStr::from_ptr(s1 as *const _), CStr::from_ptr(s2 as *const _)) };
+ Ord::cmp(lhs, rhs) as i32
+}
+
+#[no_mangle]
+pub extern "C" fn avb_strncmp(
+ s1: *const core::ffi::c_char,
+ s2: *const core::ffi::c_char,
+ n: usize,
+) -> core::ffi::c_int {
+ // SAFETY: libavb guarantees to pass valid NULL-terminated strings. References are only used
+ // within function.
+ let (lhs, rhs) = unsafe { (CStr::from_ptr(s1 as *const _), CStr::from_ptr(s2 as *const _)) };
+ let cmp_size = min(min(lhs.to_bytes().len(), rhs.to_bytes().len()), n);
+ Ord::cmp(&lhs.to_bytes()[..cmp_size], &rhs.to_bytes()[..cmp_size]) as i32
+}
+
+#[no_mangle]
+pub extern "C" fn avb_memset(
+ dest: *mut core::ffi::c_void,
+ c: core::ffi::c_int,
+ n: usize,
+) -> *mut core::ffi::c_void {
+ // SAFETY: libavb guarantees to pass valid buffer. Reference is only used within function.
+ let arr = unsafe { core::slice::from_raw_parts_mut(dest as *mut u8, n) };
+ arr.fill(c as u8);
+ dest
+}