Fix possible and absolute memory leaks of "handles"
returned by grub_efi_locate_handle() using grub_malloc().
Signed-off-by: Khalid Ali <khaliidcaliy@gmail.com>
Reviewed-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
The implementation in sd-boot was changed to return UINT32_MAX when
the EFI environment detects a working TPM2, but with an older firmware
that doesn't implement the protocol to get the list of active banks.
This allows distinguishing with the case where there is no working TPM2,
in which case userspace just gives up, and instead lets userspace try to
figure it out later.
Fixes: f326c5c47 (commands/bli: Set LoaderTpm2ActivePcrBanks runtime variable)
Signed-off-by: Luca Boccassi <luca.boccassi@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
The call was added in the 1.1 revision of the spec, 1.0 does
not have it, and there are some machines out there with a TPM2
and a UEFI firmware that only supports version 1.0, so the
call fails in those cases. Check the reported version before
calling get_active_pcr_banks().
See Table 4 in section 6.2 of the TCG EFI Protocol Specification:
https://trustedcomputinggroup.org/wp-content/uploads/EFI-Protocol-Specification-rev13-160330final.pdf
Fixes: f326c5c47 (commands/bli: Set LoaderTpm2ActivePcrBanks runtime variable)
Signed-off-by: Luca Boccassi <luca.boccassi@gmail.com>
Reviewed-by: Andrew Hamilton <adhamilt@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
It turns out checking from userspace is not 100% reliable to figure out
whether the firmware had TPM2 support enabled or not. For example with
EDK2 arm64, the default upstream build config bundles TPM2 support with
SecureBoot support, so if the latter is disabled, TPM2 is also unavailable.
But still, the ACPI TPM2 table is created just as if it was enabled. So,
/sys/firmware/acpi/tables/TPM2 exists and looks correct but there are no
measurements, neither the firmware nor the loader/stub can do them, and
/sys/kernel/security/tpm0/binary_bios_measurements does not exist.
So, userspace cannot really tell what was going on in UEFI mode.
The loader can use the apposite UEFI protocol to check, which is a more
definitive answer. Export the bitmask with the list of active banks as-is.
If it's not 0, then in userspace we can be sure a working TPM2 was available
in UEFI mode.
systemd-boot and systemd-stub v258 (current main) set this variable and
userspace portion consumes it to be able to tell what was available in
the firmware context.
Signed-off-by: Luca Boccassi <luca.boccassi@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
The measurements for confidential computing has been introduced in the
commit 4c76565b6 (efi/tpm: Add EFI_CC_MEASUREMENT_PROTOCOL support).
Recently the patch 30708dfe3 (tpm: Disable the tpm verifier if the TPM
device is not present) has been introduced to optimize the memory usage
when a TPM device is not available on platforms. This fix prevents the
tpm module to be loaded on confidential computing platforms, e.g. Intel
machines with TDX enabled, where the TPM device is not available.
In this patch, we propose to load the tpm module for this use case by
generalizing the tpm feature detection in order to cover CC platforms.
Basically, we do it by detecting the availability of the
EFI_CC_MEASUREMENT_PROTOCOL EFI protocol.
Fixes: https://savannah.gnu.org/bugs/?65821
Fixes: 30708dfe3 (tpm: Disable the tpm verifier if the TPM device is not present)
Signed-off-by: Hector Cao <hector.cao@canonical.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Currently booting the system is prevented when call to EFI firmware
hash_log_extend_event() returns unknown error. Solve this by following
convention used in commit a4356538d (commands/tpm: Don't propagate
measurement failures to the verifiers layer).
Let the system to be bootable by default when unknown TPM error is
encountered. Check environment variable tpm_fail_fatal to fallback to
previous behaviour.
Signed-off-by: Michał Grzelak <mchl.grzlk@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
There are 3 implementations of a GUID in GRUB. Replace them with
a common one, placed in types.h.
It uses the "packed" flavor of the GUID structs, the alignment attribute
is dropped, since it is not required.
Signed-off-by: Oliver Steffen <osteffen@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Now that GCC can generate function calls using the correct calling
convention for us, we can stop using the efi_call_XX() wrappers, and
just dereference the function pointers directly.
This avoids the untyped variadic wrapper routines, which means better
type checking for the method calls.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
When the tpm module is loaded, the verifier reads entire file into
memory, measures it and uses verified content as a backing buffer for
file accesses. However, this process may result in high memory
utilization for file operations, sometimes causing a system to run out
of memory which may finally lead to boot failure. To address this issue,
among others, the commit 887f98f0d (mm: Allow dynamically requesting
additional memory regions) have optimized memory management by
dynamically allocating heap space to maximize memory usage and reduce
threat of memory exhaustion. But in some cases problems may still arise,
e.g., when large ISO images are mounted using loopback or when dealing
with embedded systems with limited memory resources.
Unfortunately current implementation of the tpm module doesn't allow
elimination of the back buffer once it is loaded. Even if the TPM device
is not present or it has been explicitly disabled. This may unnecessary
allocate a lot memory. To solve this issue, a patch has been developed
to detect the TPM status at module load and skip verifier registration
if the device is missing or deactivated. This prevents allocation of
memory for the back buffer, avoiding wasting memory when no real measure
boot functionality is performed. Disabling the TPM device in the system
can reduce memory usage in the GRUB. It is useful in scenarios where
high memory utilization is a concern and measurements of loaded
artifacts are not necessary.
Signed-off-by: Michael Chang <mchang@suse.com>
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
The EFI_CC_MEASUREMENT_PROTOCOL abstracts the measurement for virtual firmware
in confidential computing environment. It is similar to the EFI_TCG2_PROTOCOL.
It was proposed by Intel and ARM and approved by UEFI organization.
It is defined in Intel GHCI specification: https://cdrdv2.intel.com/v1/dl/getContent/726790 .
The EDKII header file is available at https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Protocol/CcMeasurement.h .
Signed-off-by: Lu Ken <ken.lu@intel.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
The event description is a string, so using grub_strcpy() is cleaner than
using grub_memcpy().
Signed-off-by: Lu Ken <ken.lu@intel.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
1. Use macro GRUB_ERR_NONE instead of hard code 0.
2. Keep lowercase of the first char for the status string of log event.
Signed-off-by: Lu Ken <ken.lu@intel.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Part of the code logic for processing the return value of efi
log_extend_event is repetitive and complicated. Extract the
repetitive code into an independent function.
Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Add a number of debug logs to the tpm module. The condition tag
for opening debugging is "tpm". On TPM machines, this will bring
great convenience to diagnosis and debugging.
Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Although the tpm_execute() series of functions are defined they are not
used anywhere. Several structures in the include/grub/efi/tpm.h header
file are not used too. There is even nonexistent grub_tpm_init()
declaration in this header. Delete all that unneeded stuff.
If somebody needs the functionality implemented in the dropped code then
he/she can re-add it later. Now it needlessly increases the GRUB
code/image size.
Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
grub_tpm_log_event() and grub_tpm_measure() are two functions that
have the same effect. So, keep grub_tpm_log_event() and rename it
to grub_tpm_measure(). This way we get also a more clear semantics.
Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
The memory requested for the event is not released here,
causing memory leaks. This patch fixes this problem.
Signed-off-by: Jia Zhang <zhang.jia@linux.alibaba.com>
Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
The value of tpm_handle changes between successive calls to grub_tpm_handle_find(),
as instead of simply copying the stored pointer we end up taking the address of
said pointer when using the cached value of grub_tpm_handle.
This causes grub_efi_open_protocol() to return a nullptr in grub_tpm2_execute()
and grub_tpm2_log_event(). Said nullptr goes unchecked and
efi_call_5(tpm->hash_log_extend_event,...) ends up jumping to 0x0, Qemu crashes
once video ROM is reached at 0xb0000.
This patch seems to do the trick of fixing that bug, but we should also ensure
that all calls to grub_efi_open_protocol() are checked so that we don't start
executing low memory.
Signed-off-by: Max Tottenham <mtottenh@akamai.com>
Reviewed-by: Matthew Garrett <mjg59@google.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Add support for performing basic TPM measurements. Right now this only
supports extending PCRs statically and only on UEFI. In future we might
want to have some sort of mechanism for choosing which events get logged
to which PCRs, but this seems like a good default policy and we can wait
to see whether anyone has a use case before adding more complexity.
Signed-off-by: Matthew Garrett <mjg59@google.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>