Skip to content

Commit

Permalink
NOT FOR MERGE: apply suggestions from review
Browse files Browse the repository at this point in the history
This commit is made just to kick the CI. I'll split and squash it into
previous ones if there is no regresion.

Signed-off-by: Krystian Hebel <[email protected]>
  • Loading branch information
krystian-hebel committed Feb 8, 2024
1 parent 66004ae commit 622eb9c
Show file tree
Hide file tree
Showing 9 changed files with 139 additions and 114 deletions.
27 changes: 16 additions & 11 deletions grub-core/loader/i386/linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,14 +181,15 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align,

if (grub_slaunch_platform_type () == SLP_INTEL_TXT)
{
prot_size = ALIGN_UP (prot_size, GRUB_TXT_PMR_ALIGN);

if (prot_size > GRUB_TXT_MLE_MAX_SIZE)
{
err = GRUB_ERR_OUT_OF_RANGE;
goto fail;
}

/* Check performed above makes sure that this doesn't overflow. */
prot_size = ALIGN_UP (prot_size, GRUB_TXT_PMR_ALIGN);

slparams->mle_ptab_size = grub_txt_get_mle_ptab_size (prot_size);
slparams->mle_ptab_size = ALIGN_UP (slparams->mle_ptab_size, GRUB_TXT_PMR_ALIGN);
/* Do not go below GRUB_TXT_PMR_ALIGN. */
Expand Down Expand Up @@ -509,23 +510,23 @@ grub_linux_setup_slr_table (struct grub_slaunch_params *slparams)
/* A bit of work to extract the v2.08 EFI info from the linux params */
efi_info = (void *)((grub_uint8_t *)&boot_params->v0208 + 2*sizeof(grub_uint32_t));

grub_slaunch_add_slrt_policy_entry (18,
grub_slaunch_add_slrt_policy_entry (GRUB_SLAUNCH_DATA_PCR,
GRUB_SLR_ET_BOOT_PARAMS,
/*flags=*/0,
(grub_addr_t) boot_params,
GRUB_PAGE_SIZE,
"Measured boot parameters");

if (boot_params->setup_data)
grub_slaunch_add_slrt_policy_entry (18,
grub_slaunch_add_slrt_policy_entry (GRUB_SLAUNCH_DATA_PCR,
GRUB_SLR_ET_SETUP_DATA,
GRUB_SLR_POLICY_IMPLICIT_SIZE,
boot_params->setup_data,
/*size=*/0,
"Measured Kernel setup_data");

/* TODO the cmdline ptr can have hi bits but for now assume always < 4G */
grub_slaunch_add_slrt_policy_entry (18,
/* The cmdline ptr can have hi bits but GRUB puts it always < 4G */
grub_slaunch_add_slrt_policy_entry (GRUB_SLAUNCH_DATA_PCR,
GRUB_SLR_ET_CMDLINE,
/*flags=*/0,
boot_params->cmd_line_ptr,
Expand All @@ -536,7 +537,7 @@ grub_linux_setup_slr_table (struct grub_slaunch_params *slparams)
{
grub_uint64_t mmap_addr =
((grub_uint64_t) efi_info->efi_mmap_hi << 32) | efi_info->efi_mmap;
grub_slaunch_add_slrt_policy_entry (18,
grub_slaunch_add_slrt_policy_entry (GRUB_SLAUNCH_DATA_PCR,
GRUB_SLR_ET_UEFI_MEMMAP,
/*flags=*/0,
mmap_addr,
Expand All @@ -545,8 +546,11 @@ grub_linux_setup_slr_table (struct grub_slaunch_params *slparams)
}

if (boot_params->ramdisk_image)
/* TODO the initrd image and size can have hi bits but for now assume always < 4G */
grub_slaunch_add_slrt_policy_entry (17,
/*
* The initrd image and size can have hi bits but in GRUB it is always
* < 4G, see GRUB_LINUX_INITRD_MAX_ADDRESS in grub_cmd_initrd().
*/
grub_slaunch_add_slrt_policy_entry (GRUB_SLAUNCH_CODE_PCR,
GRUB_SLR_ET_RAMDISK,
/*flags=*/0,
boot_params->ramdisk_image,
Expand Down Expand Up @@ -711,7 +715,8 @@ grub_linux_boot (void)
grub_relocator_chunk_t ch;
grub_size_t sz;

if (grub_add (ctx.real_size, efi_mmap_size + ap_wake_block_size, &sz))
if (grub_add (efi_mmap_size, ap_wake_block_size, &sz) ||
grub_add (ctx.real_size, sz, &sz))
return GRUB_ERR_OUT_OF_RANGE;

err = grub_relocator_alloc_chunk_addr (relocator, &ch,
Expand Down Expand Up @@ -1008,7 +1013,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
/* Read the kernel_info struct. */
if (grub_le_to_cpu16 (lh.version) >= 0x020f)
{
if (grub_file_seek (file, grub_le_to_cpu32 (lh.kernel_info_offset) +
if (grub_file_seek (file, (grub_off_t) grub_le_to_cpu32 (lh.kernel_info_offset) +
real_size + GRUB_DISK_SECTOR_SIZE) == ((grub_off_t) -1))
goto fail;

Expand Down
19 changes: 12 additions & 7 deletions grub-core/loader/i386/slaunch.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ grub_slaunch_init_slrt_storage (int arch)
void grub_slaunch_add_slrt_policy_entries (void)
{
/* The SLR table should be measured too, at least parts of it. */
grub_slaunch_add_slrt_policy_entry (18,
grub_slaunch_add_slrt_policy_entry (GRUB_SLAUNCH_DATA_PCR,
GRUB_SLR_ET_SLRT,
GRUB_SLR_POLICY_IMPLICIT_SIZE,
slparams.slr_table_base,
Expand All @@ -119,7 +119,7 @@ grub_slaunch_add_slrt_policy_entry (grub_uint16_t pcr,
sizeof(struct grub_slr_entry_policy) +
slr_policy_staging->nr_entries*sizeof(*entry));

if (slr_policy_staging->hdr.size + sizeof(*entry) > sizeof(slr_policy_buf))
if (slr_policy_staging->hdr.size > sizeof(slr_policy_buf) - sizeof(*entry))
grub_fatal("Not enough space for adding policy entry: %s! The buffer is full.",
evt_info);

Expand Down Expand Up @@ -187,8 +187,8 @@ grub_cmd_slaunch_module (grub_command_t cmd __attribute__ ((unused)),
grub_file_t file;
grub_ssize_t size;

if (!argc)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
if (argc != 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected: filename"));

if (slp == SLP_NONE)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("secure launch not enabled"));
Expand Down Expand Up @@ -290,9 +290,14 @@ GRUB_MOD_INIT (slaunch)

GRUB_MOD_FINI (slaunch)
{
grub_unregister_command (cmd_slaunch_state);
grub_unregister_command (cmd_slaunch_module);
grub_unregister_command (cmd_slaunch);
if (cmd_slaunch_state)
grub_unregister_command (cmd_slaunch_state);

if (cmd_slaunch_module)
grub_unregister_command (cmd_slaunch_module);

if (cmd_slaunch)
grub_unregister_command (cmd_slaunch);

if (slp == SLP_INTEL_TXT)
grub_txt_shutdown ();
Expand Down
28 changes: 9 additions & 19 deletions grub-core/loader/i386/txt/acmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,13 +188,8 @@ get_acmod_chipset_list (struct grub_txt_acm_header *hdr)
return NULL;
}

/* Overflows? */
if ( grub_add (info_table->chipset_id_list,
sizeof(struct grub_txt_acm_chipset_id_list), &id_entries_off))
{
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("ACM chipset ID entries out of bounds"));
return NULL;
}
/* Overflows were checked by fits_in_acm() */
id_entries_off = info_table->chipset_id_list + sizeof(*chipset_id_list);

if ( n_fit_in_acm( hdr, id_entries_off, sizeof(struct grub_txt_acm_chipset_id),
chipset_id_list->count ) == NULL )
Expand Down Expand Up @@ -235,13 +230,8 @@ get_acmod_processor_list (struct grub_txt_acm_header* hdr)
return NULL;
}

/* Overflows? */
if ( grub_add (info_table->processor_id_list, sizeof(*proc_id_list),
&id_entries_off))
{
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("ACM processor ID entries out of bounds"));
return NULL;
}
/* Overflows were checked by fits_in_acm() */
id_entries_off = info_table->processor_id_list + sizeof(*proc_id_list);

if ( n_fit_in_acm ( hdr, id_entries_off, sizeof(*proc_id_list),
proc_id_list->count ) == NULL )
Expand Down Expand Up @@ -425,11 +415,11 @@ grub_txt_acmod_match_platform (struct grub_txt_acm_header *hdr)
return 0;

/* Get chipset fusing, device, and vendor id info */
didvid.value = grub_txt_reg_pub_readq (GRUB_TXT_DIDVID);
didvid.value = grub_txt_reg_pub_read64 (GRUB_TXT_DIDVID);

ver = grub_txt_reg_pub_readl (GRUB_TXT_VER_QPIIF);
ver = grub_txt_reg_pub_read32 (GRUB_TXT_VER_QPIIF);
if ( ver == 0xffffffff || ver == 0x00 ) /* Old CPU, need to use VER.FSBIF */
ver = grub_txt_reg_pub_readl (GRUB_TXT_VER_FSBIF);
ver = grub_txt_reg_pub_read32 (GRUB_TXT_VER_FSBIF);

grub_dprintf ("slaunch", "chipset production fused: %s, "
"chipset vendor: 0x%x, device: 0x%x, revision: 0x%x\n",
Expand Down Expand Up @@ -540,8 +530,8 @@ grub_txt_sinit_select (struct grub_txt_acm_header *sinit)
void *sinit_region_base;
grub_uint32_t sinit_size, sinit_region_size;

sinit_region_base = (void *)(grub_addr_t) grub_txt_reg_pub_readl (GRUB_TXT_SINIT_BASE);
sinit_region_size = (grub_uint32_t) grub_txt_reg_pub_readl (GRUB_TXT_SINIT_SIZE);
sinit_region_base = (void *)(grub_addr_t) grub_txt_reg_pub_read32 (GRUB_TXT_SINIT_BASE);
sinit_region_size = (grub_uint32_t) grub_txt_reg_pub_read32 (GRUB_TXT_SINIT_SIZE);

grub_dprintf ("slaunch", "TXT.SINIT.BASE: %p\nTXT.SINIT.SIZE: 0x%"
PRIxGRUB_UINT32_T "\n", sinit_region_base, sinit_region_size);
Expand Down
28 changes: 14 additions & 14 deletions grub-core/loader/i386/txt/txt.c
Original file line number Diff line number Diff line change
Expand Up @@ -945,7 +945,7 @@ grub_txt_state_show (void)
int i;
union grub_txt_didvid didvid;

data.d64 = grub_txt_reg_pub_readq (GRUB_TXT_STS);
data.d64 = grub_txt_reg_pub_read64 (GRUB_TXT_STS);
grub_printf (" TXT.STS: 0x%016" PRIxGRUB_UINT64_T "\n"
" SENTER.DONE.STS: %d\n"
" SEXIT.DONE.STS: %d\n"
Expand All @@ -961,21 +961,21 @@ grub_txt_state_show (void)
!!(data.d64 & GRUB_TXT_STS_LOCALITY2_OPEN));

/* Only least significant byte has a meaning. */
data.d8 = grub_txt_reg_pub_readb (GRUB_TXT_ESTS);
data.d8 = grub_txt_reg_pub_read8 (GRUB_TXT_ESTS);
grub_printf (" TXT.ESTS: 0x%02x\n"
" TXT_RESET.STS: %d\n", data.d8,
!!(data.d8 & GRUB_TXT_ESTS_TXT_RESET));

data.d64 = grub_txt_reg_pub_readq (GRUB_TXT_E2STS);
data.d64 = grub_txt_reg_pub_read64 (GRUB_TXT_E2STS);
grub_printf (" TXT.E2STS: 0x%016" PRIxGRUB_UINT64_T "\n"
" SECRETS.STS: %d\n", data.d64,
!!(data.d64 & GRUB_TXT_E2STS_SECRETS));

/* Only least significant 4 bytes have a meaning. */
data.d32 = grub_txt_reg_pub_readl (GRUB_TXT_ERRORCODE);
data.d32 = grub_txt_reg_pub_read32 (GRUB_TXT_ERRORCODE);
grub_printf (" TXT.ERRORCODE: 0x%08" PRIxGRUB_UINT32_T "\n", data.d32);

didvid.value = grub_txt_reg_pub_readq (GRUB_TXT_DIDVID);
didvid.value = grub_txt_reg_pub_read64 (GRUB_TXT_DIDVID);
grub_printf (" TXT.DIDVID: 0x%016" PRIxGRUB_UINT64_T "\n"
" VID: 0x%04x\n"
" DID: 0x%04x\n"
Expand All @@ -984,40 +984,40 @@ grub_txt_state_show (void)
didvid.value, didvid.vid, didvid.did, didvid.rid, didvid.id_ext);

/* Only least significant 4 bytes have a meaning. */
data.d32 = grub_txt_reg_pub_readl (GRUB_TXT_VER_FSBIF);
data.d32 = grub_txt_reg_pub_read32 (GRUB_TXT_VER_FSBIF);
grub_printf (" TXT.VER.FSBIF: 0x%08" PRIxGRUB_UINT32_T "\n", data.d32);

if ((data.d32 != 0x00000000) && (data.d32 != 0xffffffff))
grub_printf (" DEBUG.FUSE: %d\n", !!(data.d32 & GRUB_TXT_VER_FSBIF_DEBUG_FUSE));
else
{
/* Only least significant 4 bytes have a meaning. */
data.d32 = grub_txt_reg_pub_readl (GRUB_TXT_VER_QPIIF);
data.d32 = grub_txt_reg_pub_read32 (GRUB_TXT_VER_QPIIF);
grub_printf (" TXT.VER.QPIIF: 0x%08" PRIxGRUB_UINT32_T "\n"
" DEBUG.FUSE: %d\n", data.d32,
!!(data.d32 & GRUB_TXT_VER_QPIIF_DEBUG_FUSE));
}

/* Only least significant 4 bytes have a meaning. */
data.d32 = grub_txt_reg_pub_readl (GRUB_TXT_SINIT_BASE);
data.d32 = grub_txt_reg_pub_read32 (GRUB_TXT_SINIT_BASE);
grub_printf (" TXT.SINIT.BASE: 0x%08" PRIxGRUB_UINT32_T "\n", data.d32);

/* Only least significant 4 bytes have a meaning. */
data.d32 = grub_txt_reg_pub_readl (GRUB_TXT_SINIT_SIZE);
data.d32 = grub_txt_reg_pub_read32 (GRUB_TXT_SINIT_SIZE);
grub_printf (" TXT.SINIT.SIZE: %" PRIuGRUB_UINT32_T
" B (0x%" PRIxGRUB_UINT32_T ")\n", data.d32, data.d32);

/* Only least significant 4 bytes have a meaning. */
data.d32 = grub_txt_reg_pub_readl (GRUB_TXT_HEAP_BASE);
data.d32 = grub_txt_reg_pub_read32 (GRUB_TXT_HEAP_BASE);
grub_printf (" TXT.HEAP.BASE: 0x%08" PRIxGRUB_UINT32_T "\n", data.d32);

/* Only least significant 4 bytes have a meaning. */
data.d32 = grub_txt_reg_pub_readl (GRUB_TXT_HEAP_SIZE);
data.d32 = grub_txt_reg_pub_read32 (GRUB_TXT_HEAP_SIZE);
grub_printf (" TXT.HEAP.SIZE: %" PRIuGRUB_UINT32_T
" B (0x%" PRIxGRUB_UINT32_T ")\n", data.d32, data.d32);

/* Only least significant 4 bytes have a meaning. */
data.d32 = grub_txt_reg_pub_readl (GRUB_TXT_DPR);
data.d32 = grub_txt_reg_pub_read32 (GRUB_TXT_DPR);
grub_printf (" TXT.DPR: 0x%08" PRIxGRUB_UINT32_T "\n"
" LOCK: %d\n"
" TOP: 0x%08" PRIxGRUB_UINT32_T "\n"
Expand All @@ -1030,7 +1030,7 @@ grub_txt_state_show (void)
for (i = 0; i < 4; ++i)
{
/* TODO: Check relevant MSRs on SGX platforms. */
data.d64 = grub_txt_reg_pub_readq (GRUB_TXT_PUBLIC_KEY + i * sizeof (grub_uint64_t));
data.d64 = grub_txt_reg_pub_read64 (GRUB_TXT_PUBLIC_KEY + i * sizeof (grub_uint64_t));
grub_printf (" %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x%s", data.a8[0], data.a8[1],
data.a8[2], data.a8[3], data.a8[4], data.a8[5], data.a8[6], data.a8[7],
(i < 3) ? ":\n" : "\n");
Expand Down Expand Up @@ -1104,7 +1104,7 @@ grub_txt_add_slrt_policy_entries (void)
txt_heap = grub_txt_get_heap ();
os_mle_data = grub_txt_os_mle_data_start (txt_heap);

grub_slaunch_add_slrt_policy_entry (18,
grub_slaunch_add_slrt_policy_entry (GRUB_SLAUNCH_DATA_PCR,
GRUB_SLR_ET_TXT_OS2MLE,
/*flags=*/0,
(grub_addr_t) os_mle_data,
Expand Down
30 changes: 21 additions & 9 deletions grub-core/loader/i386/txt/verify.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ verify_acm_elt (struct grub_txt_heap_ext_data_element *elt)
if ( elt->size < GRUB_TXT_HEAP_ELEMENT_HEADER_SIZE +
sizeof(struct grub_txt_heap_acm_element) ||
grub_mul (elt->acm.num_acms, sizeof(grub_uint64_t), &acm_addrs_size) ||
elt->size != GRUB_TXT_HEAP_ELEMENT_HEADER_SIZE + sizeof(elt->acm) +
elt->size - (GRUB_TXT_HEAP_ELEMENT_HEADER_SIZE + sizeof(elt->acm)) !=
acm_addrs_size )
return grub_error (GRUB_ERR_OUT_OF_RANGE,
N_("HEAP_ACM element has wrong size (%d)"),
Expand Down Expand Up @@ -143,7 +143,8 @@ verify_ext_data_elts(struct grub_txt_heap_ext_data_element *elts,
for ( ; ; )
{
if ( elts_size < GRUB_TXT_HEAP_ELEMENT_HEADER_SIZE ||
elts_size < elt->size || elt->size == 0 )
elt->size < GRUB_TXT_HEAP_ELEMENT_HEADER_SIZE ||
elts_size < elt->size )
return grub_error (GRUB_ERR_OUT_OF_RANGE,
N_("TXT heap invalid element size: type: %d, size: %d"),
elt->type, elt->size);
Expand Down Expand Up @@ -218,32 +219,35 @@ grub_txt_verify_platform (void)
* Eventually need the verify_IA32_se_svn_status routine to be called here.
*/

errorcode = grub_txt_reg_pub_readl (GRUB_TXT_ERRORCODE);
errorcode = grub_txt_reg_pub_read32 (GRUB_TXT_ERRORCODE);
/* 0 - no previous SENTER, 0xC0000001 - previous SENTER succeeded */
if ( errorcode != 0 && errorcode != 0xC0000001 )
return grub_error (GRUB_ERR_BAD_DEVICE,
N_("TXT_ERRORCODE reports failure: 0x%08" PRIxGRUB_UINT32_T),
errorcode);

if (grub_txt_reg_pub_readb (GRUB_TXT_ESTS) & GRUB_TXT_ESTS_TXT_RESET)
if (grub_txt_reg_pub_read8 (GRUB_TXT_ESTS) & GRUB_TXT_ESTS_TXT_RESET)
return grub_error (GRUB_ERR_BAD_DEVICE,
N_("TXT_RESET.STS is set and GETSEC[SENTER] is disabled"));

/*
* Verify that the BIOS information in the TXT heap that was setup by the
* BIOS ACM is sane.
* BIOS ACM is reasonable.
*/

txt_heap = grub_txt_get_heap ();
heap_base = grub_txt_reg_pub_readl (GRUB_TXT_HEAP_BASE);
heap_size = grub_txt_reg_pub_readl (GRUB_TXT_HEAP_SIZE);
heap_base = grub_txt_reg_pub_read32 (GRUB_TXT_HEAP_BASE);
heap_size = grub_txt_reg_pub_read32 (GRUB_TXT_HEAP_SIZE);

if ( txt_heap == NULL || heap_base == 0 || heap_size == 0 )
return grub_error (GRUB_ERR_BAD_DEVICE,
N_("TXT heap is not configured correctly"));

bios_size = grub_txt_bios_data_size (txt_heap);
if ( bios_size < sizeof (grub_uint64_t) || bios_size > heap_size )
/* We support versions >= 4, but bios_data->mle_flags is in versions >= 5. */
if ( bios_size < sizeof (grub_uint64_t) + sizeof (*bios_data) -
sizeof (bios_data->mle_flags) ||
bios_size > heap_size )
return grub_error (GRUB_ERR_OUT_OF_RANGE,
N_("invalid size of the TXT heap BIOS data table"));

Expand All @@ -259,9 +263,17 @@ grub_txt_verify_platform (void)
N_("BIOS reports too many CPUs for secure launch (%d)"),
bios_data->num_logical_procs);

/*
* grub_uint32_t mle_flags is available in versions >= 5, version 4 doesn't
* have it. However, the minimal size of extended data element is 8 bytes, so
* the size check below is still valid for version 4.
*/
if ( bios_data->version >= 4 && bios_size > sizeof(*bios_data) + sizeof(bios_size) )
{
elts = (struct grub_txt_heap_ext_data_element *) ((grub_uint8_t *)bios_data + sizeof(*bios_data));
elts = (struct grub_txt_heap_ext_data_element *) ((grub_uint8_t *)bios_data +
sizeof(*bios_data) -
( bios_data->version == 4 ?
sizeof(bios_data->mle_flags) : 0 ));
err = verify_ext_data_elts(elts, bios_size - sizeof(*bios_data));
}

Expand Down
6 changes: 3 additions & 3 deletions include/grub/i386/linux.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,11 +154,11 @@ struct linux_i386_kernel_header
struct linux_kernel_info
{
grub_uint32_t header;
grub_uint32_t size;
grub_uint32_t size_total;
grub_uint32_t size; /* In bytes, excluding var_len_data[] */
grub_uint32_t size_total; /* In bytes, including var_len_data[] */
grub_uint32_t setup_type_max;
grub_uint32_t mle_header_offset;
grub_uint8_t var_len_data[0];
grub_uint8_t var_len_data[];
} GRUB_PACKED;

/* Boot parameters for Linux based on 2.6.12. This is used by the setup
Expand Down
4 changes: 4 additions & 0 deletions include/grub/i386/slaunch.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
#define SLP_NONE 0
#define SLP_INTEL_TXT 1

/* PCRs used by Secure launch. */
#define GRUB_SLAUNCH_CODE_PCR 17
#define GRUB_SLAUNCH_DATA_PCR 18

#define GRUB_SLAUNCH_TPM_EVT_LOG_SIZE (8 * GRUB_PAGE_SIZE)

/*
Expand Down
Loading

0 comments on commit 622eb9c

Please sign in to comment.