Skip to content

Commit e0f64c5

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 <pragyanpoudyal41999@gmail.com>
1 parent 8726297 commit e0f64c5

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
@@ -329,6 +329,30 @@ fn compute_boot_digest(
329329
Ok(hex::encode(digest))
330330
}
331331

332+
/// Compute SHA256Sum of .linux + .initrd section of the UKI
333+
///
334+
/// # Arguments
335+
/// * entry - BootEntry containing VMlinuz and Initrd
336+
/// * repo - The composefs repository
337+
#[context("Computing boot digest")]
338+
pub(crate) fn compute_boot_digest_uki(uki: &[u8]) -> Result<String> {
339+
let vmlinuz = composefs_boot::uki::get_section(uki, ".linux")
340+
.ok_or_else(|| anyhow::anyhow!(".linux not present"))??;
341+
342+
let initramfs = composefs_boot::uki::get_section(uki, ".initrd")
343+
.ok_or_else(|| anyhow::anyhow!(".initrd not present"))??;
344+
345+
let mut hasher = openssl::hash::Hasher::new(openssl::hash::MessageDigest::sha256())
346+
.context("Creating hasher")?;
347+
348+
hasher.update(&vmlinuz).context("hashing vmlinuz")?;
349+
hasher.update(&initramfs).context("hashing initrd")?;
350+
351+
let digest: &[u8] = &hasher.finish().context("Finishing digest")?;
352+
353+
Ok(hex::encode(digest))
354+
}
355+
332356
/// Given the SHA256 sum of current VMlinuz + Initrd combo, find boot entry with the same SHA256Sum
333357
///
334358
/// # Returns
@@ -756,10 +780,11 @@ pub(crate) fn setup_composefs_bls_boot(
756780
Ok(boot_digest)
757781
}
758782

