Skip to content

Commit 123e5b3

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 a93e118 commit 123e5b3

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
@@ -765,10 +789,11 @@ pub(crate) fn setup_composefs_bls_boot(
765789
Ok(boot_digest)
766790
}
767791

768-
struct UKILabels {
792+
struct UKIInfo {
769793
boot_label: String,
770794
version: Option<String>,
771795
os_id: Option<String>,
796+
boot_digest: String,
772797
}
773798

774799
/// Writes a PortableExecutable to ESP along with any PE specific or Global addons
@@ -782,10 +807,10 @@ fn write_pe_to_esp(
782807
is_insecure_from_opts: bool,
783808
mounted_efi: impl AsRef<Path>,
784809
bootloader: &Bootloader,
785-
) -> Result<Option<UKILabels>> {
810+
) -> Result<Option<UKIInfo>> {
786811
let efi_bin = read_file(file, &repo).context("Reading .efi binary")?;
787812

788-
let mut boot_label: Option<UKILabels> = None;
813+
let mut boot_label: Option<UKIInfo> = None;
789814

790815
// UKI Extension might not even have a cmdline
791816
// TODO: UKI Addon might also have a composefs= cmdline?
@@ -820,10 +845,13 @@ fn write_pe_to_esp(
820845

821846
let parsed_osrel = OsReleaseInfo::parse(osrel);
822847

823-
boot_label = Some(UKILabels {
848+
let boot_digest = compute_boot_digest_uki(&efi_bin)?;
849+
850+
boot_label = Some(UKIInfo {
824851
boot_label: uki::get_boot_label(&efi_bin).context("Getting UKI boot label")?,
825852
version: parsed_osrel.get_version(),
826853
os_id: parsed_osrel.get_value(&["ID"]),
854+
boot_digest,
827855
});
828856
}
829857

@@ -973,7 +1001,7 @@ fn write_grub_uki_menuentry(
9731001
fn write_systemd_uki_config(
9741002
esp_dir: &Dir,
9751003
setup_type: &BootSetupType,
976-
boot_label: UKILabels,
1004+
boot_label: UKIInfo,
9771005
id: &Sha512HashValue,
9781006
) -> Result<()> {
9791007
let os_id = boot_label.os_id.as_deref().unwrap_or("bootc");
@@ -1044,7 +1072,7 @@ pub(crate) fn setup_composefs_uki_boot(
10441072
repo: crate::store::ComposefsRepository,
10451073
id: &Sha512HashValue,
10461074
entries: Vec<ComposefsBootEntry<Sha512HashValue>>,
1047-
) -> Result<()> {
1075+
) -> Result<String> {
10481076
let (root_path, esp_device, bootloader, is_insecure_from_opts, uki_addons) = match setup_type {
10491077
BootSetupType::Setup((root_setup, state, postfetch, ..)) => {
10501078
state.require_no_kargs_for_uki()?;
@@ -1077,7 +1105,7 @@ pub(crate) fn setup_composefs_uki_boot(
10771105

10781106
let esp_mount = mount_esp(&esp_device).context("Mounting ESP")?;
10791107

1080-
let mut uki_label: Option<UKILabels> = None;
1108+
let mut uki_info: Option<UKIInfo> = None;
10811109

10821110
for entry in entries {
10831111
match entry {
@@ -1126,28 +1154,26 @@ pub(crate) fn setup_composefs_uki_boot(
11261154
)?;
11271155

11281156
if let Some(label) = ret {
1129-
uki_label = Some(label);
1157+
uki_info = Some(label);
11301158
}
11311159
}
11321160
};
11331161
}
11341162

1135-
let uki_label = uki_label
1136-
.ok_or_else(|| anyhow::anyhow!("Failed to get version and boot label from UKI"))?;
1163+
let uki_info =
1164+
uki_info.ok_or_else(|| anyhow::anyhow!("Failed to get version and boot label from UKI"))?;
1165+
1166+
let boot_digest = uki_info.boot_digest.clone();
11371167

11381168
match bootloader {
1139-
Bootloader::Grub => write_grub_uki_menuentry(
1140-
root_path,
1141-
&setup_type,
1142-
uki_label.boot_label,
1143-
id,
1144-
&esp_device,
1145-
)?,
1169+
Bootloader::Grub => {
1170+
write_grub_uki_menuentry(root_path, &setup_type, uki_info.boot_label, id, &esp_device)?
1171+
}
11461172

1147-
Bootloader::Systemd => write_systemd_uki_config(&esp_mount.fd, &setup_type, uki_label, id)?,
1173+
Bootloader::Systemd => write_systemd_uki_config(&esp_mount.fd, &setup_type, uki_info, id)?,
11481174
};
11491175

1150-
Ok(())
1176+
Ok(boot_digest)
11511177
}
11521178

11531179
pub struct SecurebootKeys {
@@ -1244,20 +1270,15 @@ pub(crate) async fn setup_composefs_boot(
12441270
};
12451271

12461272
let boot_type = BootType::from(entry);
1247-
let mut boot_digest: Option<String> = None;
1248-
1249-
match boot_type {
1250-
BootType::Bls => {
1251-
let digest = setup_composefs_bls_boot(
1252-
BootSetupType::Setup((&root_setup, &state, &postfetch, &fs)),
1253-
repo,
1254-
&id,
1255-
entry,
1256-
&mounted_fs,
1257-
)?;
12581273

1259-
boot_digest = Some(digest);
1260-
}
1274+
let boot_digest = match boot_type {
1275+
BootType::Bls => setup_composefs_bls_boot(
1276+
BootSetupType::Setup((&root_setup, &state, &postfetch, &fs)),
1277+
repo,
1278+
&id,
1279+
entry,
1280+
&mounted_fs,
1281+
)?,
12611282
BootType::Uki => setup_composefs_uki_boot(
12621283
BootSetupType::Setup((&root_setup, &state, &postfetch, &fs)),
12631284
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)