Skip to content

Commit 13113d8

Browse files
composefs/uki: Save boot digest
Similar to what we do with Type1 entries, we save the SHA256Sum of .linux + .initrd sections of the UKI under `boot_digest` key in the origin file Signed-off-by: Pragyan Poudyal <[email protected]>
1 parent 969dfd4 commit 13113d8

File tree

2 files changed

+62
-44
lines changed

2 files changed

+62
-44
lines changed

crates/lib/src/bootc_composefs/boot.rs

Lines changed: 53 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,30 @@ fn compute_boot_digest(
338338
Ok(hex::encode(digest))
339339
}
340340

341+
/// Compute SHA256Sum of .linux + .initrd section of the UKI
342+
///
343+
/// # Arguments
344+
/// * entry - BootEntry containing VMlinuz and Initrd
345+
/// * repo - The composefs repository
346+
#[context("Computing boot digest")]
347+
pub(crate) fn compute_boot_digest_uki(uki: &[u8]) -> Result<String> {
348+
let vmlinuz = composefs_boot::uki::get_section(uki, ".linux")
349+
.ok_or_else(|| anyhow::anyhow!(".linux not present"))??;
350+
351+
let initramfs = composefs_boot::uki::get_section(uki, ".initrd")
352+
.ok_or_else(|| anyhow::anyhow!(".initrd not present"))??;
353+
354+
let mut hasher = openssl::hash::Hasher::new(openssl::hash::MessageDigest::sha256())
355+
.context("Creating hasher")?;
356+
357+
hasher.update(&vmlinuz).context("hashing vmlinuz")?;
358+
hasher.update(&initramfs).context("hashing initrd")?;
359+
360+
let digest: &[u8] = &hasher.finish().context("Finishing digest")?;
361+
362+
Ok(hex::encode(digest))
363+
}
364+
341365
/// Given the SHA256 sum of current VMlinuz + Initrd combo, find boot entry with the same SHA256Sum
342366
///
343367
/// # Returns
@@ -773,10 +797,11 @@ pub(crate) fn setup_composefs_bls_boot(
773797
Ok(boot_digest)
774798
}
775799

