Merge changes Ie098a1e9,Iaff910f0

* changes:
  mv apkverity apkdmverity
  apkdmverity: use data_model crate for better handling of C structs
diff --git a/apkverity/.cargo/config.toml b/apkdmverity/apkverity/.cargo/config.toml
similarity index 100%
rename from apkverity/.cargo/config.toml
rename to apkdmverity/apkverity/.cargo/config.toml
diff --git a/apkverity/Android.bp b/apkdmverity/apkverity/Android.bp
similarity index 96%
rename from apkverity/Android.bp
rename to apkdmverity/apkverity/Android.bp
index 3d0dab5..9b53a47 100644
--- a/apkverity/Android.bp
+++ b/apkdmverity/apkverity/Android.bp
@@ -12,6 +12,7 @@
         "libanyhow",
         "libbitflags",
         "libclap",
+        "libdata_model",
         "liblibc",
         "libnix",
         "libnum_traits",
diff --git a/apkverity/AndroidTest.xml b/apkdmverity/apkverity/AndroidTest.xml
similarity index 100%
rename from apkverity/AndroidTest.xml
rename to apkdmverity/apkverity/AndroidTest.xml
diff --git a/apkverity/Cargo.toml b/apkdmverity/apkverity/Cargo.toml
similarity index 94%
rename from apkverity/Cargo.toml
rename to apkdmverity/apkverity/Cargo.toml
index 43100e5..c367587 100644
--- a/apkverity/Cargo.toml
+++ b/apkdmverity/apkverity/Cargo.toml
@@ -14,6 +14,7 @@
 num-derive = "0.3"
 num-traits = "0.2"
 uuid = { version = "0.8", features = ["v1"] }
+data_model = "0.1"
 
 [dev-dependencies]
 tempfile = "3.2"
diff --git a/apkverity/src/apksigv4.rs b/apkdmverity/apkverity/src/apksigv4.rs
similarity index 100%
rename from apkverity/src/apksigv4.rs
rename to apkdmverity/apkverity/src/apksigv4.rs
diff --git a/apkverity/src/dm.rs b/apkdmverity/apkverity/src/dm.rs
similarity index 88%
rename from apkverity/src/dm.rs
rename to apkdmverity/apkverity/src/dm.rs
index 7ac72c8..75a4366 100644
--- a/apkverity/src/dm.rs
+++ b/apkdmverity/apkverity/src/dm.rs
@@ -29,6 +29,7 @@
 use crate::util::*;
 
 use anyhow::Result;
+use data_model::DataInit;
 use std::fs::{File, OpenOptions};
 use std::io::Write;
 use std::mem::size_of;
@@ -74,6 +75,7 @@
 // `DmTargetSpec` is the header of the data structure for a device-mapper target. When doing the
 // ioctl, one of more `DmTargetSpec` (and its body) are appened to the `DmIoctl` struct.
 #[repr(C)]
+#[derive(Copy, Clone)]
 struct DmTargetSpec {
     sector_start: u64,
     length: u64, // number of 512 sectors
@@ -82,24 +84,22 @@
     target_type: [u8; DM_MAX_TYPE_NAME],
 }
 
+// SAFETY: C struct is safe to be initialized from raw data
+unsafe impl DataInit for DmTargetSpec {}
+
 impl DmTargetSpec {
     fn new(target_type: &str) -> Result<Self> {
-        // SAFETY: zero initialized C struct is safe
-        let mut spec = unsafe { std::mem::MaybeUninit::<Self>::zeroed().assume_init() };
+        // safe because the size of the array is the same as the size of the struct
+        let mut spec: Self = *DataInit::from_mut_slice(&mut [0; size_of::<Self>()]).unwrap();
         spec.target_type.as_mut().write_all(target_type.as_bytes())?;
         Ok(spec)
     }
-
-    fn as_u8_slice(&self) -> &[u8; size_of::<Self>()] {
-        // SAFETY: lifetime of the output reference isn't changed.
-        unsafe { &*(&self as *const &Self as *const [u8; size_of::<Self>()]) }
-    }
 }
 
 impl DmIoctl {
     fn new(name: &str) -> Result<DmIoctl> {
-        // SAFETY: zero initialized C struct is safe
-        let mut data = unsafe { std::mem::MaybeUninit::<Self>::zeroed().assume_init() };
+        // safe because the size of the array is the same as the size of the struct
+        let mut data: Self = *DataInit::from_mut_slice(&mut [0; size_of::<Self>()]).unwrap();
         data.version[0] = DM_VERSION_MAJOR;
         data.version[1] = DM_VERSION_MINOR;
         data.version[2] = DM_VERSION_PATCHLEVEL;
@@ -115,11 +115,6 @@
         dst.write_all(uuid.as_bytes())?;
         Ok(())
     }
-
-    fn as_u8_slice(&self) -> &[u8; size_of::<Self>()] {
-        // SAFETY: lifetime of the output reference isn't changed.
-        unsafe { &*(&self as *const &Self as *const [u8; size_of::<Self>()]) }
-    }
 }
 
 /// `DeviceMapper` is the entry point for the device mapper framework. It essentially is a file
