Commit Graph

2391 Commits

Author SHA1 Message Date
Steve McIntyre
2c1a132e34 Switch away from git-dpm 2022-12-04 18:22:27 +00:00
Zhang Boyang
afa02a1bb2 normal/charset: Fix an integer overflow in grub_unicode_aglomerate_comb()
The out->ncomb is a bit-field of 8 bits. So, the max possible value is 255.
However, code in grub_unicode_aglomerate_comb() doesn't check for an
overflow when incrementing out->ncomb. If out->ncomb is already 255,
after incrementing it will get 0 instead of 256, and cause illegal
memory access in subsequent processing.

This patch introduces GRUB_UNICODE_NCOMB_MAX to represent the max
acceptable value of ncomb. The code now checks for this limit and
ignores additional combining characters when limit is reached.

Reported-by: Daniel Axtens <dja@axtens.net>
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2022-11-12 22:51:49 +00:00
Zhang Boyang
c2491cb80c fbutil: Fix integer overflow
Expressions like u64 = u32 * u32 are unsafe because their products are
truncated to u32 even if left hand side is u64. This patch fixes all
problems like that one in fbutil.

To get right result not only left hand side have to be u64 but it's also
necessary to cast at least one of the operands of all leaf operators of
right hand side to u64, e.g. u64 = u32 * u32 + u32 * u32 should be
u64 = (u64)u32 * u32 + (u64)u32 * u32.

For 1-bit bitmaps grub_uint64_t have to be used. It's safe because any
combination of values in (grub_uint64_t)u32 * u32 + u32 expression will
not overflow grub_uint64_t.

Other expressions like ptr + u32 * u32 + u32 * u32 are also vulnerable.
They should be ptr + (grub_addr_t)u32 * u32 + (grub_addr_t)u32 * u32.

This patch also adds a comment to grub_video_fb_get_video_ptr() which
says it's arguments must be valid and no sanity check is performed
(like its siblings in grub-core/video/fb/fbutil.c).

Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2022-11-12 22:51:49 +00:00
Zhang Boyang
2f01e9c03b font: Fix size overflow in grub_font_get_glyph_internal()
The length of memory allocation and file read may overflow. This patch
fixes the problem by using safemath macros.

There is a lot of code repetition like "(x * y + 7) / 8". It is unsafe
if overflow happens. This patch introduces grub_video_bitmap_calc_1bpp_bufsz().
It is safe replacement for such code. It has safemath-like prototype.

This patch also introduces grub_cast(value, pointer), it casts value to
typeof(*pointer) then store the value to *pointer. It returns true when
overflow occurs or false if there is no overflow. The semantics of arguments
and return value are designed to be consistent with other safemath macros.

Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2022-11-12 22:51:49 +00:00
Alec Brown
85856560d5 video/readers: Add artificial limit to image dimensions
In grub-core/video/readers/jpeg.c, the height and width of a JPEG image don't
have an upper limit for how big the JPEG image can be. In Coverity, this is
getting flagged as an untrusted loop bound. This issue can also seen in PNG and
TGA format images as well but Coverity isn't flagging it. To prevent this, the
constant IMAGE_HW_MAX_PX is being added to include/grub/bitmap.h, which has
a value of 16384, to act as an artificial limit and restrict the height and
width of images. This value was picked as it is double the current max
resolution size, which is 8K.

Fixes: CID 292450

Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2022-11-12 22:51:49 +00:00
Daniel Axtens
e7573be61b net/tftp: Prevent a UAF and double-free from a failed seek
A malicious tftp server can cause UAFs and a double free.

An attempt to read from a network file is handled by grub_net_fs_read(). If
the read is at an offset other than the current offset, grub_net_seek_real()
is invoked.

In grub_net_seek_real(), if a backwards seek cannot be satisfied from the
currently received packets, and the underlying transport does not provide
a seek method, then grub_net_seek_real() will close and reopen the network
protocol layer.

For tftp, the ->close() call goes to tftp_close() and frees the tftp_data_t
file->data. The file->data pointer is not nulled out after the free.

If the ->open() call fails, the file->data will not be reallocated and will
continue point to a freed memory block. This could happen from a server
refusing to send the requisite ack to the new tftp request, for example.

