apt/keyring: keep the keyring cache readable
A fresh chroot download failed with mmdebstrap unable to copy the keyrings: its unshare-mode hooks run under an identity that cannot read the invoking user's private directories, so the 0700 cache directory the module created broke the trusted.gpg.d setup hook with 'Permission denied' (builds reusing an already-cached tarball never hit the path). Create the cache 0755 and chmod the keyrings 0644 instead. The planting guard does not weaken: cached keyrings are trusted as-is, and validate_keyring_dir keeps refusing directories that are not owned by the current user or are writable by group or others — read access for the bootstrap tool is not a planting vector. Legacy 0700 cache directories are validated as before, then widened.
This commit is contained in:
+21
-9
@@ -89,24 +89,27 @@ pub async fn download_cache_keyrings(
|
|||||||
keyring_dir.display()
|
keyring_dir.display()
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
// Upgrade cache directories created by versions that made them
|
||||||
|
// private: mmdebstrap's unshare-mode hooks cannot read them.
|
||||||
} else {
|
} else {
|
||||||
// Remote contexts (e.g. ssh) have no stat/metadata access through
|
// Remote contexts (e.g. ssh) have no stat/metadata access through
|
||||||
// the context API, so the ownership guard cannot be performed;
|
// the context API, so the ownership guard cannot be performed;
|
||||||
// keep the previous best-effort behavior of tightening the
|
// keep the previous best-effort behavior of tightening the
|
||||||
// directory permissions instead (0700 instead of the former
|
// directory permissions instead (no group/others write).
|
||||||
// world-writable a+rwx).
|
|
||||||
ctx.command("chmod").arg("700").arg(&keyring_dir).status()?;
|
|
||||||
}
|
}
|
||||||
|
ctx.command("chmod").arg("755").arg(&keyring_dir).status()?;
|
||||||
} else {
|
} else {
|
||||||
// Create the directory private to the invoking user (0700). This is
|
// Create the directory readable but not writable by group/others.
|
||||||
// sufficient for mmdebstrap in unshare mode: it runs with the same
|
// mmdebstrap's unshare-mode hooks run under an identity that cannot
|
||||||
// real uid (the user namespace only maps that uid to root, file
|
// read the invoking user's private directories, so 0700 breaks the
|
||||||
// access still happens as the real uid), so no world-accessible
|
// keyring copy into the chroot; the planting guard stays on the
|
||||||
// permissions are needed.
|
// ownership and no-write checks of validate_keyring_dir (the
|
||||||
|
// skip-if-exists logic below trusts pre-existing keyrings, so the
|
||||||
|
// directory must never be writable by anyone else).
|
||||||
ctx.command("mkdir")
|
ctx.command("mkdir")
|
||||||
.arg("-p")
|
.arg("-p")
|
||||||
.arg("-m")
|
.arg("-m")
|
||||||
.arg("700")
|
.arg("755")
|
||||||
.arg(&keyring_dir)
|
.arg(&keyring_dir)
|
||||||
.status()?;
|
.status()?;
|
||||||
}
|
}
|
||||||
@@ -178,6 +181,11 @@ pub async fn download_cache_keyrings(
|
|||||||
binary_path.display()
|
binary_path.display()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Readable like the directory: mmdebstrap's hooks copy these into
|
||||||
|
// the chroot. Applies to legacy files too, which a restrictive
|
||||||
|
// umask may have left private, and a permissive one group-writable.
|
||||||
|
let _ = ctx.command("chmod").arg("644").arg(&binary_path).status();
|
||||||
}
|
}
|
||||||
|
|
||||||
log::info!(
|
log::info!(
|
||||||
@@ -348,6 +356,10 @@ mod tests {
|
|||||||
assert!(validate_keyring_dir(1000, 0o750, 1000).is_ok());
|
assert!(validate_keyring_dir(1000, 0o750, 1000).is_ok());
|
||||||
assert!(validate_keyring_dir(1000, 0o1744, 1000).is_ok());
|
assert!(validate_keyring_dir(1000, 0o1744, 1000).is_ok());
|
||||||
assert!(validate_keyring_dir(0, 0o700, 0).is_ok());
|
assert!(validate_keyring_dir(0, 0o700, 0).is_ok());
|
||||||
|
// The world-readable modes the cache now uses: readable so that
|
||||||
|
// mmdebstrap's unshare-mode hooks can copy the keyrings, while the
|
||||||
|
// ownership and no-write checks keep the planting guard.
|
||||||
|
assert!(validate_keyring_dir(1000, 0o755, 1000).is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
Reference in New Issue
Block a user