759-
struct UKILabels {
783+
struct UKIInfo {
760784
boot_label: String,
761785
version: Option<String>,
762786
os_id: Option<String>,
787+
boot_digest: String,
763788
}
764789

765790
/// Writes a PortableExecutable to ESP along with any PE specific or Global addons
@@ -773,10 +798,10 @@ fn write_pe_to_esp(
773798
is_insecure_from_opts: bool,
774799
mounted_efi: impl AsRef<Path>,
775800
bootloader: &Bootloader,
776-
) -> Result<Option<UKILabels>> {
801+
) -> Result<Option<UKIInfo>> {
777802
let efi_bin = read_file(file, &repo).context("Reading .efi binary")?;
778803

779-
let mut boot_label: Option<UKILabels> = None;
804+
let mut boot_label: Option<UKIInfo> = None;
780805

781806
// UKI Extension might not even have a cmdline
782807
// TODO: UKI Addon might also have a composefs= cmdline?
@@ -811,10 +836,13 @@ fn write_pe_to_esp(
811836

812837
let parsed_osrel = OsReleaseInfo::parse(osrel);
813838

814-
boot_label = Some(UKILabels {
839+
let boot_digest = compute_boot_digest_uki(&efi_bin)?;
840+
841+
boot_label = Some(UKIInfo {
815842
boot_label: uki::get_boot_label(&efi_bin).context("Getting UKI boot label")?,
816843
version: parsed_osrel.get_version(),
817844
os_id: parsed_osrel.get_value(&["ID"]),
845+
boot_digest,
818846
});
819847
}
820848

@@ -964,7 +992,7 @@ fn write_grub_uki_menuentry(
964992
fn write_systemd_uki_config(
965993
esp_dir: &Dir,
966994
setup_type: &BootSetupType,
967-
boot_label: UKILabels,
995+
boot_label: UKIInfo,
968996
id: &Sha512HashValue,
969997
) -> Result<()> {
970998
let os_id = boot_label.os_id.as_deref().unwrap_or("bootc");
@@ -1035,7 +1063,7 @@ pub(crate) fn setup_composefs_uki_boot(
10351063
repo: crate::store::ComposefsRepository,
10361064
id: &Sha512HashValue,
10371065
entries: Vec<ComposefsBootEntry<Sha512HashValue>>,
1038-
) -> Result<()> {
1066+
) -> Result<String> {
10391067
let (root_path, esp_device, bootloader, is_insecure_from_opts, uki_addons) = match setup_type {
10401068
BootSetupType::Setup((root_setup, state, postfetch, ..)) => {
10411069
state.require_no_kargs_for_uki()?;
@@ -1068,7 +1096,7 @@ pub(crate) fn setup_composefs_uki_boot(
10681096

10691097
let esp_mount = mount_esp(&esp_device).context("Mounting ESP")?;
10701098

1071-
let mut uki_label: Option<UKILabels> = None;
1099+
let mut uki_info: Option<UKIInfo> = None;
10721100

10731101
for entry in entries {
10741102
match entry {
@@ -1117,28 +1145,26 @@ pub(crate) fn setup_composefs_uki_boot(
11171145
)?;
11181146

11191147
if let Some(label) = ret {
1120-
uki_label = Some(label);
1148+
uki_info = Some(label);
11211149
}
11221150
}
11231151
};
11241152
}
11251153

1126-
let uki_label = uki_label
1127-
.ok_or_else(|| anyhow::anyhow!("Failed to get version and boot label from UKI"))?;
1154+
let uki_info =
1155+
uki_info.ok_or_else(|| anyhow::anyhow!("Failed to get version and boot label from UKI"))?;
1156+
1157+
let boot_digest = uki_info.boot_digest.clone();
11281158

11291159
match bootloader {
1130-
Bootloader::Grub => write_grub_uki_menuentry(
1131-
root_path,
1132-
&setup_type,
1133-
uki_label.boot_label,
1134-
id,
1135-
&esp_device,
1136-
)?,
1160+
Bootloader::Grub => {
1161+
write_grub_uki_menuentry(root_path, &setup_type, uki_info.boot_label, id, &esp_device)?
1162+
}
11371163

1138-
Bootloader::Systemd => write_systemd_uki_config(&esp_mount.fd, &setup_type, uki_label, id)?,
1164+
Bootloader::Systemd => write_systemd_uki_config(&esp_mount.fd, &setup_type, uki_info, id)?,
11391165
};
11401166

1141-
Ok(())
1167+
Ok(boot_digest)
11421168
}
11431169

11441170
#[context("Setting up composefs boot")]
@@ -1188,20 +1214,15 @@ pub(crate) fn setup_composefs_boot(
11881214
};
11891215

11901216
let boot_type = BootType::from(entry);
1191-
let mut boot_digest: Option<String> = None;
1192-
1193-
match boot_type {
1194-
BootType::Bls => {
1195-
let digest = setup_composefs_bls_boot(
1196-
BootSetupType::Setup((&root_setup, &state, &postfetch, &fs)),
1197-
repo,
1198-
&id,
1199-
entry,
1200-
&mounted_fs,
1201-
)?;
12021217

1203-
boot_digest = Some(digest);
1204-
}
1218+
let boot_digest = match boot_type {
1219+
BootType::Bls => setup_composefs_bls_boot(
1220+
BootSetupType::Setup((&root_setup, &state, &postfetch, &fs)),
1221+
repo,
1222+
&id,
1223+
entry,
1224+
&mounted_fs,
1225+
)?,
12051226
BootType::Uki => setup_composefs_uki_boot(
12061227
BootSetupType::Setup((&root_setup, &state, &postfetch, &fs)),
12071228
repo,

crates/lib/src/bootc_composefs/update.rs

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

238238
let boot_type = BootType::from(entry);
239-
let mut boot_digest = None;
240-
241-
match boot_type {
242-
BootType::Bls => {
243-
boot_digest = Some(setup_composefs_bls_boot(
244-
BootSetupType::Upgrade((storage, &fs, &host)),
245-
repo,
246-
&id,
247-
entry,
248-
&mounted_fs,
249-
)?)
250-
}
239+
240+
let boot_digest = match boot_type {
241+
BootType::Bls => setup_composefs_bls_boot(
242+
BootSetupType::Upgrade((storage, &fs, &host)),
243+
repo,
244+
&id,
245+
entry,
246+
&mounted_fs,
247+
)?,
251248

252249
BootType::Uki => setup_composefs_uki_boot(
253250
BootSetupType::Upgrade((storage, &fs, &host)),

0 commit comments

Comments
 (0)