The seek and the read will then fail, but the grub_file continues to exist:
the failed seek does not necessarily cause the entire file to be thrown
away (e.g. where the file is checked to see if it is gzipped/lzio/xz/etc.,
a read failure is interpreted as a decompressor passing on the file, not as
an invalidation of the entire grub_file_t structure).

This means subsequent attempts to read or seek the file will use the old
file->data after free. Eventually, the file will be close()d again and
file->data will be freed again.

Mark a net_fs file that doesn't reopen as broken. Do not permit read() or
close() on a broken file (seek is not exposed directly to the file API -
it is only called as part of read, so this blocks seeks as well).

As an additional defence, null out the ->data pointer if tftp_open() fails.
That would have lead to a simple null pointer dereference rather than
a mess of UAFs.

This may affect other protocols, I haven't checked.

Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2022-06-08 12:41:03 +02:00
Julian Andres Klode
24e6d59ac6 kern/efi/sb: Reject non-kernel files in the shim_lock verifier
We must not allow other verifiers to pass things like the GRUB modules.
Instead of maintaining a blocklist, maintain an allowlist of things
that we do not care about.

This allowlist really should be made reusable, and shared by the
lockdown verifier, but this is the minimal patch addressing
security concerns where the TPM verifier was able to mark modules
as verified (or the OpenPGP verifier for that matter), when it
should not do so on shim-powered secure boot systems.

Fixes: CVE-2022-28735

Signed-off-by: Julian Andres Klode <julian.klode@canonical.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2022-06-08 12:41:03 +02:00
Chris Coulson
bb35dbb9bf commands/boot: Add API to pass context to loader
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>
(cherry picked from commit 4322a64dde7e8fedb58e50b79408667129d45dd3)
2022-06-08 12:41:03 +02:00
Michael Chang
4a6abe501f i386-pc: build verifiers API as module
Given no core functions on i386-pc would require verifiers to work and
the only consumer of the verifier API is the pgp module, it looks good
to me that we can move the verifiers out of the kernel image and let
moddep.lst to auto-load it when pgp is loaded on i386-pc platform.

This helps to reduce the size of core image and thus can relax the
tension of exploding on some i386-pc system with very short MBR gap
size. See also a very comprehensive summary from Colin [1] about the
details.

[1] https://lists.gnu.org/archive/html/grub-devel/2021-03/msg00240.html

V2:
Drop COND_NOT_i386_pc and use !COND_i386_pc.
Add comment in kern/verifiers.c to help understanding what's going on
without digging into the commit history.

Reported-by: Colin Watson <cjwatson@debian.org>
Reviewed-by: Colin Watson <cjwatson@debian.org>
Signed-off-by: Michael Chang <mchang@suse.com>

Origin: other, https://lists.gnu.org/archive/html/grub-devel/2021-03/msg00251.html
Bug-Debian: https://bugs.debian.org/984488
Bug-Debian: https://bugs.debian.org/985374
Last-Update: 2021-09-24

Patch-Name: pc-verifiers-module.patch
2021-09-27 20:09:39 +01:00
Colin Watson
6e3841fc4a Minimise writes to EFI variable storage
Some UEFI firmware is easily provoked into running out of space in its
variable storage.  This is usually due to certain kernel drivers (e.g.
pstore), but regardless of the cause it can cause grub-install to fail
because it currently asks efibootmgr to delete and re-add entries, and
the deletion often doesn't result in an immediate garbage collection.
Writing variables frequently also increases wear on the NVRAM which may
have limited write cycles.  For these reasons, it's desirable to find a
way to minimise writes while still allowing grub-install to ensure that
a suitable boot entry exists.

Unfortunately, efibootmgr doesn't offer an interface that would let
grub-install do this.  It doesn't in general make very much effort to
minimise writes; it doesn't allow modifying an existing Boot* variable
entry, except in certain limited ways; and current versions don't have a
way to export the expected variable data so that grub-install can
compare it to the current data.  While it would be possible (and perhaps
desirable?) to add at least some of this to efibootmgr, that would still
leave the problem that there isn't a good upstreamable way for
grub-install to guarantee that it has a new enough version of
efibootmgr.  In any case, it's cumbersome and slow for grub-install to
have to fork efibootmgr to get things done.

