Merge pull request #177 from nix-community/rustfmt

Add rustfmt checks
This commit is contained in:
Ryan Lahfa 2023-05-18 18:46:52 +02:00 committed by GitHub
commit 354ec6f451
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 129 additions and 79 deletions

View File

@ -124,6 +124,8 @@
inherit cargoArtifacts; inherit cargoArtifacts;
cargoClippyExtraArgs = "-- --deny warnings"; cargoClippyExtraArgs = "-- --deny warnings";
}); });
rustfmt = craneLib.cargoFmt (commonArgs // { inherit cargoArtifacts; });
}; };
stubCrane = buildRustApp { stubCrane = buildRustApp {
@ -174,6 +176,8 @@
checks = { checks = {
toolClippy = toolCrane.clippy; toolClippy = toolCrane.clippy;
stubClippy = stubCrane.clippy; stubClippy = stubCrane.clippy;
toolFmt = toolCrane.rustfmt;
stubFmt = stubCrane.rustfmt;
} // (import ./nix/tests/lanzaboote.nix { } // (import ./nix/tests/lanzaboote.nix {
inherit pkgs; inherit pkgs;
lanzabooteModule = self.nixosModules.lanzaboote; lanzabooteModule = self.nixosModules.lanzaboote;

View File

@ -1,5 +1,21 @@
use alloc::{vec::Vec, vec, string::ToString, format}; use alloc::{format, string::ToString, vec, vec::Vec};
use uefi::{Result, Handle, prelude::{BootServices, RuntimeServices}, proto::{device_path::{DevicePath, media::{HardDrive, PartitionSignature}, DeviceType, DeviceSubType, text::DevicePathToText}, loaded_image::LoadedImage}, Guid, guid, table::{runtime::{VariableVendor, VariableAttributes}, SystemTable, Boot}, cstr16, CStr16}; use uefi::{
cstr16, guid,
prelude::{BootServices, RuntimeServices},
proto::{
device_path::{
media::{HardDrive, PartitionSignature},
text::DevicePathToText,
DevicePath, DeviceSubType, DeviceType,
},
loaded_image::LoadedImage,
},
table::{
runtime::{VariableAttributes, VariableVendor},
Boot, SystemTable,
},
CStr16, Guid, Handle, Result,
};
use bitflags::bitflags; use bitflags::bitflags;
@ -7,7 +23,9 @@ fn disk_get_part_uuid(boot_services: &BootServices, disk_handle: Handle) -> Resu
let dp = boot_services.open_protocol_exclusive::<DevicePath>(disk_handle)?; let dp = boot_services.open_protocol_exclusive::<DevicePath>(disk_handle)?;
for node in dp.node_iter() { for node in dp.node_iter() {
if node.device_type() != DeviceType::MEDIA || node.sub_type() != DeviceSubType::MEDIA_HARD_DRIVE { if node.device_type() != DeviceType::MEDIA
|| node.sub_type() != DeviceSubType::MEDIA_HARD_DRIVE
{
continue; continue;
} }
@ -21,12 +39,12 @@ fn disk_get_part_uuid(boot_services: &BootServices, disk_handle: Handle) -> Resu
Err(uefi::Status::UNSUPPORTED.into()) Err(uefi::Status::UNSUPPORTED.into())
} }
/// systemd loader's GUID /// systemd loader's GUID
/// != systemd's GUID /// != systemd's GUID
/// https://github.com/systemd/systemd/blob/main/src/boot/efi/util.h#L114-L121 /// https://github.com/systemd/systemd/blob/main/src/boot/efi/util.h#L114-L121
/// https://systemd.io/BOOT_LOADER_INTERFACE/ /// https://systemd.io/BOOT_LOADER_INTERFACE/
pub const BOOT_LOADER_VENDOR_UUID: VariableVendor = VariableVendor(guid!("4a67b082-0a4c-41cf-b6c7-440b29bb8c4f")); pub const BOOT_LOADER_VENDOR_UUID: VariableVendor =
VariableVendor(guid!("4a67b082-0a4c-41cf-b6c7-440b29bb8c4f"));
/// Lanzaboote stub name /// Lanzaboote stub name
pub static STUB_INFO_STRING: &str = concat!("lanzastub ", env!("CARGO_PKG_VERSION")); pub static STUB_INFO_STRING: &str = concat!("lanzastub ", env!("CARGO_PKG_VERSION"));
@ -54,17 +72,20 @@ bitflags! {
/// Get the currently supported EFI features from the loader if they do exist /// Get the currently supported EFI features from the loader if they do exist
/// https://systemd.io/BOOT_LOADER_INTERFACE/ /// https://systemd.io/BOOT_LOADER_INTERFACE/
pub fn get_loader_features(runtime_services: &RuntimeServices) -> Result<EfiLoaderFeatures> { pub fn get_loader_features(runtime_services: &RuntimeServices) -> Result<EfiLoaderFeatures> {
if let Ok(size) = runtime_services.get_variable_size(cstr16!("LoaderFeatures"), &BOOT_LOADER_VENDOR_UUID) { if let Ok(size) =
runtime_services.get_variable_size(cstr16!("LoaderFeatures"), &BOOT_LOADER_VENDOR_UUID)
{
let mut buffer = vec![0; size].into_boxed_slice(); let mut buffer = vec![0; size].into_boxed_slice();
runtime_services.get_variable( runtime_services.get_variable(
cstr16!("LoaderFeatures"), cstr16!("LoaderFeatures"),
&BOOT_LOADER_VENDOR_UUID, &BOOT_LOADER_VENDOR_UUID,
&mut buffer)?; &mut buffer,
)?;
return EfiLoaderFeatures::from_bits( return EfiLoaderFeatures::from_bits(u64::from_le_bytes(
u64::from_le_bytes( (*buffer)
(*buffer).try_into() .try_into()
.map_err(|_err| uefi::Status::BAD_BUFFER_SIZE)? .map_err(|_err| uefi::Status::BAD_BUFFER_SIZE)?,
)) ))
.ok_or_else(|| uefi::Status::INCOMPATIBLE_VERSION.into()); .ok_or_else(|| uefi::Status::INCOMPATIBLE_VERSION.into());
} }
@ -106,21 +127,19 @@ pub fn cstr16_to_bytes(s: &CStr16) -> &[u8] {
/// Ensures that an UEFI variable is set or set it with a fallback value /// Ensures that an UEFI variable is set or set it with a fallback value
/// computed in a lazy way. /// computed in a lazy way.
pub fn ensure_efi_variable<F>(runtime_services: &RuntimeServices, pub fn ensure_efi_variable<F>(
runtime_services: &RuntimeServices,
name: &CStr16, name: &CStr16,
vendor: &VariableVendor, vendor: &VariableVendor,
attributes: VariableAttributes, attributes: VariableAttributes,
get_fallback_value: F) -> uefi::Result get_fallback_value: F,
where F: FnOnce() -> uefi::Result<Vec<u8>> ) -> uefi::Result
where
F: FnOnce() -> uefi::Result<Vec<u8>>,
{ {
// If we get a variable size, a variable already exist. // If we get a variable size, a variable already exist.
if runtime_services.get_variable_size(name, vendor).is_err() { if runtime_services.get_variable_size(name, vendor).is_err() {
runtime_services.set_variable( runtime_services.set_variable(name, vendor, attributes, &get_fallback_value()?)?;
name,
vendor,
attributes,
&get_fallback_value()?
)?;
} }
uefi::Status::SUCCESS.into() uefi::Status::SUCCESS.into()
@ -131,91 +150,115 @@ pub fn export_efi_variables(system_table: &SystemTable<Boot>) -> Result<()> {
let boot_services = system_table.boot_services(); let boot_services = system_table.boot_services();
let runtime_services = system_table.runtime_services(); let runtime_services = system_table.runtime_services();
let stub_features: EfiStubFeatures = let stub_features: EfiStubFeatures = EfiStubFeatures::ReportBootPartition;
EfiStubFeatures::ReportBootPartition;
let loaded_image = let loaded_image =
boot_services.open_protocol_exclusive::<LoadedImage>(boot_services.image_handle())?; boot_services.open_protocol_exclusive::<LoadedImage>(boot_services.image_handle())?;
let default_attributes = VariableAttributes::BOOTSERVICE_ACCESS | VariableAttributes::RUNTIME_ACCESS; let default_attributes =
VariableAttributes::BOOTSERVICE_ACCESS | VariableAttributes::RUNTIME_ACCESS;
#[allow(unused_must_use)] #[allow(unused_must_use)]
// LoaderDevicePartUUID // LoaderDevicePartUUID
ensure_efi_variable(runtime_services, ensure_efi_variable(
runtime_services,
cstr16!("LoaderDevicePartUUID"), cstr16!("LoaderDevicePartUUID"),
&BOOT_LOADER_VENDOR_UUID, &BOOT_LOADER_VENDOR_UUID,
default_attributes, default_attributes,
|| disk_get_part_uuid(boot_services, loaded_image.device()).map(|guid| guid.to_string() || {
disk_get_part_uuid(boot_services, loaded_image.device()).map(|guid| {
guid.to_string()
.encode_utf16() .encode_utf16()
.flat_map(|c| c.to_le_bytes()) .flat_map(|c| c.to_le_bytes())
.collect::<Vec<u8>>() .collect::<Vec<u8>>()
})
},
) )
).ok(); .ok();
// LoaderImageIdentifier // LoaderImageIdentifier
ensure_efi_variable(runtime_services, ensure_efi_variable(
runtime_services,
cstr16!("LoaderImageIdentifier"), cstr16!("LoaderImageIdentifier"),
&BOOT_LOADER_VENDOR_UUID, &BOOT_LOADER_VENDOR_UUID,
default_attributes, default_attributes,
|| { || {
if let Some(dp) = loaded_image.file_path() { if let Some(dp) = loaded_image.file_path() {
let dp_protocol = boot_services.open_protocol_exclusive::<DevicePathToText>( let dp_protocol = boot_services.open_protocol_exclusive::<DevicePathToText>(
boot_services.get_handle_for_protocol::<DevicePathToText>()? boot_services.get_handle_for_protocol::<DevicePathToText>()?,
)?; )?;
dp_protocol.convert_device_path_to_text( dp_protocol
.convert_device_path_to_text(
boot_services, boot_services,
dp, dp,
uefi::proto::device_path::text::DisplayOnly(false), uefi::proto::device_path::text::DisplayOnly(false),
uefi::proto::device_path::text::AllowShortcuts(false) uefi::proto::device_path::text::AllowShortcuts(false),
).map(|ps| cstr16_to_bytes(&ps).to_vec()) )
.map(|ps| cstr16_to_bytes(&ps).to_vec())
} else { } else {
// If we cannot retrieve the filepath of the loaded image // If we cannot retrieve the filepath of the loaded image
// Then, we cannot set `LoaderImageIdentifier`. // Then, we cannot set `LoaderImageIdentifier`.
Err(uefi::Status::UNSUPPORTED.into()) Err(uefi::Status::UNSUPPORTED.into())
} }
}).ok(); },
)
.ok();
// LoaderFirmwareInfo // LoaderFirmwareInfo
ensure_efi_variable(runtime_services, ensure_efi_variable(
runtime_services,
cstr16!("LoaderFirmwareInfo"), cstr16!("LoaderFirmwareInfo"),
&BOOT_LOADER_VENDOR_UUID, &BOOT_LOADER_VENDOR_UUID,
default_attributes, default_attributes,
|| Ok( || {
format!("{} {}.{:02}", system_table.firmware_vendor(), system_table.firmware_revision() >> 16, system_table.firmware_revision() & 0xFFFFF) Ok(format!(
"{} {}.{:02}",
system_table.firmware_vendor(),
system_table.firmware_revision() >> 16,
system_table.firmware_revision() & 0xFFFFF
)
.encode_utf16() .encode_utf16()
.flat_map(|c| c.to_le_bytes()) .flat_map(|c| c.to_le_bytes())
.collect::<Vec<u8>>() .collect::<Vec<u8>>())
},
) )
).ok(); .ok();
// LoaderFirmwareType // LoaderFirmwareType
ensure_efi_variable(runtime_services, ensure_efi_variable(
runtime_services,
cstr16!("LoaderFirmwareType"), cstr16!("LoaderFirmwareType"),
&BOOT_LOADER_VENDOR_UUID, &BOOT_LOADER_VENDOR_UUID,
default_attributes, default_attributes,
|| Ok( || {
format!("UEFI {:02}", system_table.uefi_revision()) Ok(format!("UEFI {:02}", system_table.uefi_revision())
.encode_utf16() .encode_utf16()
.flat_map(|c| c.to_le_bytes()) .flat_map(|c| c.to_le_bytes())
.collect::<Vec<u8>>() .collect::<Vec<u8>>())
},
) )
).ok(); .ok();
// StubInfo // StubInfo
// FIXME: ideally, no one should be able to overwrite `StubInfo`, but that would require // FIXME: ideally, no one should be able to overwrite `StubInfo`, but that would require
// constructing an EFI authenticated variable payload. This seems overcomplicated for now. // constructing an EFI authenticated variable payload. This seems overcomplicated for now.
runtime_services.set_variable( runtime_services
.set_variable(
cstr16!("StubInfo"), cstr16!("StubInfo"),
&BOOT_LOADER_VENDOR_UUID, &BOOT_LOADER_VENDOR_UUID,
default_attributes, default_attributes,
&STUB_INFO_STRING.encode_utf16().flat_map(|c| c.to_le_bytes()).collect::<Vec<u8>>() &STUB_INFO_STRING
).ok(); .encode_utf16()
.flat_map(|c| c.to_le_bytes())
.collect::<Vec<u8>>(),
)
.ok();
// StubFeatures // StubFeatures
runtime_services.set_variable( runtime_services
.set_variable(
cstr16!("StubFeatures"), cstr16!("StubFeatures"),
&BOOT_LOADER_VENDOR_UUID, &BOOT_LOADER_VENDOR_UUID,
default_attributes, default_attributes,
&stub_features.bits().to_le_bytes() &stub_features.bits().to_le_bytes(),
).ok(); )
.ok();
Ok(()) Ok(())
} }

View File

@ -4,14 +4,15 @@
extern crate alloc; extern crate alloc;
mod efivars;
mod linux_loader; mod linux_loader;
mod pe_loader; mod pe_loader;
mod pe_section; mod pe_section;
mod uefi_helpers; mod uefi_helpers;
mod efivars;
use alloc::vec::Vec; use alloc::vec::Vec;
use log::{info, warn, debug}; use efivars::{export_efi_variables, get_loader_features, EfiLoaderFeatures};
use log::{debug, info, warn};
use pe_loader::Image; use pe_loader::Image;
use pe_section::{pe_section, pe_section_as_string}; use pe_section::{pe_section, pe_section_as_string};
use sha2::{Digest, Sha256}; use sha2::{Digest, Sha256};
@ -23,7 +24,6 @@ use uefi::{
}, },
CStr16, CString16, Result, CStr16, CString16, Result,
}; };
use efivars::{EfiLoaderFeatures, export_efi_variables, get_loader_features};
use crate::{ use crate::{
linux_loader::InitrdLoader, linux_loader::InitrdLoader,
@ -244,8 +244,7 @@ fn main(handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
debug!("Random seed is available, but lanzaboote does not support it yet."); debug!("Random seed is available, but lanzaboote does not support it yet.");
} }
} }
export_efi_variables(&system_table) export_efi_variables(&system_table).expect("Failed to export stub EFI variables");
.expect("Failed to export stub EFI variables");
if is_kernel_hash_correct && is_initrd_hash_correct { if is_kernel_hash_correct && is_initrd_hash_correct {
boot_linux_unchecked( boot_linux_unchecked(

View File

@ -4,9 +4,9 @@ use std::os::unix::fs::MetadataExt;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use anyhow::{anyhow, Context, Result}; use anyhow::{anyhow, Context, Result};
use bootspec::BootSpec;
use bootspec::BootJson;
use bootspec::generation::Generation as BootspecGeneration; use bootspec::generation::Generation as BootspecGeneration;
use bootspec::BootJson;
use bootspec::BootSpec;
use bootspec::SpecialisationName; use bootspec::SpecialisationName;
use time::Date; use time::Date;
@ -55,7 +55,7 @@ impl Generation {
// TODO: replace me when https://github.com/DeterminateSystems/bootspec/pull/109 lands. // TODO: replace me when https://github.com/DeterminateSystems/bootspec/pull/109 lands.
let bootspec: BootSpec = match boot_json.generation { let bootspec: BootSpec = match boot_json.generation {
BootspecGeneration::V1(bootspec) => bootspec, BootspecGeneration::V1(bootspec) => bootspec,
_ => return Err(anyhow!("Unsupported bootspec schema")) _ => return Err(anyhow!("Unsupported bootspec schema")),
}; };
Ok(Self { Ok(Self {
@ -104,7 +104,8 @@ impl fmt::Display for Generation {
} }
fn read_build_time(path: &Path) -> Result<Date> { fn read_build_time(path: &Path) -> Result<Date> {
let build_time = time::OffsetDateTime::from_unix_timestamp(fs::symlink_metadata(path)?.mtime())?.date(); let build_time =
time::OffsetDateTime::from_unix_timestamp(fs::symlink_metadata(path)?.mtime())?.date();
Ok(build_time) Ok(build_time)
} }

View File

@ -26,7 +26,10 @@ impl OsRelease {
// Because the ID field here does not have the same meaning as in a real os-release file, // Because the ID field here does not have the same meaning as in a real os-release file,
// it is fine to use a dummy value. // it is fine to use a dummy value.
map.insert("ID".into(), String::from("lanza")); map.insert("ID".into(), String::from("lanza"));
map.insert("PRETTY_NAME".into(), generation.spec.bootspec.bootspec.label.clone()); map.insert(
"PRETTY_NAME".into(),
generation.spec.bootspec.bootspec.label.clone(),
);
map.insert("VERSION_ID".into(), generation.describe()); map.insert("VERSION_ID".into(), generation.describe());
Ok(Self(map)) Ok(Self(map))