Use the object name in the json array rather than the 0 based index in the
json array for keyslots, segments, and digests. This is less confusing for
the end user. For example, say you have a LUKS2 device with a key in slot 1
and slot 4. When using the password for slot 4 to unlock the device, the
messages using the index of the keyslot will mention keyslot 1 (its a
zero-based index). Furthermore, with this change the keyslot number will
align with the number used to reference the keyslot when using the
--key-slot argument to cryptsetup.
Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This allows code using these structs to know the named key associated with
these json data structures. In the future we can use these to provide better
error messages to the user.
Get rid of idx local variable in luks2_get_keyslot() which was overloaded to
be used for both keyslot and segment slot keys.
Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
We should assume that the output argument "out" is uninitialized and could
have random data. So, make sure to initialize the segments and keyslots bit
fields because potentially not all bits of those fields are written to.
Otherwise, the digest could say it belongs to keyslots and segments that it
does not.
Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Patrick Steinhardt <ps@pks.im>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
The function grub_disk_get_size() is confusingly named because it actually
returns a sector count where the sectors are sized in the GRUB native sector
size. Rename to something more appropriate.
Suggested-by: Daniel Kiper <daniel.kiper@oracle.com>
Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Patrick Steinhardt <ps@pks.im>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
If there is a loopback device with the same name as the one to be created,
instead of closing the old one and replacing it with the new one, return an
error instead. If the loopback device was created, its probably being used
by something and just replacing it may cause GRUB to crash unexpectedly.
This fixes obvious problems like "loopback d (d)/somefile". Its not too
onerous to force the user to delete the loopback first with the "-d" switch.
Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
There is a hardcoded maximum disk size that can be read or written from,
currently set at 1 EiB in grub_disk_adjust_range(). Move the literal into a
macro in disk.h, so our assumptions are more visible. This hard coded limit
does not prevent using larger disks, just GRUB won't read/write past the
limit. The comment accompanying this restriction didn't quite make sense to
me, so its been modified too.
Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
When checking if a block list goes past the end of the disk, make sure
the total size of the disk is in GRUB native sector sizes, otherwise there
will be blocks at the end of the disk inaccessible by block lists.
Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
We don't want to support small MBR gap in pair with anything but the
simplest config of biosdisk + part_msdos + simple filesystem. In this
path "simple filesystems" are all current filesystems except ZFS and
Btrfs.
Signed-off-by: Vladimir Serbinenko <phcoder@google.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>
Now that the GRUB has a grub_efi_get_secureboot() function to check the
UEFI Secure Boot status, use it to report that to the Linux kernel.
Signed-off-by: Ignat Korchagin <ignat@cloudflare.com>
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 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>
Introduce grub_efi_get_secureboot() function which returns whether
UEFI Secure Boot is enabled or not on UEFI systems.
Signed-off-by: Ignat Korchagin <ignat@cloudflare.com>
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>
It 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.
Signed-off-by: Ignat Korchagin <ignat@cloudflare.com>
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>
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>
When building with --target=arm-linux-gnu --with-platform=coreboot
a linking error occurs caused by multiple definitions of the
ps2_state variable.
Mark them as static since they aren't used outside their compilation unit.
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Nothing defined in the header file is used in the assembly code but it
may lead to build errors if some headers are included through this and
contains definitions that are not recognized by the assembler, e.g.:
../include/grub/types.h: Assembler messages:
../include/grub/types.h:76: Error: no such instruction: `typedef signed char grub_int8_t'
../include/grub/types.h:77: Error: no such instruction: `typedef short grub_int16_t'
../include/grub/types.h:78: Error: no such instruction: `typedef int grub_int32_t'
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Looping variable "j" was named such because the variable name "i" was taken.
Since "i" has been renamed in the previous patch, we can rename "j" to "i".
Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Patrick Steinhardt <ps@pks.im>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Variables named "i" are usually looping variables. So, rename it to
"keyslot_idx" to ease luks2_get_keyslot() reading.
Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Patrick Steinhardt <ps@pks.im>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
The loop variable "j" should be used to index the digests and segments json
array, instead of the variable "i", which is the keyslot index.
Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Patrick Steinhardt <ps@pks.im>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This makes it more obvious to the reader that the disk referred to is the
source disk, as opposed to say the disk holding the cryptodisk.
Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Patrick Steinhardt <ps@pks.im>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This makes it clear that the offset represents sectors, not bytes, in
order to improve readability.
Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Patrick Steinhardt <ps@pks.im>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This creates an alignment with grub_disk_t naming of the same field and is
more intuitive as to how it should be used.
Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Patrick Steinhardt <ps@pks.im>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Compiling under clang 10 gives:
grub-core/lib/LzmaEnc.c:1362:9: error: misleading indentation; statement is not part of the previous 'if' [-Werror,-Wmisleading-indentation]
{
^
grub-core/lib/LzmaEnc.c:1358:7: note: previous statement is here
if (repIndex == 0)
^
1 error generated.
It's not really that unclear in context: there's a commented-out
if-statement. But tweak the alignment anyway so that clang is happy.
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
When setting cipher IV mode, detection is done by prefix matching the
cipher IV mode part of the cipher mode string. Since "plain" matches
"plain64", we must check for "plain64" first. Otherwise, "plain64" will
be detected as "plain".
Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Patrick Steinhardt <ps@pks.im>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Currently the following is valid syntax but should be a syntax error:
grub> function f; { echo HERE; }
grub> f
HERE
This fix is not backward compatible, but current syntax is not documented
either and has no functional value. So any scripts with this unintended
syntax are technically syntactically incorrect and should not be relying
on this behavior.
Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
The UUID header for LUKS2 uses a format with dashes, same as for
LUKS(1). But while we strip these dashes for the latter, we don't for
the former. This isn't wrong per se, but it's definitely inconsistent
for users as they need to use the dashed format for LUKS2 and the
non-dashed format for LUKS when e.g. calling "cryptomount -u $UUID".
Fix this inconsistency by stripping dashes off of the LUKS2 UUID.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
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>
Like the tpm the shim_lock module is only enabled for x86_64 target.
However, there's nothing specific to x86_64 in the implementation and
it can be enabled for all EFI architectures.
Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Commit 781b3e5efc (tftp: Do not use priority queue) caused a regression
when fetching files over TFTP whose size is bigger than 65535 * block size.
grub> linux /images/pxeboot/vmlinuz
grub> echo $?
0
grub> initrd /images/pxeboot/initrd.img
error: timeout reading '/images/pxeboot/initrd.img'.
grub> echo $?
28
It is caused by the block number counter being a 16-bit field, which leads
to a maximum file size of ((1 << 16) - 1) * block size. Because GRUB sets
the block size to 1024 octets (by using the TFTP Blocksize Option from RFC
2348 [0]), the maximum file size that can be transferred is 67107840 bytes.
The TFTP PROTOCOL (REVISION 2) RFC 1350 [1] does not mention what a client
should do when a file size is bigger than the maximum, but most TFTP hosts
support the block number counter to be rolled over. That is, acking a data
packet with a block number of 0 is taken as if the 65356th block was acked.
It was working before because the block counter roll-over was happening due
an overflow. But that got fixed by the mentioned commit, which led to the
regression when attempting to fetch files larger than the maximum size.
To allow TFTP file transfers of unlimited size again, re-introduce a block
counter roll-over so the data packets are acked preventing the timeouts.
[0]: https://tools.ietf.org/html/rfc2348
[1]: https://tools.ietf.org/html/rfc1350
Fixes: 781b3e5efc (tftp: Do not use priority queue)
Suggested-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Here dev is a grub_cryptodisk_t and dev->offset is offset in sectors of size
native to the cryptodisk device. The sector is correctly transformed into
native grub sector size, but then added to dev->offset which is not
transformed. It would be nice if the type system would help us with this.
Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Patrick Steinhardt <ps@pks.im>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
While we already set up error messages in both luks2_verify_key() and
luks2_decrypt_key(), we do not ever print them. This makes it really
hard to discover why a given key actually failed to decrypt a disk.
Improve this by including the error message in the user-visible output.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
When configuring a LUKS disk, we copy over the UUID from the LUKS header
into the new grub_cryptodisk_t structure via grub_memcpy(). As size
we mistakenly use the size of the grub_cryptodisk_t UUID field, which
is guaranteed to be strictly bigger than the LUKS UUID field we're
copying. As a result, the copy always goes out-of-bounds and copies some
garbage from other surrounding fields. During runtime, this isn't
noticed due to the fact that we always NUL-terminate the UUID and thus
never hit the trailing garbage.
Fix the issue by using the size of the local stripped UUID field.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
The C standard does not allow for typedef redefinitions, even if they
map to the same underlying type. In order to avoid including the
jsmn.h in json.h and thus exposing jsmn's internals, we have exactly
such a forward-declaring typedef in json.h. If enforcing the GNU99 C
standard, clang may generate a warning about this non-standard
construct.
Fix the issue by using a simple "struct jsmntok" forward declaration
instead of using a typedef.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Tested-by: Chuck Tuffli <chuck@freebsd.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
These could be triggered by a crafted filesystem with very large files.
Fixes: CVE-2020-15707
Signed-off-by: Colin Watson <cjwatson@debian.org>
Reviewed-by: Jan Setje-Eilers <jan.setjeeilers@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
commit 92bfc33db9 ("efi: Free malloc regions on exit")
introduced memory freeing in grub_efi_fini(), which is
used not only by exit path but by halt/reboot one as well.
As result of memory freeing, code and data regions used by
modules, such as halt, reboot, acpi (used by halt) also got
freed. After return to module code, CPU executes, filled
by UEFI firmware (tested with edk2), 0xAFAFAFAF pattern as
a code. Which leads to #UD exception later.
grub> halt
!!!! X64 Exception Type - 06(#UD - Invalid Opcode) CPU Apic ID - 00000000 !!!!
RIP - 0000000003F4EC28, CS - 0000000000000038, RFLAGS - 0000000000200246
RAX - 0000000000000000, RCX - 00000000061DA188, RDX - 0A74C0854DC35D41
RBX - 0000000003E10E08, RSP - 0000000007F0F860, RBP - 0000000000000000
RSI - 00000000064DB768, RDI - 000000000832C5C3
R8 - 0000000000000002, R9 - 0000000000000000, R10 - 00000000061E2E52
R11 - 0000000000000020, R12 - 0000000003EE5C1F, R13 - 00000000061E0FF4
R14 - 0000000003E10D80, R15 - 00000000061E2F60
DS - 0000000000000030, ES - 0000000000000030, FS - 0000000000000030
GS - 0000000000000030, SS - 0000000000000030
CR0 - 0000000080010033, CR2 - 0000000000000000, CR3 - 0000000007C01000
CR4 - 0000000000000668, CR8 - 0000000000000000
DR0 - 0000000000000000, DR1 - 0000000000000000, DR2 - 0000000000000000
DR3 - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 - 0000000000000400
GDTR - 00000000079EEA98 0000000000000047, LDTR - 0000000000000000
IDTR - 0000000007598018 0000000000000FFF, TR - 0000000000000000
FXSAVE_STATE - 0000000007F0F4C0
Proposal here is to continue to free allocated memory for
exit boot services path but keep it for halt/reboot path
as it won't be much security concern here.
Introduced GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY
loader flag to be used by efi halt/reboot path.
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Without any error propagated to the caller, make_file_path()
would then try to advance the invalid device path node with
GRUB_EFI_NEXT_DEVICE_PATH(), which would fail, returning a NULL
pointer that would subsequently be dereferenced. Hence, propagate
errors from copy_file_path().
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Several places we take the length of a device path and subtract 4 from
it, without ever checking that it's >= 4. There are also cases where
this kind of malformation will result in unpredictable iteration,
including treating the length from one dp node as the type in the next
node. These are all errors, no matter where the data comes from.
This patch adds a checking macro, GRUB_EFI_DEVICE_PATH_VALID(), which
can be used in several places, and makes GRUB_EFI_NEXT_DEVICE_PATH()
return NULL and GRUB_EFI_END_ENTIRE_DEVICE_PATH() evaluate as true when
the length is too small. Additionally, it makes several places in the
code check for and return errors in these cases.
Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>