Fortunately, a few years ago Peter Jones helpfully factored out a
substantial part of efibootmgr to the efivar and efiboot libraries, and
so it's now possible to have grub-install use those directly.  We still
have to use some code from efibootmgr, but much less than would
previously have been necessary.

grub-install now reuses existing boot entries where possible, and avoids
writing to variables when the new contents are the same as the old
contents.  In the common upgrade case where nothing needs to change, it
no longer writes to NVRAM at all.  It's also now slightly faster, since
using libefivar is faster than forking efibootmgr.

Fixes Debian bug #891434.

Signed-off-by: Colin Watson <cjwatson@ubuntu.com>

Bug-Debian: https://bugs.debian.org/891434
Forwarded: https://lists.gnu.org/archive/html/grub-devel/2019-03/msg00119.html
Last-Update: 2019-03-23

Patch-Name: efi-variable-storage-minimise-writes.patch
2021-09-27 20:09:39 +01:00
Michael Chang
5a2c53dd05 efinet: Setting DNS server from UEFI protocol
In the URI device path node, any name rahter than address can be used for
looking up the resources so that DNS service become needed to get answer of the
name's address. Unfortunately the DNS is not defined in any of the device path
nodes so that we use the EFI_IP4_CONFIG2_PROTOCOL and EFI_IP6_CONFIG_PROTOCOL
to obtain it.

These two protcols are defined the sections of UEFI specification.

 27.5 EFI IPv4 Configuration II Protocol
 27.7 EFI IPv6 Configuration Protocol

include/grub/efi/api.h:
Add new structure and protocol UUID of EFI_IP4_CONFIG2_PROTOCOL and
EFI_IP6_CONFIG_PROTOCOL.

grub-core/net/drivers/efi/efinet.c:
Use the EFI_IP4_CONFIG2_PROTOCOL and EFI_IP6_CONFIG_PROTOCOL to obtain the list
of DNS server address for IPv4 and IPv6 respectively. The address of DNS
servers is structured into DHCPACK packet and feed into the same DHCP packet
processing functions to ensure the network interface is setting up the same way
it used to be.

Signed-off-by: Michael Chang <mchang@suse.com>
Signed-off-by: Ken Lin <ken.lin@hpe.com>

Last-Update: 2021-09-24

Patch-Name: efinet-set-dns-from-uefi-proto.patch
2021-09-27 20:09:39 +01:00
Michael Chang
3f85b646c8 efinet: Setting network from UEFI device path
The PXE Base Code protocol used to obtain cached PXE DHCPACK packet is no
longer provided for HTTP Boot. Instead, we have to get the HTTP boot
information from the device path nodes defined in following UEFI Specification
sections.

 9.3.5.12 IPv4 Device Path
 9.3.5.13 IPv6 Device Path
 9.3.5.23 Uniform Resource Identifiers (URI) Device Path

This patch basically does:

include/grub/efi/api.h:
Add new structure of Uniform Resource Identifiers (URI) Device Path

grub-core/net/drivers/efi/efinet.c:
Check if PXE Base Code is available, if not it will try to obtain the netboot
information from the device path where the image booted from. The DHCPACK
packet is recoverd from the information in device patch and feed into the same
DHCP packet processing functions to ensure the network interface is setting up
the same way it used to be.

Signed-off-by: Michael Chang <mchang@suse.com>
Signed-off-by: Ken Lin <ken.lin@hpe.com>

Patch-Name: efinet-set-network-from-uefi-devpath.patch
2021-09-27 20:09:39 +01:00
Michael Chang
cd78a54e5f bootp: Add processing DHCPACK packet from HTTP Boot
The vendor class identifier with the string "HTTPClient" is used to denote the
packet as responding to HTTP boot request. In DHCP4 config, the filename for
HTTP boot is the URL of the boot file while for PXE boot it is the path to the
boot file. As a consequence, the next-server becomes obseleted because the HTTP
URL already contains the server address for the boot file. For DHCP6 config,
there's no difference definition in existing config as dhcp6.bootfile-url can
be used to specify URL for both HTTP and PXE boot file.

This patch adds processing for "HTTPClient" vendor class identifier in DHCPACK
packet by treating it as HTTP format, not as the PXE format.

Signed-off-by: Michael Chang <mchang@suse.com>
Signed-off-by: Ken Lin <ken.lin@hpe.com>

Last-Update: 2021-09-24

Patch-Name: bootp-process-dhcpack-http-boot.patch
2021-09-27 20:09:39 +01:00
Michael Chang
a124f29543 efinet: UEFI IPv6 PXE support
When grub2 image is booted from UEFI IPv6 PXE, the DHCPv6 Reply packet is
cached in firmware buffer which can be obtained by PXE Base Code protocol. The
network interface can be setup through the parameters in that obtained packet.

Signed-off-by: Michael Chang <mchang@suse.com>
Signed-off-by: Ken Lin <ken.lin@hpe.com>

Patch-Name: efinet-uefi-ipv6-pxe-support.patch
2021-09-27 20:09:39 +01:00
Michael Chang
2ce72d9b58 bootp: New net_bootp6 command
Implement new net_bootp6 command for IPv6 network auto configuration via the
DHCPv6 protocol (RFC3315).

Signed-off-by: Michael Chang <mchang@suse.com>
Signed-off-by: Ken Lin <ken.lin@hpe.com>

Last-Update: 2021-09-24

Patch-Name: bootp-new-net_bootp6-command.patch
2021-09-27 20:09:39 +01:00
Aaron Miller
c7e2338904 net: read bracketed ipv6 addrs and port numbers
Allow specifying port numbers for http and tftp paths, and allow ipv6 addresses
to be recognized with brackets around them, which is required to specify a port
number

Last-Update: 2021-09-24

Patch-Name: net-read-bracketed-ipv6-addr.patch
2021-09-27 20:09:39 +01:00
Colin Watson
4b6f846398 Port yaboot logic for various powerpc machine types
Some powerpc machines require not updating the NVRAM.  This can be handled
by existing grub-install command-line options, but it's friendlier to detect
this automatically.

On chrp_ibm machines, use the nvram utility rather than nvsetenv.  (This
is possibly suitable for other machines too, but that needs to be
verified.)

Forwarded: no
Last-Update: 2014-10-15

Patch-Name: install-powerpc-machtypes.patch
2021-09-27 20:09:38 +01:00
Evan Broder
bc7f762a1d Add configure option to enable gfxpayload=keep dynamically
Set GRUB_GFXPAYLOAD_LINUX=keep unless it's known to be unsupported on
the current hardware.  See
https://blueprints.launchpad.net/ubuntu/+spec/packageselection-foundations-n-grub2-boot-framebuffer.

Author: Colin Watson <cjwatson@ubuntu.com>
Forwarded: no
Last-Update: 2019-05-25

Patch-Name: gfxpayload-dynamic.patch
2021-09-27 20:09:38 +01:00
Matthew Garrett
fc550c31c2 Add "linuxefi" loader which avoids ExitBootServices
Origin: vendor, http://pkgs.fedoraproject.org/cgit/grub2.git/tree/grub2-linuxefi.patch
Author: Colin Watson <cjwatson@ubuntu.com>
Author: Steve Langasek <steve.langasek@canonical.com>
Author: Linn Crosetto <linn@hpe.com>
Forwarded: no
Last-Update: 2021-09-24

Patch-Name: linuxefi.patch
2021-09-27 20:09:34 +01:00
Colin Watson
a7b960126f Restore grub-mkdevicemap
This is kind of a mess, requiring lots of OS-specific code to iterate
over all possible devices.  However, we use it in a number of scripts to
discover devices and reimplementing those in terms of something else
would be very complicated.

Author: Dimitri John Ledkov <dimitri.ledkov@canonical.com>
Forwarded: no
Last-Update: 2021-09-24

