stub: load companions #306
No reviewers
Labels
No labels
bug
dependency
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
review-next
security
stub
tool
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: raito/lanzaboote#306
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "stub-loads-companions"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
This makes use of the pio library to discover, charge, measures companions.
Depends on the dynamic initrds PR: https://github.com/nix-community/lanzaboote/pull/305.
I want to cry, I force pushed this thing, but it seems to have no effect.
Generally looks fine, didn't look into it in too in depth because it's new functionality. I'll defer the final review to @blitz.
This needs some more context, for example why is it called
pad4
?The code has lots of panics. Is it possible to have warnings instead and return
Err
?Feel free to ignore the code suggestions, if they don't make sense to you or result in too much refactoring.
nit: Can you leave a comment when this can go away?
Clippy should complain about this (superfluous return). Isn't it?
Why do we panic here? I don't understand the comment.
metadata.is_directory().then_some(|| PathBuf::from(target_directory)
Should we convert the CPIO errors into uefi errors and return instead of panicking? Same below.
It's weird to have an enum that has exactly the same payload for all variants. This also leads you to implement the awkward
into_cpio
function below. Maybe:Maybe better:
We should not panic here, but propagate the error.
This function and the calling code might become simpler if you split this function into
discover_global_credentials
anddiscover_local_credentials
.@ -0,0 +20,4 @@
) -> uefi::Result<Vec<PathBuf>> {
let mut results = Vec::new();
for maybe_entry in fs.read_dir(search_path).unwrap() {
Shouldn't this propagate the error instead of panicking?
nit: This would be easier to read as
read_dir().iter().filter().map().collect()
@ -0,0 +137,4 @@
/// Discover any system image extension, i.e. files ending by .raw
/// They must be present inside $path_to_image.extra/*.raw, specific to this image.
///
/// Those will be unmeasured, you are responsible for measuring them or not.
"The extensions are not measured."
@ -0,0 +141,4 @@
/// But CPIOs are guaranteed to be stable and independent of file discovery order.
pub fn discover_system_extensions(
fs: &mut uefi::fs::FileSystem,
default_dropin_dir: &Path,
Why is this parameter optional above and not here?
"The order of companions matters for the measurement. The caller is responsible for a stable order."
I would suggest making a pass through the code and removing all mentions of "you" from the docstrings.
@ -71,0 +112,4 @@
credentials_measured += 1;
}
}
CompanionInitrdType::GlobalCredentials => {
nit: If you filter the irrelevant initds from the vector before iterating, you can simplify this a bit.
measurements
doesn't have to be imperatively computed, but is then justrelevant_initrds.len()
. Might not be worth it, but maybe there is a way to make this function less C-like and remove the mutable state for easier reading.@ -69,2 +71,3 @@
}
export_efi_variables(STUB_NAME, &system_table).expect("Failed to export stub EFI variables");
if export_efi_variables(STUB_NAME, &system_table).is_err() {
Could maybe be simmplified to:
This would also remove the panic.
This function also panics a lot. Is it necessary and can't we propagate the errors instead?
And it could just return
Vec<u8>
, because this can already represent not having to add padding by returning an empty vector and thus simplifying calling code.vec![0u8; (4 - (len % 4)) % 4]
?@ -0,0 +20,4 @@
) -> uefi::Result<Vec<PathBuf>> {
let mut results = Vec::new();
for maybe_entry in fs.read_dir(search_path).unwrap() {
So re-encoding the FileSystemError into
uefi::Result
is quite difficult because the enum is Io, Path or Utf8Encoding and it's probably going to be very unhelpful to eat the low level errors into high level errors that will produce difficult to debug code IMHO. A better solution would be to have ways to propagate the original error up but there's impedence mismatch with our error management here.Nope
But addressed
The comment is outdated, please ignore.
There's four sources of panic:
So those are low level errors that have no chance for recovery in the current way our code is structured, it seems better to me that our panic handler catch them and report them fully rather than silencing them.
So interestingly, this doesn't work because:
So I don't know if I'm fucking up somewhere but I'm not so sure if there is not a closure capturing problem.
Yep, addressed.
I can return an LOAD_ERROR but not very sure if that's a good idea for debuggability given that our logging facilities are quite bad.
I kind of want to make a remark that
you
appears in your docstrings for the initrd loader ;) -- but sure, done.@ -0,0 +141,4 @@
/// But CPIOs are guaranteed to be stable and independent of file discovery order.
pub fn discover_system_extensions(
fs: &mut uefi::fs::FileSystem,
default_dropin_dir: &Path,
If there's no dropin directory for system extensions, there's no attempt to load them.
If there's no dropin directory for systemd credentials, we can still try to load them from a default dropin directory location.
We can make both of them take &Path and put the default inside of the caller site if we want but that's weird because the logic comes from the function itself.
@ -69,2 +71,3 @@
}
export_efi_variables(STUB_NAME, &system_table).expect("Failed to export stub EFI variables");
if export_efi_variables(STUB_NAME, &system_table).is_err() {
Fixed.
@ -69,2 +71,3 @@
}
export_efi_variables(STUB_NAME, &system_table).expect("Failed to export stub EFI variables");
if export_efi_variables(STUB_NAME, &system_table).is_err() {
Fixed.
Done.
Fixed, it was
then
, notthen_some
.Fixed.
Fixed.
Done.
Done for returning just a Vec.