776-
struct UKILabels {
800+
struct UKIInfo {
777801
boot_label: String,
778802
version: Option<String>,
779803
os_id: Option<String>,
804+
boot_digest: String,
780805
}
781806

782807
/// Writes a PortableExecutable to ESP along with any PE specific or Global addons
@@ -790,10 +815,10 @@ fn write_pe_to_esp(
790815
is_insecure_from_opts: bool,
791816
mounted_efi: impl AsRef<Path>,
792817
bootloader: &Bootloader,
793-
) -> Result<Option<UKILabels>> {
818+
) -> Result<Option<UKIInfo>> {
794819
let efi_bin = read_file(file, &repo).context("Reading .efi binary")?;
795820

796-
let mut boot_label: Option<UKILabels> = None;
821+
let mut boot_label: Option<UKIInfo> = None;
797822

798823
// UKI Extension might not even have a cmdline
799824
// TODO: UKI Addon might also have a composefs= cmdline?
@@ -828,10 +853,13 @@ fn write_pe_to_esp(
828853

829854
let parsed_osrel = OsReleaseInfo::parse(osrel);
830855

831-
boot_label = Some(UKILabels {
856+
let boot_digest = compute_boot_digest_uki(&efi_bin)?;
857+
858+
boot_label = Some(UKIInfo {
832859
boot_label: uki::get_boot_label(&efi_bin).context("Getting UKI boot label")?,
833860
version: parsed_osrel.get_version(),
834861
os_id: parsed_osrel.get_value(&["ID"]),
862+
boot_digest,
835863
});
836864
}
837865

@@ -981,7 +1009,7 @@ fn write_grub_uki_menuentry(
9811009
fn write_systemd_uki_config(
9821010
esp_dir: &Dir,
9831011
setup_type: &BootSetupType,
984-
boot_label: UKILabels,
1012+
boot_label: UKIInfo,
9851013
id: &Sha512HashValue,
9861014
) -> Result<()> {
9871015
let os_id = boot_label.os_id.as_deref().unwrap_or("bootc");
@@ -1052,7 +1080,7 @@ pub(crate) fn setup_composefs_uki_boot(
10521080
repo: crate::store::ComposefsRepository,
10531081
id: &Sha512HashValue,
10541082
entries: Vec<ComposefsBootEntry<Sha512HashValue>>,
1055-
) -> Result<()> {
1083+
) -> Result<String> {
10561084
let (root_path, esp_device, bootloader, is_insecure_from_opts, uki_addons) = match setup_type {
10571085
BootSetupType::Setup((root_setup, state, postfetch, ..)) => {
10581086
state.require_no_kargs_for_uki()?;
@@ -1085,7 +1113,7 @@ pub(crate) fn setup_composefs_uki_boot(
10851113

10861114
let esp_mount = mount_esp(&esp_device).context("Mounting ESP")?;
10871115

1088-
let mut uki_label: Option<UKILabels> = None;
1116+
let mut uki_info: Option<UKIInfo> = None;
10891117

10901118
for entry in entries {
10911119
match entry {
@@ -1134,28 +1162,26 @@ pub(crate) fn setup_composefs_uki_boot(
11341162
)?;
11351163

11361164
if let Some(label) = ret {
1137-
uki_label = Some(label);
1165+
uki_info = Some(label);
11381166
}
11391167
}
11401168
};
11411169
}
11421170

1143-
let uki_label = uki_label
1144-
.ok_or_else(|| anyhow::anyhow!("Failed to get version and boot label from UKI"))?;
1171+
let uki_info =
1172+
uki_info.ok_or_else(|| anyhow::anyhow!("Failed to get version and boot label from UKI"))?;
1173+
1174+
let boot_digest = uki_info.boot_digest.clone();
11451175

11461176
match bootloader {
1147-
Bootloader::Grub => write_grub_uki_menuentry(
1148-
root_path,
1149-
&setup_type,
1150-
uki_label.boot_label,
1151-
id,
1152-
&esp_device,
1153-
)?,
1177+
Bootloader::Grub => {
1178+
write_grub_uki_menuentry(root_path, &setup_type, uki_info.boot_label, id, &esp_device)?
1179+
}
11541180

1155-
Bootloader::Systemd => write_systemd_uki_config(&esp_mount.fd, &setup_type, uki_label, id)?,
1181+
Bootloader::Systemd => write_systemd_uki_config(&esp_mount.fd, &setup_type, uki_info, id)?,
11561182
};
11571183

1158-
Ok(())
1184+
Ok(boot_digest)
11591185
}
11601186

11611187
pub struct SecurebootKeys {
@@ -1252,20 +1278,15 @@ pub(crate) async fn setup_composefs_boot(
12521278
};
12531279

12541280
let boot_type = BootType::from(entry);
1255-
let mut boot_digest: Option<String> = None;
1256-
1257-
match boot_type {
1258-
BootType::Bls => {
1259-
let digest = setup_composefs_bls_boot(
1260-
BootSetupType::Setup((&root_setup, &state, &postfetch, &fs)),
1261-
repo,
1262-
&id,
1263-
entry,
1264-
&mounted_fs,
1265-
)?;
12661281

1267-
boot_digest = Some(digest);
1268-
}
1282+
let boot_digest = match boot_type {
1283+
BootType::Bls => setup_composefs_bls_boot(
1284+
BootSetupType::Setup((&root_setup, &state, &postfetch, &fs)),
1285+
repo,
1286+
&id,
1287+
entry,
1288+
&mounted_fs,
1289+
)?,
12691290
BootType::Uki => setup_composefs_uki_boot(
12701291
BootSetupType::Setup((&root_setup, &state, &postfetch, &fs)),
12711292
repo,

crates/lib/src/bootc_composefs/update.rs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -240,18 +240,15 @@ pub(crate) async fn do_upgrade(
240240
)?;
241241

242242
let boot_type = BootType::from(entry);
243-
let mut boot_digest = None;
244-
245-
match boot_type {
246-
BootType::Bls => {
247-
boot_digest = Some(setup_composefs_bls_boot(
248-
BootSetupType::Upgrade((storage, &fs, &host)),
249-
repo,
250-
&id,
251-
entry,
252-
&mounted_fs,
253-
)?)
254-
}
243+
244+
let boot_digest = match boot_type {
245+
BootType::Bls => setup_composefs_bls_boot(
246+
BootSetupType::Upgrade((storage, &fs, &host)),
247+
repo,
248+
&id,
249+
entry,
250+
&mounted_fs,
251+
)?,
255252

256253
BootType::Uki => setup_composefs_uki_boot(
257254
BootSetupType::Upgrade((storage, &fs, &host)),

0 commit comments

Comments
 (0)