Patch-Name: restore-mkdevicemap.patch
2021-09-24 22:18:39 +01:00
Colin Watson
21f954425f Import grub2_2.06.orig.tar.xz 2021-09-24 10:34:42 +01:00
Dimitri John Ledkov
8ddbdc3bc2 grub-install: Add backup and restore
Refactor clean_grub_dir() to create a backup of all the files, instead
of just irrevocably removing them as the first action. If available,
register atexit() handler to restore the backup if errors occur before
point of no return, or remove the backup if everything was successful.
If atexit() is not available, the backup remains on disk for manual
recovery.

Some platforms defined a point of no return, i.e. after modules & core
images were updated. Failures from any commands after that stage are
ignored, and backup is cleaned up. For example, on EFI platforms update
is not reverted when efibootmgr fails.

Extra care is taken to ensure atexit() handler is only invoked by the
parent process and not any children forks. Some older GRUB codebases
can invoke parent atexit() hooks from forks, which can mess up the
backup.

This allows safer upgrades of MBR & modules, such that
modules/images/fonts/translations are consistent with MBR in case of
errors. For example accidental grub-install /dev/non-existent-disk
currently clobbers and upgrades modules in /boot/grub, despite not
actually updating any MBR.

This patch only handles backup and restore of files copied to /boot/grub.
This patch does not perform backup (or restoration) of MBR itself or
blocklists. Thus when installing i386-pc platform, corruption may still
occur with MBR and blocklists which will not be attempted to be
automatically recovered.

Also add modinfo.sh and *.efi to the cleanup/backup/restore code path,
to ensure it is also cleaned, backed up and restored.

Signed-off-by: Dimitri John Ledkov <xnox@ubuntu.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2021-06-01 17:20:20 +02:00
Carlos Maiolino
8b1e5d1936 fs/xfs: Add bigtime incompat feature support
The XFS filesystem supports a bigtime feature to overcome y2038 problem.
This patch makes the GRUB able to support the XFS filesystems with this
feature enabled.

The XFS counter for the bigtime enabled timestamps starts at 0, which
translates to GRUB_INT32_MIN (Dec 31 20:45:52 UTC 1901) in the legacy
timestamps. The conversion to Unix timestamps is made before passing the
value to other GRUB functions.

For this to work properly, GRUB requires an access to flags2 field in the
XFS ondisk inode. So, the grub_xfs_inode structure has been updated to
cover full ondisk inode.

Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2021-06-01 17:20:20 +02:00
Carlos Maiolino
81f1962393 fs: Use 64-bit type for filesystem timestamp
Some filesystems nowadays use 64-bit types for timestamps. So, update
grub_dirhook_info struct to use an grub_int64_t type to store mtime.
This also updates the grub_unixtime2datetime() function to receive
a 64-bit timestamp argument and do 64-bit-safe divisions.

All the remaining conversion from 32-bit to 64-bit should be safe, as
32-bit to 64-bit attributions will be implicitly casted. The most
critical part in the 32-bit to 64-bit conversion is in the function
grub_unixtime2datetime() where it needs to deal with the 64-bit type.
So, for that, the grub_divmod64() helper has been used.

These changes enables the GRUB to support dates beyond y2038.

Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2021-06-01 17:19:13 +02:00
Javier Martinez Canillas
af54062b54 types: Define PRI{x,d}GRUB_INT{32,64}_T format specifiers
There are already PRI*_T constants defined for unsigned integers but not
for signed integers. Add format specifiers for the latter.

Suggested-by: Daniel Kiper <daniel.kiper@oracle.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2021-05-28 15:57:05 +02:00
Colin Watson
edbe7076cb buffer: Sync up out-of-range error message
The messages associated with other similar GRUB_ERR_OUT_OF_RANGE errors
were lacking the trailing full stop. Syncing up the strings saves a small
amount of precious core image space on i386-pc.

  DOWN: obj/i386-pc/grub-core/kernel.img (31740 > 31708) - change: -32
  DOWN: i386-pc core image (biosdisk ext2 part_msdos) (27453 > 27452) - change: -1
  DOWN: i386-pc core image (biosdisk ext2 part_msdos diskfilter mdraid09) (32367 > 32359) - change: -8

