Make ID-map artifact identity encoding explicit
This commit is contained in:
parent
c361217fe9
commit
5376aa90f9
1 changed files with 51 additions and 1 deletions
|
|
@ -666,7 +666,7 @@ impl Identities {
|
||||||
POLICY_NAME.as_bytes(),
|
POLICY_NAME.as_bytes(),
|
||||||
&destination_bytes,
|
&destination_bytes,
|
||||||
]));
|
]));
|
||||||
let id_map_bytes = postcard::to_stdvec(&request.id_map)?;
|
let id_map_bytes = canonical_id_map_bytes(&request.id_map)?;
|
||||||
let id_map = IdMapDigest::new(hash_parts(&[b"lazaret-id-map-v1", &id_map_bytes]));
|
let id_map = IdMapDigest::new(hash_parts(&[b"lazaret-id-map-v1", &id_map_bytes]));
|
||||||
let artifact_id = PreparedArtifactId::new(hash_parts(&[
|
let artifact_id = PreparedArtifactId::new(hash_parts(&[
|
||||||
b"lazaret-prepared-artifact-v1",
|
b"lazaret-prepared-artifact-v1",
|
||||||
|
|
@ -857,6 +857,30 @@ fn sync_tree(directory: &File) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn canonical_id_map_bytes(id_map: &IdMap) -> Result<Vec<u8>> {
|
||||||
|
let capacity = id_map
|
||||||
|
.uid
|
||||||
|
.len()
|
||||||
|
.checked_add(id_map.gid.len())
|
||||||
|
.and_then(|ranges| ranges.checked_mul(12))
|
||||||
|
.and_then(|ranges| ranges.checked_add(16))
|
||||||
|
.context("ID-map encoding length overflow")?;
|
||||||
|
let mut bytes = Vec::with_capacity(capacity);
|
||||||
|
for ranges in [&id_map.uid, &id_map.gid] {
|
||||||
|
bytes.extend_from_slice(
|
||||||
|
&u64::try_from(ranges.len())
|
||||||
|
.context("ID-map range count exceeds u64")?
|
||||||
|
.to_be_bytes(),
|
||||||
|
);
|
||||||
|
for range in ranges {
|
||||||
|
bytes.extend_from_slice(&range.container_id.to_be_bytes());
|
||||||
|
bytes.extend_from_slice(&range.namespace_id.to_be_bytes());
|
||||||
|
bytes.extend_from_slice(&range.size.to_be_bytes());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(bytes)
|
||||||
|
}
|
||||||
|
|
||||||
fn hash_parts(parts: &[&[u8]]) -> [u8; 32] {
|
fn hash_parts(parts: &[&[u8]]) -> [u8; 32] {
|
||||||
let mut hasher = Sha256::new();
|
let mut hasher = Sha256::new();
|
||||||
for part in parts {
|
for part in parts {
|
||||||
|
|
@ -910,8 +934,34 @@ fn secure_resolve() -> ResolveFlags {
|
||||||
mod fixed_directory_tests {
|
mod fixed_directory_tests {
|
||||||
use std::os::unix::fs::PermissionsExt;
|
use std::os::unix::fs::PermissionsExt;
|
||||||
|
|
||||||
|
use crate::layer::IdMapRange;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn id_map_identity_encoding_is_explicit_and_fixed() {
|
||||||
|
let encoded = canonical_id_map_bytes(&IdMap {
|
||||||
|
uid: vec![IdMapRange {
|
||||||
|
container_id: 1,
|
||||||
|
namespace_id: 2,
|
||||||
|
size: 3,
|
||||||
|
}],
|
||||||
|
gid: vec![IdMapRange {
|
||||||
|
container_id: 4,
|
||||||
|
namespace_id: 5,
|
||||||
|
size: 6,
|
||||||
|
}],
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
encoded,
|
||||||
|
[
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1,
|
||||||
|
0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 6,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn prepared_lower_root_requires_invoking_owner_and_exact_private_mode() {
|
fn prepared_lower_root_requires_invoking_owner_and_exact_private_mode() {
|
||||||
let directory = tempfile::tempdir().unwrap();
|
let directory = tempfile::tempdir().unwrap();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue