From b28326198cdd45191530b974bc3409f50f66e187 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Fri, 22 Sep 2023 01:39:21 -0700 Subject: [PATCH] Use crates for cpio code --- native/src/Cargo.lock | 2 ++ native/src/boot/Cargo.toml | 2 ++ native/src/boot/cpio.rs | 55 +++++++++++++++++++++----------------- 3 files changed, 34 insertions(+), 25 deletions(-) diff --git a/native/src/Cargo.lock b/native/src/Cargo.lock index 79b81f325..e0f5ad7b5 100644 --- a/native/src/Cargo.lock +++ b/native/src/Cargo.lock @@ -462,12 +462,14 @@ version = "0.0.0" dependencies = [ "argh", "base", + "bytemuck", "byteorder", "cxx", "cxx-gen", "der", "digest", "fdt", + "num-traits", "p256", "p384", "pb-rs", diff --git a/native/src/boot/Cargo.toml b/native/src/boot/Cargo.toml index 5034c6c65..79807f067 100644 --- a/native/src/boot/Cargo.toml +++ b/native/src/boot/Cargo.toml @@ -27,3 +27,5 @@ rsa = { workspace = true, features = ["sha2"] } x509-cert = { workspace = true } der = { workspace = true, features = ["derive"] } fdt = { workspace = true } +bytemuck = { workspace = true, features = ["derive", "min_const_generics"] } +num-traits = { workspace = true } diff --git a/native/src/boot/cpio.rs b/native/src/boot/cpio.rs index 5a830d9f5..7f8d25580 100644 --- a/native/src/boot/cpio.rs +++ b/native/src/boot/cpio.rs @@ -1,7 +1,6 @@ #![allow(clippy::useless_conversion)] use std::collections::BTreeMap; -use std::ffi::CStr; use std::fmt::{Display, Formatter}; use std::fs::{metadata, read, DirBuilder, File}; use std::io::Write; @@ -9,8 +8,11 @@ use std::mem::size_of; use std::os::unix::fs::{symlink, DirBuilderExt, FileTypeExt, MetadataExt}; use std::path::Path; use std::process::exit; +use std::str; use argh::FromArgs; +use bytemuck::{from_bytes, Pod, Zeroable}; +use num_traits::cast::AsPrimitive; use size::{Base, Size, Style}; use base::libc::{ @@ -183,6 +185,7 @@ Supported commands: ) } +#[derive(Copy, Clone, Pod, Zeroable)] #[repr(C, packed)] struct CpioHeader { magic: [u8; 6], @@ -223,17 +226,17 @@ impl Cpio { fn load_from_data(data: &[u8]) -> LoggedResult { let mut cpio = Cpio::new(); - let mut pos = 0usize; + let mut pos = 0_usize; while pos < data.len() { - let hdr = unsafe { &*(data.as_ptr().add(pos) as *const CpioHeader) }; + let hdr_sz = size_of::(); + let hdr = from_bytes::(&data[pos..(pos + hdr_sz)]); if &hdr.magic != b"070701" { return Err(log_err!("invalid cpio magic")); } - pos += size_of::(); - let name = CStr::from_bytes_until_nul(&data[pos..])? - .to_str()? - .to_string(); - pos += x8u::(&hdr.namesize)?; + pos += hdr_sz; + let name_sz = x8u(&hdr.namesize)? as usize; + let name = Utf8CStr::from_bytes(&data[pos..(pos + name_sz)])?.to_string(); + pos += name_sz; pos = align_4(pos); if name == "." || name == ".." { continue; @@ -245,16 +248,16 @@ impl Cpio { } continue; } - let file_size = x8u::(&hdr.filesize)?; + let file_sz = x8u(&hdr.filesize)? as usize; let entry = Box::new(CpioEntry { - mode: x8u(&hdr.mode)?, - uid: x8u(&hdr.uid)?, - gid: x8u(&hdr.gid)?, - rdevmajor: x8u(&hdr.rdevmajor)?, - rdevminor: x8u(&hdr.rdevminor)?, - data: data[pos..pos + file_size].to_vec(), + mode: x8u(&hdr.mode)?.as_(), + uid: x8u(&hdr.uid)?.as_(), + gid: x8u(&hdr.gid)?.as_(), + rdevmajor: x8u(&hdr.rdevmajor)?.as_(), + rdevminor: x8u(&hdr.rdevminor)?.as_(), + data: data[pos..(pos + file_sz)].to_vec(), }); - pos += file_size; + pos += file_sz; cpio.entries.insert(name, entry); pos = align_4(pos); } @@ -352,7 +355,7 @@ impl Cpio { file.write_all(&entry.data)?; } S_IFLNK => { - symlink(Path::new(&std::str::from_utf8(entry.data.as_slice())?), out)?; + symlink(Path::new(&str::from_utf8(entry.data.as_slice())?), out)?; } S_IFBLK | S_IFCHR => { let dev = makedev(entry.rdevmajor.try_into()?, entry.rdevminor.try_into()?); @@ -600,15 +603,14 @@ pub fn cpio_commands(argc: i32, argv: *const *const c_char) -> bool { .is_ok() } -fn x8u>(x: &[u8; 8]) -> LoggedResult { +fn x8u(x: &[u8; 8]) -> LoggedResult { // parse hex let mut ret = 0u32; - for i in x { - let c = *i as char; - let v = c.to_digit(16).ok_or_else(|| log_err!("bad cpio header"))?; - ret = ret * 16 + v; + let s = str::from_utf8(x).log_with_msg(|w| w.write_str("bad cpio header"))?; + for c in s.chars() { + ret = ret * 16 + c.to_digit(16).ok_or_else(|| log_err!("bad cpio header"))?; } - ret.try_into().map_err(|_| log_err!("bad cpio header")) + Ok(ret) } #[inline(always)] @@ -618,8 +620,11 @@ fn align_4(x: usize) -> usize { #[inline(always)] fn norm_path(path: &str) -> String { - let path = path.strip_prefix('/').unwrap_or(path); - path.strip_suffix('/').unwrap_or(path).to_string() + path.strip_prefix('/') + .unwrap_or(path) + .strip_suffix('/') + .unwrap_or(path) + .to_string() } fn parse_mode(s: &str) -> Result {