Signed-off-by: Colin Watson <cjwatson@debian.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2021-04-12 16:31:18 +02:00
Ard Biesheuvel
a166484483 arm/linux: Fix ARM Linux header layout
The hdr_offset member of the ARM Linux image header appears at
offset 0x3c, matching the PE/COFF spec's placement of the COFF
header offset in the MS-DOS header. We're currently off by four,
so fix that.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2021-03-11 20:57:42 +01:00
Glenn Washburn
57236f2dd9 grub/err: Do compile-time format string checking on grub_error()
This should help prevent format string errors and thus improve the quality
of error reporting.

Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2021-03-10 15:23:34 +01:00
Heinrich Schuchardt
0860abe130 commands/efi/lsefisystab: Add short text for EFI_RT_PROPERTIES_TABLE_GUID
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>
2021-03-02 17:35:30 +01:00
Thomas Frauendorfer | Miray Software
83603bea6c kern/misc: Add function to check printf() format against expected format
The grub_printf_fmt_check() function parses the arguments of an untrusted
printf() format and an expected printf() format and then compares the
arguments counts and arguments types. The arguments count in the untrusted
format string must be less or equal to the arguments count in the expected
format string and both arguments types must match.

To do this the parse_printf_arg_fmt() helper function is extended in the
following way:

  1. Add a return value to report errors to the grub_printf_fmt_check().

  2. Add the fmt_check argument to enable stricter format verification:
     - the function expects that arguments definitions are always
       terminated by a supported conversion specifier.
     - positional parameters, "$", are not allowed, as they cannot be
       validated correctly with the current implementation. For example
       "%s%1$d" would assign the first args entry twice while leaving the
       second one unchanged.
     - Return an error if preallocated space in args is too small and
       allocation fails for the needed size. The grub_printf_fmt_check()
       should verify all arguments. So, if validation is not possible for
       any reason it should return an error.
     This also adds a case entry to handle "%%", which is the escape
     sequence to print "%" character.

  3. Add the max_args argument to check for the maximum allowed arguments
     count in a printf() string. This should be set to the arguments count
     of the expected format. Then the parse_printf_arg_fmt() function will
     return an error if the arguments count is exceeded.

The two additional arguments allow us to use parse_printf_arg_fmt() in
printf() and grub_printf_fmt_check() calls.

When parse_printf_arg_fmt() is used by grub_printf_fmt_check() the
function parse user provided untrusted format string too. So, in
that case it is better to be too strict than too lenient.

Signed-off-by: Thomas Frauendorfer | Miray Software <tf@miray.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2021-03-02 15:54:20 +01:00
Dimitri John Ledkov
968de8c23c shim_lock: Only skip loading shim_lock verifier with explicit consent
Commit 32ddc42c (efi: Only register shim_lock verifier if shim_lock
protocol is found and SB enabled) reintroduced CVE-2020-15705 which
previously only existed in the out-of-tree linuxefi patches and was
fixed as part of the BootHole patch series.

Under Secure Boot enforce loading shim_lock verifier. Allow skipping
shim_lock verifier if SecureBoot/MokSBState EFI variables indicate
skipping validations, or if GRUB image is built with --disable-shim-lock.

Fixes: 132ddc42c (efi: Only register shim_lock verifier if shim_lock
       protocol is found and SB enabled)
Fixes: CVE-2020-15705
Fixes: CVE-2021-3418

Reported-by: Dimitri John Ledkov <xnox@ubuntu.com>
Signed-off-by: Dimitri John Ledkov <xnox@ubuntu.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2021-03-02 15:54:19 +01:00
Dimitri John Ledkov
bb51ee2b49 grub-install-common: Add --sbat option
Signed-off-by: Dimitri John Ledkov <xnox@ubuntu.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2021-03-02 15:54:19 +01:00
Peter Jones
b115471377 util/mkimage: Add an option to import SBAT metadata into a .sbat section
Add a --sbat option to the grub-mkimage tool which allows us to import
an SBAT metadata formatted as a CSV file into a .sbat section of the
EFI binary.