@@ -153,7 +148,7 @@
         dm_dev_create(&self, &mut data)?;
 
         // Step 2: load table onto the device
-        let payload_size = size_of::<DmIoctl>() + target.as_u8_slice().len();
+        let payload_size = size_of::<DmIoctl>() + target.as_slice().len();
 
         let mut data = DmIoctl::new(&name)?;
         data.data_size = payload_size as u32;
@@ -162,8 +157,8 @@
         data.flags |= Flag::DM_READONLY_FLAG;
 
         let mut payload = Vec::with_capacity(payload_size);
-        payload.extend_from_slice(data.as_u8_slice());
-        payload.extend_from_slice(target.as_u8_slice());
+        payload.extend_from_slice(data.as_slice());
+        payload.extend_from_slice(target.as_slice());
         dm_table_load(&self, payload.as_mut_ptr() as *mut DmIoctl)?;
 
         // Step 3: activate the device (note: the term 'suspend' might be misleading, but it
diff --git a/apkverity/src/dm/sys.rs b/apkdmverity/apkverity/src/dm/sys.rs
similarity index 94%
rename from apkverity/src/dm/sys.rs
rename to apkdmverity/apkverity/src/dm/sys.rs
index f623a2b..e709bf0 100644
--- a/apkverity/src/dm/sys.rs
+++ b/apkdmverity/apkverity/src/dm/sys.rs
@@ -15,6 +15,7 @@
  */
 
 use bitflags::bitflags;
+use data_model::DataInit;
 
 // UAPI for device mapper can be found at include/uapi/linux/dm-ioctl.h
 
@@ -43,6 +44,7 @@
 }
 
 #[repr(C)]
+#[derive(Copy, Clone)]
 pub struct DmIoctl {
     pub version: [u32; 3],
     pub data_size: u32,
@@ -58,6 +60,9 @@
     pub data: [u8; 7],
 }
 
+// SAFETY: C struct is safe to be initialized from raw data
+unsafe impl DataInit for DmIoctl {}
+
 pub const DM_VERSION_MAJOR: u32 = 4;
 pub const DM_VERSION_MINOR: u32 = 0;
 pub const DM_VERSION_PATCHLEVEL: u32 = 0;
diff --git a/apkverity/src/dm/verity.rs b/apkdmverity/apkverity/src/dm/verity.rs
similarity index 98%
rename from apkverity/src/dm/verity.rs
rename to apkdmverity/apkverity/src/dm/verity.rs
index 950b26e..3a49ee2 100644
--- a/apkverity/src/dm/verity.rs
+++ b/apkdmverity/apkverity/src/dm/verity.rs
@@ -19,6 +19,7 @@
 // which is then given to `DeviceMapper` to create a mapper device.
 
 use anyhow::{bail, Context, Result};
+use data_model::DataInit;
 use std::io::Write;
 use std::mem::size_of;
 use std::path::Path;
