Store returned value from grub_getkey() in int instead of char to
prevent throwing away the extended bits. This was a problem because,
for instance, the left arrow key press would return
(GRUB_TERM_EXTENDED | 0x4b), which would have the GRUB_TERM_EXTENDED
thrown away leaving 0x4b or 'K'. These extended keys should either
work as intended or do nothing. This change has them do nothing,
instead of inserting a key not pressed by the user.
Signed-off-by: Li Gen <ligenlive@gmail.com>
Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Add a new --is-supported option to commands/efi/efifwsetup and
conditionalize display on it.
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
The "fwsetup" command is only registered if the firmware supports booting
to the firmware setup UI. But it could be possible that the GRUB config
already contains a "fwsetup" entry, because it was generated in a machine
that has support for this feature.
To prevent users getting an error like:
error: ../../grub-core/script/function.c:109:can't find command `fwsetup'.
if it is not supported by the firmware, let's just always register the
command but print a more accurate message if the firmware doesn't
support this option.
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Each call of grub_efi_get_variable() needs a grub_free().
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This command is meant to behave similarly to the "mode" command of the EFI
Shell application. In addition to allowing mode selection by giving the
number of columns and rows as arguments, the command allows specifying the
mode number to select the mode. Also supported are the arguments "min" and
"max", which set the mode to the minimum and maximum mode respectively as
calculated by the columns * rows of that mode.
Signed-off-by: Glenn Washburn <development@efficientek.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>
It will be desirable in the future to allow having the read hook modify the
data passed back from a read function call on a disk or file. This adds that
infrastructure and has no impact on code flow for existing uses of the read
hook. Also changed is that now when the read hook callback is called it can
also indicate what error code should be sent back to the read caller.
Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Patrick Steinhardt <ps@pks.im>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Loaders rely on global variables for saving context which is consumed
in the boot hook and freed in the unload hook. In the case where a loader
command is executed twice, calling grub_loader_set() a second time executes
the unload hook, but in some cases this runs when the loader's global
context has already been updated, resulting in the updated context being
freed and potential use-after-free bugs when the boot hook is subsequently
called.
This adds a new API, grub_loader_set_ex(), which allows a loader to specify
context that is passed to its boot and unload hooks. This is an alternative
to requiring that loaders call grub_loader_unset() before mutating their
global context.
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
The GRUB is failing to build with GCC-12 in many places like this:
In function 'init_cbfsdisk',
inlined from 'grub_mod_init' at ../../grub-core/fs/cbfs.c:391:3:
../../grub-core/fs/cbfs.c:345:7: error: array subscript 0 is outside array bounds of 'grub_uint32_t[0]' {aka 'unsigned int[]'} [-Werror=array-bounds]
345 | ptr = *(grub_uint32_t *) 0xfffffffc;
| ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is caused by GCC regression in 11/12 [1]. In a nut shell, the
warning is about detected invalid accesses at non-zero offsets to NULL
pointers. Since hardwired constant address is treated as NULL plus an
offset in the same underlying code, the warning is therefore triggered.
Instead of inserting #pragma all over the places where literal pointers
are accessed to avoid diagnosing array-bounds, we can try to borrow the
idea from Linux kernel that the absolute_pointer() macro [2][3] is used
to disconnect a pointer using literal address from it's original object,
hence GCC won't be able to make assumptions on the boundary while doing
pointer arithmetic. With that we can greatly reduce the code we have to
cover up by making initial literal pointer assignment to use the new
wrapper but not having to track everywhere literal pointers are
accessed. This also makes code looks cleaner.
Please note the grub_absolute_pointer() macro requires to be invoked in
a function as long as it is compound expression. Some global variables
with literal pointers has been changed to local ones in order to use
grub_absolute_pointer() to initialize it. The shuffling is basically done
in a selective and careful way that the variable's scope doesn't matter
being local or global, for example, the global variable must not get
modified at run time throughout. For the record, here's the list of
global variables got shuffled in this patch:
grub-core/commands/i386/pc/drivemap.c:int13slot
grub-core/term/i386/pc/console.c:bios_data_area
grub-core/term/ns8250.c:serial_hw_io_addr
[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99578
[2] https://elixir.bootlin.com/linux/v5.16.14/source/include/linux/compiler.h#L180
[3] https://elixir.bootlin.com/linux/v5.16.14/source/include/linux/compiler-gcc.h#L31
Signed-off-by: Michael Chang <mchang@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
When using "search" on EFI systems, we sometimes want to exclude devices
that are not EFI disks, e.g. md, lvm. This is typically used when
wanting to chainload when having a software raid (md) for EFI partition:
with no option, "search --file /EFI/redhat/shimx64.efi" sets root envvar
to "md/boot_efi" which cannot be used for chainloading since there is no
effective EFI device behind.
Signed-off-by: Renaud Métrich <rmetrich@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Latest GCC may complain in that way:
commands/i386/pc/sendkey.c: In function ‘grub_sendkey_postboot’:
commands/i386/pc/sendkey.c:223:21: error: writing 1 byte into a region of size 0 [-Werror=stringop-overflow=]
223 | *((char *) 0x41a) = 0x1e;
| ~~~~~~~~~~~~~~~~~~^~~~~~
The volatile keyword addition helps and additionally assures us the
compiler will not optimize out fixed assignments.
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Robbie Harwood <rharwood@redhat.com>
The EFI_IMAGE_SECURITY_DATABASE_GUID is used for the image execution
information table (cf. UEFI specification 2.9, 32.5.3.1 Using The Image
Execution Information Table).
The lsefisystab command is used to display installed EFI configuration
tables. Currently it only shows the GUID but not a short text for the
table.
Provide a short text for the EFI_IMAGE_SECURITY_DATABASE_GUID.
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
When using --no-floppy and a floppy was encountered, iterate_device()
was returning 1, causing the iteration to stop instead of continuing.
Signed-off-by: Renaud Métrich <rmetrich@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Commit 1fc860bb76bb (commands/probe: Fix a resource leak when probing disks),
missed other cases where grub_device_close() should be called before a return
statement is called. Also found that grub_disk_close() wasn't being called when
an error is being returned. To avoid conflict with grub_errno, grub_error_push()
should be called before either grub_device_close() or grub_disk_close() is
called and grub_error_pop() should be called before grub_errno is returned.
Fixes: 1fc860bb76bb (commands/probe: Fix a resource leak when probing disks)
Fixes: CID 292443
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This conforms to the behavior of the -s option of the Bash read command.
docs/grub: Document the -s option for the read command.
Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
In the case that one passes a write mask with ":" the write_mask is
obtained from grub_strtoul() and then promptly overwritten by 0xffffffff
three lines later.
This appears to have been so since the initial version of setpci in 2009.
I'm surprised no one else has hit this issue in the past 12 years...
Signed-off-by: Wouter van Kesteren <woutershep@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
The format code is for a 32-bit int, but the argument, keyid, is declared as
a 64 bit int. The comment above says keyid is 32-bit. I'm not sure if the
comment or declaration is wrong, so force the display of a 64-bit int for now.
Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
UEFI specification 2.8 errata B introduced the EFI_RT_PROPERTIES_TABLE
describing the services available at runtime.
The lsefisystab command is used to display installed EFI configuration
tables. Currently it only shows the GUID but not a short text for the
new table.
Provide a short text for the EFI_RT_PROPERTIES_TABLE_GUID.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
The commit f1957dc8a (RISC-V: Add to build system) added two entries to
the options array, but only 1 entry to the enum. This resulted in
everything after the insertion point being off by one.
This broke at least the "file --is-hibernated-hiberfil" command.
Bring the two back in sync by splitting the IS_RISCV_EFI enum entry into
two, as is done for other architectures.
Signed-off-by: Derek Foreman <derek@endlessos.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Commit 9acdcbf32542 (use single quotes in menuentry setparams command)
says that expressing a quoted single quote will require 3 characters. It
actually requires (and always did require!) 4 characters:
str: a'b => a'\''b
len: 3 => 6 (2 for the letters + 4 for the quote)
This leads to not allocating enough memory and thus out of bounds writes
that have been observed to cause heap corruption.
Allocate 4 bytes for each single quote.
Commit 22e7dbb2bb81 (Fix quoting in legacy parser.) does the same
quoting, but it adds 3 as extra overhead on top of the single byte that
the quote already needs. So it's correct.
Fixes: 9acdcbf32542 (use single quotes in menuentry setparams command)
Fixes: CVE-2021-20233
Reported-by: Daniel Axtens <dja@axtens.net>
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This can be triggered with:
ls -l (0 0*)
and causes a NULL deref in grub_normal_print_device_info().
I'm not sure if there's any implication with the IEEE 1275 platform.
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Every other return statement in this code is calling grub_device_close()
to clean up dev before returning. This one should do that too.
Fixes: CID 292443
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
check_list() uses grub_file_getline(), which allocates a buffer.
If the hash list file contains invalid lines, the function leaks
this buffer when it returns an error.
Fixes: CID 176635
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
When a module is attempted to be removed its reference counter is always
decremented. This means that repeated rmmod invocations will cause the
module to be unloaded even if another module depends on it.
This may lead to a use-after-free scenario allowing an attacker to execute
arbitrary code and by-pass the UEFI Secure Boot protection.
While being there, add the extern keyword to some function declarations in
that header file.
Fixes: CVE-2020-25632
Reported-by: Chris Coulson <chris.coulson@canonical.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
The command can be used to get/set ATA disk parameters. Some of these can
be dangerous since change the disk behavior. Restrict it when locked down.
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This command can set PCI devices register values, which makes it dangerous
in a locked down configuration. Restrict it so can't be used on this setup.
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
There are some more commands that should be restricted when the GRUB is
locked down. Following is the list of commands and reasons to restrict:
* fakebios: creates BIOS-like structures for backward compatibility with
existing OSes. This should not be allowed when locked down.
* loadbios: reads a BIOS dump from storage and loads it. This action
should not be allowed when locked down.
* devicetree: loads a Device Tree blob and passes it to the OS. It replaces
any Device Tree provided by the firmware. This also should
not be allowed when locked down.
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
The command is not allowed when lockdown is enforced. Otherwise an
attacker can instruct the GRUB to load an SSDT table to overwrite
the kernel lockdown configuration and later load and execute
unsigned code.
Fixes: CVE-2020-14372
Reported-by: Máté Kukri <km@mkukri.xyz>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Now the GRUB can check if it has been locked down and this can be used to
prevent executing commands that can be utilized to circumvent the UEFI
Secure Boot mechanisms. So, instead of hardcoding a list of modules that
have to be disabled, prevent the usage of commands that can be dangerous.
This not only allows the commands to be disabled on other platforms, but
also properly separate the concerns. Since the shim_lock verifier logic
should be only about preventing to run untrusted binaries and not about
defining these kind of policies.
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
When the GRUB starts on a secure boot platform, some commands can be
used to subvert the protections provided by the verification mechanism and
could lead to booting untrusted system.
To prevent that situation, allow GRUB to be locked down. That way the code
may check if GRUB has been locked down and further restrict the commands
that are registered or what subset of their functionality could be used.
The lockdown support adds the following components:
* The grub_lockdown() function which can be used to lockdown GRUB if,
e.g., UEFI Secure Boot is enabled.
* The grub_is_lockdown() function which can be used to check if the GRUB
was locked down.
* A verifier that flags OS kernels, the GRUB modules, Device Trees and ACPI
tables as GRUB_VERIFY_FLAGS_DEFER_AUTH to defer verification to other
verifiers. These files are only successfully verified if another registered
verifier returns success. Otherwise, the whole verification process fails.
For example, PE/COFF binaries verification can be done by the shim_lock
verifier which validates the signatures using the shim_lock protocol.
However, the verification is not deferred directly to the shim_lock verifier.
The shim_lock verifier is hooked into the verification process instead.
* A set of grub_{command,extcmd}_lockdown functions that can be used by
code registering command handlers, to only register unsafe commands if
the GRUB has not been locked down.
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Move the shim_lock verifier from its own module into the core image. The
Secure Boot lockdown mechanism has the intent to prevent the load of any
unsigned code or binary when Secure Boot is enabled.
The reason is that GRUB must be able to prevent executing untrusted code
if UEFI Secure Boot is enabled, without depending on external modules.
Signed-off-by: Marco A Benatto <mbenatto@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Move verifiers API from a module to the kernel image, so it can be
used there as well. There are no functional changes in this patch.
Signed-off-by: Marco A Benatto <mbenatto@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.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>
The shim_lock module registers a verifier to call shim's verify, but the
handler is registered even when the shim_lock protocol was not installed.
This doesn't cause a NULL pointer dereference in shim_lock_write() because
the shim_lock_init() function just returns GRUB_ERR_NONE if sl isn't set.
But in that case there's no point to even register the shim_lock verifier
since won't do anything. Additionally, it is only useful when Secure Boot
is enabled.
Finally, don't assume that the shim_lock protocol will always be present
when the shim_lock_write() function is called, and check for it on every
call to this function.
Reported-by: Michael Chang <mchang@suse.com>
Reported-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This is needed to properly detect and report UEFI Secure Boot status
to the x86 Linux kernel. The functionality will be added by subsequent
patches.
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Signed-off-by: Marco A Benatto <mbenatto@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
The GUID will be used to properly detect and report UEFI Secure Boot
status to the x86 Linux kernel. The functionality will be added by
subsequent patches. The shim_lock protocol type is made public for
completeness.
Additionally, fix formatting of four preceding GUIDs.
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Signed-off-by: Marco A Benatto <mbenatto@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.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>
This attempts to fix the places where we do the following where
arithmetic_expr may include unvalidated data:
X = grub_malloc(arithmetic_expr);
It accomplishes this by doing the arithmetic ahead of time using grub_add(),
grub_sub(), grub_mul() and testing for overflow before proceeding.
Among other issues, this fixes:
- allocation of integer overflow in grub_video_bitmap_create()
reported by Chris Coulson,
- allocation of integer overflow in grub_png_decode_image_header()
reported by Chris Coulson,
- allocation of integer overflow in grub_squash_read_symlink()
reported by Chris Coulson,
- allocation of integer overflow in grub_ext2_read_symlink()
reported by Chris Coulson,
- allocation of integer overflow in read_section_as_string()
reported by Chris Coulson.
Fixes: CVE-2020-14309, CVE-2020-14310, CVE-2020-14311
Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This modifies most of the places we do some form of:
X = malloc(Y * Z);
to use calloc(Y, Z) instead.
Among other issues, this fixes:
- allocation of integer overflow in grub_png_decode_image_header()
reported by Chris Coulson,
- allocation of integer overflow in luks_recover_key()
reported by Chris Coulson,
- allocation of integer overflow in grub_lvm_detect()
reported by Chris Coulson.
Fixes: CVE-2020-14308
Signed-off-by: Peter Jones <pjones@redhat.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>
Like grub_verifiers_open(), the grub_verify_string() should also
display this debug message, which is very helpful for debugging.
Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
On some devices the ESC key is the hotkey to enter the BIOS/EFI setup
screen, making it really hard to time pressing it right. Besides that
ESC is also pretty hard to discover for a user who does not know it
will unhide the menu.
This commit makes F4, which was chosen because is not used as a hotkey
to enter the BIOS setup by any vendor, also interrupt sleeps / stop the
menu countdown.
This solves the ESC gets into the BIOS setup and also somewhat solves
the discoverability issue, but leaves the timing issue unresolved.
This commit fixes the timing issue by also adding support for keeping
SHIFT pressed during boot to stop the menu countdown. This matches
what Ubuntu is doing, which should also help with discoverability.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>