Merge "[refactoring] Group all the CBOR util functions in cbor_util" into main
diff --git a/apkdmverity/Android.bp b/apkdmverity/Android.bp
index c4c90cd..0cb8ca1 100644
--- a/apkdmverity/Android.bp
+++ b/apkdmverity/Android.bp
@@ -15,6 +15,7 @@
"libbitflags",
"libclap",
"libdm_rust",
+ "libhex",
"libitertools",
"liblibc",
"libnix",
diff --git a/apkdmverity/src/main.rs b/apkdmverity/src/main.rs
index d9e9e2b..0ecb0ea 100644
--- a/apkdmverity/src/main.rs
+++ b/apkdmverity/src/main.rs
@@ -46,7 +46,7 @@
for (apk, idsig, name, roothash) in apks.tuples() {
let roothash = if roothash != "none" {
- Some(util::parse_hexstring(roothash).expect("failed to parse roothash"))
+ Some(hex::decode(roothash).expect("failed to parse roothash"))
} else {
None
};
@@ -108,8 +108,10 @@
bail!("The size of {:?} is not multiple of {}.", &apk, BLOCK_SIZE)
}
(
- loopdevice::attach(&apk, 0, apk_size, /*direct_io*/ true, /*writable*/ false)
- .context("Failed to attach APK to a loop device")?,
+ loopdevice::attach(
+ &apk, 0, apk_size, /* direct_io */ true, /* writable */ false,
+ )
+ .context("Failed to attach APK to a loop device")?,
apk_size,
)
};
@@ -123,9 +125,10 @@
// Due to unknown reason(b/191344832), we can't enable "direct IO" for the IDSIG file (backing
// the hash). For now we don't use "direct IO" but it seems OK since the IDSIG file is very
// small and the benefit of direct-IO would be negliable.
- let hash_device =
- loopdevice::attach(&idsig, offset, size, /*direct_io*/ false, /*writable*/ false)
- .context("Failed to attach idsig to a loop device")?;
+ let hash_device = loopdevice::attach(
+ &idsig, offset, size, /* direct_io */ false, /* writable */ false,
+ )
+ .context("Failed to attach idsig to a loop device")?;
// Build a dm-verity target spec from the information from the idsig file. The apk and the
// idsig files are used as the data device and the hash device, respectively.
@@ -338,7 +341,7 @@
// of the data device is done in the scopeguard for the return value of `enable_verity`
// below. Only the idsig_loop_device needs detatching.
let apk_loop_device = loopdevice::attach(
- &apk_path, 0, apk_size, /*direct_io*/ true, /*writable*/ false,
+ &apk_path, 0, apk_size, /* direct_io */ true, /* writable */ false,
)
.unwrap();
let idsig_loop_device = scopeguard::guard(
@@ -346,8 +349,8 @@
&idsig_path,
0,
idsig_size,
- /*direct_io*/ false,
- /*writable*/ false,
+ /* direct_io */ false,
+ /* writable */ false,
)
.unwrap(),
|dev| loopdevice::detach(dev).unwrap(),
diff --git a/authfs/src/fsverity/builder.rs b/authfs/src/fsverity/builder.rs
index 8585fdf..6d724ca 100644
--- a/authfs/src/fsverity/builder.rs
+++ b/authfs/src/fsverity/builder.rs
@@ -159,7 +159,7 @@
#[test]
fn merkle_tree_empty_file() -> Result<()> {
assert_eq!(
- to_u8_vec("3d248ca542a24fc62d1c43b916eae5016878e2533c88238480b26128a1f1af95"),
+ hex::decode("3d248ca542a24fc62d1c43b916eae5016878e2533c88238480b26128a1f1af95")?,
generate_fsverity_digest_sequentially(&Vec::new())?
);
Ok(())
@@ -169,7 +169,7 @@
fn merkle_tree_file_size_less_than_or_equal_to_4k() -> Result<()> {
// Test a file that contains 4096 '\01's.
assert_eq!(
- to_u8_vec("cd0875ca59c7d37e962c5e8f5acd3770750ac80225e2df652ce5672fd34500af"),
+ hex::decode("cd0875ca59c7d37e962c5e8f5acd3770750ac80225e2df652ce5672fd34500af")?,
generate_fsverity_digest_sequentially(&vec![1; 4096])?
);
Ok(())
@@ -180,24 +180,24 @@
// Test files that contains >4096 '\01's.
assert_eq!(
- to_u8_vec("2901b849fda2d91e3929524561c4a47e77bb64734319759507b2029f18b9cc52"),
+ hex::decode("2901b849fda2d91e3929524561c4a47e77bb64734319759507b2029f18b9cc52")?,
generate_fsverity_digest_sequentially(&vec![1; 4097])?
);
assert_eq!(
- to_u8_vec("2a476d58eb80394052a3a783111e1458ac3ecf68a7878183fed86ca0ff47ec0d"),
+ hex::decode("2a476d58eb80394052a3a783111e1458ac3ecf68a7878183fed86ca0ff47ec0d")?,
generate_fsverity_digest_sequentially(&vec![1; 8192])?
);
// Test with max size that still fits in 2 levels.
assert_eq!(
- to_u8_vec("26b7c190a34e19f420808ee7ec233b09fa6c34543b5a9d2950530114c205d14f"),
+ hex::decode("26b7c190a34e19f420808ee7ec233b09fa6c34543b5a9d2950530114c205d14f")?,
generate_fsverity_digest_sequentially(&vec![1; 524288])?
);
// Test with data that requires 3 levels.
assert_eq!(
- to_u8_vec("316835d9be1c95b5cd55d07ae7965d651689efad186e26cbf680e40b683a3262"),
+ hex::decode("316835d9be1c95b5cd55d07ae7965d651689efad186e26cbf680e40b683a3262")?,
generate_fsverity_digest_sequentially(&vec![1; 524289])?
);
Ok(())
@@ -215,7 +215,7 @@
tree.update_hash(2, &hash, CHUNK_SIZE * 3);
assert_eq!(
- to_u8_vec("7d3c0d2e1dc54230b20ed875f5f3a4bd3f9873df601936b3ca8127d4db3548f3"),
+ hex::decode("7d3c0d2e1dc54230b20ed875f5f3a4bd3f9873df601936b3ca8127d4db3548f3")?,
tree.calculate_fsverity_digest()?
);
Ok(())
@@ -268,12 +268,4 @@
}
Ok(tree.calculate_fsverity_digest()?)
}
-
- fn to_u8_vec(hex_str: &str) -> Vec<u8> {
- assert!(hex_str.len() % 2 == 0);
- (0..hex_str.len())
- .step_by(2)
- .map(|i| u8::from_str_radix(&hex_str[i..i + 2], 16).unwrap())
- .collect()
- }
}
diff --git a/authfs/src/fsverity/editor.rs b/authfs/src/fsverity/editor.rs
index 4af6e80..c84500b 100644
--- a/authfs/src/fsverity/editor.rs
+++ b/authfs/src/fsverity/editor.rs
@@ -373,7 +373,7 @@
let file = VerifiedFileEditor::new(InMemoryEditor::new());
assert_eq!(
file.calculate_fsverity_digest()?,
- to_u8_vec("3d248ca542a24fc62d1c43b916eae5016878e2533c88238480b26128a1f1af95")
+ hex::decode("3d248ca542a24fc62d1c43b916eae5016878e2533c88238480b26128a1f1af95")?
.as_slice()
);
Ok(())
@@ -386,7 +386,7 @@
assert_eq!(file.write_at(&[1; 4096], 0)?, 4096);
assert_eq!(
file.calculate_fsverity_digest()?,
- to_u8_vec("cd0875ca59c7d37e962c5e8f5acd3770750ac80225e2df652ce5672fd34500af")
+ hex::decode("cd0875ca59c7d37e962c5e8f5acd3770750ac80225e2df652ce5672fd34500af")?
.as_slice()
);
@@ -395,7 +395,7 @@
assert_eq!(file.write_at(&[1; 4097], 0)?, 4097);
assert_eq!(
file.calculate_fsverity_digest()?,
- to_u8_vec("2901b849fda2d91e3929524561c4a47e77bb64734319759507b2029f18b9cc52")
+ hex::decode("2901b849fda2d91e3929524561c4a47e77bb64734319759507b2029f18b9cc52")?
.as_slice()
);
@@ -404,7 +404,7 @@
assert_eq!(file.write_at(&[1; 10000], 0)?, 10000);
assert_eq!(
file.calculate_fsverity_digest()?,
- to_u8_vec("7545409b556071554d18973a29b96409588c7cda4edd00d5586b27a11e1a523b")
+ hex::decode("7545409b556071554d18973a29b96409588c7cda4edd00d5586b27a11e1a523b")?
.as_slice()
);
Ok(())
@@ -417,7 +417,7 @@
assert_eq!(file.write_at(&[1; 5], 3)?, 5);
assert_eq!(
file.calculate_fsverity_digest()?,
- to_u8_vec("a23fc5130d3d7b3323fc4b4a5e79d5d3e9ddf3a3f5872639e867713512c6702f")
+ hex::decode("a23fc5130d3d7b3323fc4b4a5e79d5d3e9ddf3a3f5872639e867713512c6702f")?
.as_slice()
);
@@ -426,7 +426,7 @@
assert_eq!(file.write_at(&[1; 6000], 4000)?, 6000);
assert_eq!(
file.calculate_fsverity_digest()?,
- to_u8_vec("d16d4c1c186d757e646f76208b21254f50d7f07ea07b1505ff48b2a6f603f989")
+ hex::decode("d16d4c1c186d757e646f76208b21254f50d7f07ea07b1505ff48b2a6f603f989")?
.as_slice()
);
Ok(())
@@ -439,7 +439,7 @@
assert_eq!(file.write_at(&[1; 4096], 4096)?, 4096);
assert_eq!(
file.calculate_fsverity_digest()?,
- to_u8_vec("4df2aefd8c2a9101d1d8770dca3ede418232eabce766bb8e020395eae2e97103")
+ hex::decode("4df2aefd8c2a9101d1d8770dca3ede418232eabce766bb8e020395eae2e97103")?
.as_slice()
);
@@ -448,7 +448,7 @@
assert_eq!(file.write_at(&[1; 5000], 6000)?, 5000);
assert_eq!(
file.calculate_fsverity_digest()?,
- to_u8_vec("47d5da26f6934484e260630a69eb2eebb21b48f69bc8fbf8486d1694b7dba94f")
+ hex::decode("47d5da26f6934484e260630a69eb2eebb21b48f69bc8fbf8486d1694b7dba94f")?
.as_slice()
);
@@ -457,7 +457,7 @@
assert_eq!(file.write_at(&[1; 5], 16381)?, 5);
assert_eq!(
file.calculate_fsverity_digest()?,
- to_u8_vec("8bd118821fb4aff26bb4b51d485cc481a093c68131b7f4f112e9546198449752")
+ hex::decode("8bd118821fb4aff26bb4b51d485cc481a093c68131b7f4f112e9546198449752")?
.as_slice()
);
Ok(())
@@ -470,34 +470,34 @@
assert_eq!(file.write_at(&[1; 2048], 4096 + 2048)?, 2048);
assert_eq!(
file.calculate_fsverity_digest()?,
- to_u8_vec("4c433d8640c888b629dc673d318cbb8d93b1eebcc784d9353e07f09f0dcfe707")
+ hex::decode("4c433d8640c888b629dc673d318cbb8d93b1eebcc784d9353e07f09f0dcfe707")?
.as_slice()
);
assert_eq!(file.write_at(&[1; 2048], 2048)?, 2048);
assert_eq!(file.write_at(&[1; 2048], 4096)?, 2048);
assert_eq!(
file.calculate_fsverity_digest()?,
- to_u8_vec("2a476d58eb80394052a3a783111e1458ac3ecf68a7878183fed86ca0ff47ec0d")
+ hex::decode("2a476d58eb80394052a3a783111e1458ac3ecf68a7878183fed86ca0ff47ec0d")?
.as_slice()
);
assert_eq!(file.write_at(&[0; 2048], 2048)?, 2048);
assert_eq!(file.write_at(&[0; 2048], 4096)?, 2048);
assert_eq!(
file.calculate_fsverity_digest()?,
- to_u8_vec("4c433d8640c888b629dc673d318cbb8d93b1eebcc784d9353e07f09f0dcfe707")
+ hex::decode("4c433d8640c888b629dc673d318cbb8d93b1eebcc784d9353e07f09f0dcfe707")?
.as_slice()
);
assert_eq!(file.write_at(&[1; 4096], 2048)?, 4096);
assert_eq!(
file.calculate_fsverity_digest()?,
- to_u8_vec("2a476d58eb80394052a3a783111e1458ac3ecf68a7878183fed86ca0ff47ec0d")
+ hex::decode("2a476d58eb80394052a3a783111e1458ac3ecf68a7878183fed86ca0ff47ec0d")?
.as_slice()
);
assert_eq!(file.write_at(&[1; 2048], 8192)?, 2048);
assert_eq!(file.write_at(&[1; 2048], 8192 + 2048)?, 2048);
assert_eq!(
file.calculate_fsverity_digest()?,
- to_u8_vec("23cbac08371e6ee838ebcc7ae6512b939d2226e802337be7b383c3e046047d24")
+ hex::decode("23cbac08371e6ee838ebcc7ae6512b939d2226e802337be7b383c3e046047d24")?
.as_slice()
);
Ok(())
@@ -555,7 +555,7 @@
assert_eq!(
file.calculate_fsverity_digest()?,
- to_u8_vec("fef1b4f19bb7a2cd944d7cdee44d1accb12726389ca5b0f61ac0f548ae40876f")
+ hex::decode("fef1b4f19bb7a2cd944d7cdee44d1accb12726389ca5b0f61ac0f548ae40876f")?
.as_slice()
);
Ok(())
@@ -572,7 +572,7 @@
assert_eq!(
file.calculate_fsverity_digest()?,
- to_u8_vec("9e0e2745c21e4e74065240936d2047340d96a466680c3c9d177b82433e7a0bb1")
+ hex::decode("9e0e2745c21e4e74065240936d2047340d96a466680c3c9d177b82433e7a0bb1")?
.as_slice()
);
Ok(())
@@ -589,7 +589,7 @@
assert_eq!(
file.calculate_fsverity_digest()?,
- to_u8_vec("fef1b4f19bb7a2cd944d7cdee44d1accb12726389ca5b0f61ac0f548ae40876f")
+ hex::decode("fef1b4f19bb7a2cd944d7cdee44d1accb12726389ca5b0f61ac0f548ae40876f")?
.as_slice()
);
Ok(())
@@ -621,17 +621,9 @@
assert_eq!(
file.calculate_fsverity_digest()?,
- to_u8_vec("cd0875ca59c7d37e962c5e8f5acd3770750ac80225e2df652ce5672fd34500af")
+ hex::decode("cd0875ca59c7d37e962c5e8f5acd3770750ac80225e2df652ce5672fd34500af")?
.as_slice()
);
Ok(())
}
-
- fn to_u8_vec(hex_str: &str) -> Vec<u8> {
- assert!(hex_str.len() % 2 == 0);
- (0..hex_str.len())
- .step_by(2)
- .map(|i| u8::from_str_radix(&hex_str[i..i + 2], 16).unwrap())
- .collect()
- }
}
diff --git a/libs/devicemapper/src/util.rs b/libs/devicemapper/src/util.rs
index e8df424..cc071e4 100644
--- a/libs/devicemapper/src/util.rs
+++ b/libs/devicemapper/src/util.rs
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-use anyhow::{anyhow, bail, Result};
+use anyhow::{bail, Result};
use nix::sys::stat::FileStat;
use std::fs::File;
use std::os::unix::fs::FileTypeExt;
@@ -52,24 +52,6 @@
Ok(())
}
-/// Returns hexadecimal reprentation of a given byte array.
-pub fn hexstring_from(s: &[u8]) -> String {
- s.iter().map(|byte| format!("{:02x}", byte)).reduce(|i, j| i + &j).unwrap_or_default()
-}
-
-/// Parses a hexadecimal string into a byte array
-pub fn parse_hexstring(s: &str) -> Result<Vec<u8>> {
- let len = s.len();
- if len % 2 != 0 {
- bail!("length {} is not even", len)
- } else {
- (0..len)
- .step_by(2)
- .map(|i| u8::from_str_radix(&s[i..i + 2], 16).map_err(|e| anyhow!(e)))
- .collect()
- }
-}
-
/// fstat that accepts a path rather than FD
pub fn fstat(p: &Path) -> Result<FileStat> {
let f = File::open(p)?;
diff --git a/libs/devicemapper/src/verity.rs b/libs/devicemapper/src/verity.rs
index 24584f8..bbd9d38 100644
--- a/libs/devicemapper/src/verity.rs
+++ b/libs/devicemapper/src/verity.rs
@@ -151,7 +151,7 @@
};
let root_digest = if let Some(root_digest) = self.root_digest {
- hexstring_from(root_digest)
+ hex::encode(root_digest)
} else {
bail!("root digest is not set")
};
@@ -159,7 +159,7 @@
let salt = if self.salt.is_none() || self.salt.unwrap().is_empty() {
"-".to_string() // Note. It's not an empty string!
} else {
- hexstring_from(self.salt.unwrap())
+ hex::encode(self.salt.unwrap())
};
// Step2: serialize the information according to the spec, which is ...
diff --git a/libs/libfdt/src/iterators.rs b/libs/libfdt/src/iterators.rs
index 000f723..a524655 100644
--- a/libs/libfdt/src/iterators.rs
+++ b/libs/libfdt/src/iterators.rs
@@ -323,6 +323,29 @@
}
}
+/// Iterator over descendants
+#[derive(Debug)]
+pub struct DescendantsIterator<'a> {
+ node: Option<(FdtNode<'a>, usize)>,
+}
+
+impl<'a> DescendantsIterator<'a> {
+ pub(crate) fn new(node: &'a FdtNode) -> Self {
+ Self { node: Some((*node, 0)) }
+ }
+}
+
+impl<'a> Iterator for DescendantsIterator<'a> {
+ type Item = (FdtNode<'a>, usize);
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let (node, depth) = self.node?;
+ self.node = node.next_node(depth).ok().flatten().filter(|(_, depth)| *depth > 0);
+
+ self.node
+ }
+}
+
/// Iterator over properties
#[derive(Debug)]
pub struct PropertyIterator<'a> {
diff --git a/libs/libfdt/src/lib.rs b/libs/libfdt/src/lib.rs
index b513649..aae75f7 100644
--- a/libs/libfdt/src/lib.rs
+++ b/libs/libfdt/src/lib.rs
@@ -20,8 +20,8 @@
mod iterators;
pub use iterators::{
- AddressRange, CellIterator, CompatibleIterator, MemRegIterator, PropertyIterator,
- RangesIterator, Reg, RegIterator, SubnodeIterator,
+ AddressRange, CellIterator, CompatibleIterator, DescendantsIterator, MemRegIterator,
+ PropertyIterator, RangesIterator, Reg, RegIterator, SubnodeIterator,
};
use core::cmp::max;
@@ -486,6 +486,23 @@
Ok(fdt_err_or_option(ret)?.map(|offset| FdtNode { fdt: self.fdt, offset }))
}
+ /// Returns an iterator of descendants
+ pub fn descendants(&'a self) -> DescendantsIterator<'a> {
+ DescendantsIterator::new(self)
+ }
+
+ fn next_node(&self, depth: usize) -> Result<Option<(Self, usize)>> {
+ let mut next_depth: c_int = depth.try_into().unwrap();
+ // SAFETY: Accesses (read-only) are constrained to the DT totalsize.
+ let ret = unsafe {
+ libfdt_bindgen::fdt_next_node(self.fdt.as_ptr(), self.offset, &mut next_depth)
+ };
+ let Ok(next_depth) = usize::try_from(next_depth) else {
+ return Ok(None);
+ };
+ Ok(fdt_err_or_option(ret)?.map(|offset| (FdtNode { fdt: self.fdt, offset }, next_depth)))
+ }
+
/// Returns an iterator of properties
pub fn properties(&'a self) -> Result<PropertyIterator<'a>> {
PropertyIterator::new(self)
diff --git a/libs/libfdt/tests/api_test.rs b/libs/libfdt/tests/api_test.rs
index 63cbdee..d5d6ece 100644
--- a/libs/libfdt/tests/api_test.rs
+++ b/libs/libfdt/tests/api_test.rs
@@ -308,3 +308,23 @@
// Just check whether borrow checker doesn't complain this.
memory.setprop_inplace(cstr!("device_type"), b"MEMORY\0").unwrap();
}
+
+#[test]
+fn node_descendants() {
+ let mut data = fs::read(TEST_TREE_PHANDLE_PATH).unwrap();
+ let fdt = Fdt::from_mut_slice(&mut data).unwrap();
+
+ let node_z = fdt.node(cstr!("/node_z")).unwrap().unwrap();
+ let descendants: Vec<_> =
+ node_z.descendants().map(|(node, depth)| (node.name().unwrap(), depth)).collect();
+
+ assert_eq!(
+ descendants,
+ vec![
+ (cstr!("node_za"), 1),
+ (cstr!("node_zb"), 1),
+ (cstr!("node_zz"), 1),
+ (cstr!("node_zzz"), 2)
+ ]
+ );
+}