@@ -55,7 +56,7 @@
 pub struct DmVerityTarget(Box<[u8]>);
 
 impl DmVerityTarget {
-    pub fn as_u8_slice(&self) -> &[u8] {
+    pub fn as_slice(&self) -> &[u8] {
         self.0.as_ref()
     }
 }
@@ -188,7 +189,7 @@
         header.next = aligned_size as u32;
 
         let mut buf = Vec::with_capacity(aligned_size);
-        buf.write_all(header.as_u8_slice())?;
+        buf.write_all(header.as_slice())?;
         buf.write_all(body.as_bytes())?;
         buf.write_all(vec![0; padding].as_slice())?;
         Ok(DmVerityTarget(buf.into_boxed_slice()))
diff --git a/apkverity/src/loopdevice.rs b/apkdmverity/apkverity/src/loopdevice.rs
similarity index 95%
rename from apkverity/src/loopdevice.rs
rename to apkdmverity/apkverity/src/loopdevice.rs
index 68516d7..69920d5 100644
--- a/apkverity/src/loopdevice.rs
+++ b/apkdmverity/apkverity/src/loopdevice.rs
@@ -24,7 +24,9 @@
 mod sys;
 
 use anyhow::{Context, Result};
+use data_model::DataInit;
 use std::fs::{File, OpenOptions};
+use std::mem::size_of;
 use std::os::unix::io::AsRawFd;
 use std::path::{Path, PathBuf};
 use std::thread;
@@ -106,8 +108,9 @@
         .read(true)
         .open(&path)
         .context(format!("failed to open {:?}", path.as_ref()))?;
-    // SAFETY: zero initialized C structs is safe
-    let mut config = unsafe { std::mem::MaybeUninit::<loop_config>::zeroed().assume_init() };
+    // safe because the size of the array is the same as the size of the struct
+    let mut config: loop_config =
+        *DataInit::from_mut_slice(&mut [0; size_of::<loop_config>()]).unwrap();
     config.fd = backing_file.as_raw_fd() as u32;
     config.block_size = 4096;
     config.info.lo_offset = offset;
diff --git a/apkverity/src/loopdevice/sys.rs b/apkdmverity/apkverity/src/loopdevice/sys.rs
similarity index 91%
rename from apkverity/src/loopdevice/sys.rs
rename to apkdmverity/apkverity/src/loopdevice/sys.rs
index 3f10f22..5de0c92 100644
--- a/apkverity/src/loopdevice/sys.rs
+++ b/apkdmverity/apkverity/src/loopdevice/sys.rs
@@ -15,6 +15,7 @@
  */
 
 use bitflags::bitflags;
+use data_model::DataInit;
 
 // This UAPI is copied and converted from include/uapi/linux/loop.h Note that this module doesn't
 // implement all the features introduced in loop(4). Only the features that are required to support
@@ -28,6 +29,7 @@
 pub const LOOP_CLR_FD: libc::c_ulong = 0x4C01;
 
 #[repr(C)]
+#[derive(Copy, Clone)]
 pub struct loop_config {
     pub fd: u32,
     pub block_size: u32,
@@ -35,7 +37,11 @@
     pub reserved: [u64; 8],
 }
 
+// SAFETY: C struct is safe to be initialized from raw data
+unsafe impl DataInit for loop_config {}
+
 #[repr(C)]
+#[derive(Copy, Clone)]
 pub struct loop_info64 {
     pub lo_device: u64,
     pub lo_inode: u64,
diff --git a/apkverity/src/main.rs b/apkdmverity/apkverity/src/main.rs
similarity index 100%
rename from apkverity/src/main.rs
rename to apkdmverity/apkverity/src/main.rs
diff --git a/apkverity/src/util.rs b/apkdmverity/apkverity/src/util.rs
similarity index 100%
rename from apkverity/src/util.rs
rename to apkdmverity/apkverity/src/util.rs
diff --git a/apkverity/testdata/README b/apkdmverity/apkverity/testdata/README
similarity index 100%
rename from apkverity/testdata/README
rename to apkdmverity/apkverity/testdata/README
diff --git a/apkverity/testdata/keystore b/apkdmverity/apkverity/testdata/keystore
similarity index 100%
rename from apkverity/testdata/keystore
rename to apkdmverity/apkverity/testdata/keystore
Binary files differ
diff --git a/apkverity/testdata/test.apk b/apkdmverity/apkverity/testdata/test.apk
similarity index 100%
rename from apkverity/testdata/test.apk
rename to apkdmverity/apkverity/testdata/test.apk
Binary files differ
diff --git a/apkverity/testdata/test.apk.idsig b/apkdmverity/apkverity/testdata/test.apk.idsig
similarity index 100%
rename from apkverity/testdata/test.apk.idsig
rename to apkdmverity/apkverity/testdata/test.apk.idsig
Binary files differ