Signed-off-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2021-03-02 15:54:19 +01:00
Chris Coulson
133d73079c kern/efi: Add initial stack protector implementation
It works only on UEFI platforms but can be quite easily extended to
others architectures and platforms if needed.

Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Marco A Benatto <mbenatto@redhat.com>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
2021-03-02 15:54:19 +01:00
Chris Coulson
030fb6c4fa kern/buffer: Add variable sized heap buffer
Add a new variable sized heap buffer type (grub_buffer_t) with simple
operations for appending data, accessing the data and maintaining
a read cursor.

Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2021-03-02 15:54:19 +01:00
Daniel Axtens
2ca0e5dbcd fs/hfsplus: Don't use uninitialized data on corrupt filesystems
Valgrind identified the following use of uninitialized data:

  ==2782220== Conditional jump or move depends on uninitialised value(s)
  ==2782220==    at 0x42B364: grub_hfsplus_btree_search (hfsplus.c:566)
  ==2782220==    by 0x42B21D: grub_hfsplus_read_block (hfsplus.c:185)
  ==2782220==    by 0x42A693: grub_fshelp_read_file (fshelp.c:386)
  ==2782220==    by 0x42C598: grub_hfsplus_read_file (hfsplus.c:219)
  ==2782220==    by 0x42C598: grub_hfsplus_mount (hfsplus.c:330)
  ==2782220==    by 0x42B8C5: grub_hfsplus_dir (hfsplus.c:958)
  ==2782220==    by 0x4C1AE6: grub_fs_probe (fs.c:73)
  ==2782220==    by 0x407C94: grub_ls_list_files (ls.c:186)
  ==2782220==    by 0x407C94: grub_cmd_ls (ls.c:284)
  ==2782220==    by 0x4D7130: grub_extcmd_dispatcher (extcmd.c:55)
  ==2782220==    by 0x4045A6: execute_command (grub-fstest.c:59)
  ==2782220==    by 0x4045A6: fstest (grub-fstest.c:433)
  ==2782220==    by 0x4045A6: main (grub-fstest.c:772)
  ==2782220==  Uninitialised value was created by a heap allocation
  ==2782220==    at 0x483C7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
  ==2782220==    by 0x4C0305: grub_malloc (mm.c:42)
  ==2782220==    by 0x42C21D: grub_hfsplus_mount (hfsplus.c:239)
  ==2782220==    by 0x42B8C5: grub_hfsplus_dir (hfsplus.c:958)
  ==2782220==    by 0x4C1AE6: grub_fs_probe (fs.c:73)
  ==2782220==    by 0x407C94: grub_ls_list_files (ls.c:186)
  ==2782220==    by 0x407C94: grub_cmd_ls (ls.c:284)
  ==2782220==    by 0x4D7130: grub_extcmd_dispatcher (extcmd.c:55)
  ==2782220==    by 0x4045A6: execute_command (grub-fstest.c:59)
  ==2782220==    by 0x4045A6: fstest (grub-fstest.c:433)
  ==2782220==    by 0x4045A6: main (grub-fstest.c:772)

This happens when the process of reading the catalog file goes sufficiently
wrong that there's an attempt to read the extent overflow file, which has
not yet been loaded. Keep track of when the extent overflow file is
fully loaded and refuse to use it before then.

The load valgrind doesn't like is btree->nodesize, and that's then used
to allocate a data structure. It looks like there are subsequently a lot
of reads based on that pointer so OOB reads are likely, and indeed crashes
(albeit difficult-to-replicate ones) have been observed in fuzzing.

Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2021-03-02 15:54:18 +01:00
Javier Martinez Canillas
128c16a682 usb: Avoid possible out-of-bound accesses caused by malicious devices
The maximum number of configurations and interfaces are fixed but there is
no out-of-bound checking to prevent a malicious USB device to report large
values for these and cause accesses outside the arrays' memory.

Fixes: CVE-2020-25647

Reported-by: Joseph Tartaro <joseph.tartaro@ioactive.com>
Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2021-03-02 15:54:15 +01:00
Javier Martinez Canillas
7630ec5397 dl: Only allow unloading modules that are not dependencies
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>
2021-03-02 15:54:15 +01:00
Javier Martinez Canillas
578c95298b kern: Add lockdown support
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>
2021-03-02 15:54:15 +01:00
Marco A Benatto
5e280caa65 efi: Move the shim_lock verifier to the GRUB core
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>
2021-03-02 15:54:15 +01:00
Marco A Benatto
9e95f45cee verifiers: Move verifiers API to kernel image
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>
2021-03-02 15:54:15 +01:00
Glenn Washburn
3ab19ba3b1 misc: Add grub_log2ull() macro for calculating log base 2 of 64-bit integers
Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-12-18 23:08:14 +01:00
Glenn Washburn
9b4e8f0c4b mips: Enable __clzdi2()
This patch is similar to commit 9dab2f51e (sparc: Enable __clzsi2() and
__clzdi2()) but for MIPS target and __clzdi2() only, __clzsi2() was
already enabled.

Suggested-by: Daniel Kiper <dkiper@net-space.pl>
Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-12-18 23:04:36 +01:00
Glenn Washburn
9c3149a2f2 luks2: Better error handling when setting up the cryptodisk
Do some sanity checking on data coming from the LUKS2 header. If segment.size
is "dynamic", verify that the offset is not past the end of disk. Otherwise,
check for errors from grub_strtoull() when converting segment size from
string. If a GRUB_ERR_BAD_NUMBER error was returned, then the string was
not a valid parsable number, so skip the key. If GRUB_ERR_OUT_OF_RANGE was
returned, then there was an overflow in converting to a 64-bit unsigned
integer. So this could be a very large disk (perhaps large RAID array).
In this case skip the key too. Additionally, enforce some other limits
and fail if needed.

Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-12-18 23:00:28 +01:00
Glenn Washburn
cf3a3acff0 cryptodisk: Properly handle non-512 byte sized sectors
By default, dm-crypt internally uses an IV that corresponds to 512-byte
sectors, even when a larger sector size is specified. What this means is
that when using a larger sector size, the IV is incremented every sector.
However, the amount the IV is incremented is the number of 512 byte blocks
in a sector (i.e. 8 for 4K sectors). Confusingly the IV does not correspond
to the number of, for example, 4K sectors. So each 512 byte cipher block in
a sector will be encrypted with the same IV and the IV will be incremented
afterwards by the number of 512 byte cipher blocks in the sector.

There are some encryption utilities which do it the intuitive way and have
the IV equal to the sector number regardless of sector size (ie. the fifth
sector would have an IV of 4 for each cipher block). And this is supported
by dm-crypt with the iv_large_sectors option and also cryptsetup as of 2.3.3
with the --iv-large-sectors, though not with LUKS headers (only with --type
plain). However, support for this has not been included as grub does not
support plain devices right now.

One gotcha here is that the encrypted split keys are encrypted with a hard-
coded 512-byte sector size. So even if your data is encrypted with 4K sector
sizes, the split key encrypted area must be decrypted with a block size of
512 (ie the IV increments every 512 bytes). This made these changes less
aesthetically pleasing than desired.

Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-12-12 01:19:05 +01:00
Glenn Washburn
b34cb38795 cryptodisk: Add macros GRUB_TYPE_U_MAX/MIN(type) to replace literals
Add GRUB_TYPE_U_MAX/MIN(type) macros to get the max/min values for an
unsigned number with size of type.

Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-12-12 01:19:04 +01:00
Glenn Washburn
3e5f7f5112 cryptodisk: Add macro GRUB_TYPE_BITS() to replace some literals
The new macro GRUB_TYPE_BITS(type) returns the number of bits
allocated for type.

Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-12-12 01:19:04 +01:00
Glenn Washburn
8e8b2316ac misc: Add parentheses around ALIGN_UP() and ALIGN_DOWN() arguments
This ensures that expected order of operations is preserved when arguments
are expressions.

Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Patrick Steinhardt <ps@pks.im>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-12-12 01:19:04 +01:00
Glenn Washburn
880dfd8f40 disk: Rename grub_disk_get_size() to grub_disk_native_sectors()
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>
2020-12-12 01:19:03 +01:00
Glenn Washburn
407ddead69 disk: Move hardcoded max disk size literal to a GRUB_DISK_MAX_SECTORS in disk.h
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>
2020-12-12 01:19:03 +01:00