Bootstd reads files from whatever boot media it finds, such as a USB
stick or SD card, or from a TFTP server, and some of the sizes and
offsets that decide where those files land in memory come from the
media itself. This series checks them in four places where they are
used as they are.

Patch 1: the pxe parser reads a file named by 'include' to the memory
just after the config file that includes it. The extlinux and pxe
bootmeths parse the config file from a heap buffer allocated to fit it,
so the included file, of up to 1GB, is written past the end of that
buffer. Refuse 'include' in a config file read by a bootmeth; the pxe
and sysboot commands, which read the config file to ${pxefile_addr_r},
keep it.

Patch 2: the load command refuses to read a file over reserved memory,
such as U-Boot itself, since the fix for CVE-2018-18440. The bootmeths
and sysboot read files with fs_read(), which does not check this, so a
large kernel, initrd or FDT can be written over U-Boot. sysboot had the
check until it stopped using the load commands. Use the load command's
checked read in both.

Patch 3: the ChromiumOS bootmeth takes the bootloader address and size
from the kernel preamble without checking them against the kernel body.
Check them, in the same way as the recent keyblock_size check. Its
private data is now allocated zeroed, since the error path frees a
buffer pointer in it which is only set once the read succeeds.

Patch 4: zimage_get_kernel_version() takes the offset of the version
string from the setup header and reads as far as the nul terminator,
without a limit on either. Give it the size of what it may read. This
one is for x86 and touches the ChromiumOS bootmeth only to pass the
size.

Patches 1-3 add sandbox tests (bootflow_extlinux_include,
bootmeth_read_reserved and two more partitions in the bootflow_cros
image) which fail without the fix and pass with it. All the bootstd
tests pass on sandbox with the series applied, and patch 4 builds for
qemu-x86_64.

The patches are independent of each other.

CI: v1, whose code v2 keeps as it was, passes all jobs of U-Boot's
Azure pipeline, in build 13713 of my CI-only pull request, merged with
main 3973f3c4d24. v2 changes only a comment.
PR:    https://github.com/u-boot/u-boot/pull/1064
Build: https://dev.azure.com/u-boot/u-boot/_build/results?buildId=13713

Changes in v2:
- Patch 1: document no_include in the form the other bools of struct
  pxe_context use (Tom)

Ana Bobillo (4):
  boot: pxe: Refuse 'include' in a config file read by a bootmeth
  fs: Check reserved memory when bootmeths and sysboot read files
  bootstd: cros: Check where the preamble puts the bootloader
  x86: zimage: Bound the kernel version string to the image

 arch/x86/lib/zimage.c    | 27 ++++++++++-----
 boot/bootmeth-uclass.c   |  2 +-
 boot/bootmeth_cros.c     | 31 +++++++++++++++--
 boot/bootmeth_extlinux.c |  3 ++
 boot/bootmeth_pxe.c      |  3 ++
 boot/pxe_utils.c         |  7 ++++
 cmd/sysboot.c            |  2 +-
 fs/fs.c                  | 12 +++++--
 include/bootm.h          |  6 ++--
 include/fs.h             | 19 ++++++++++
 include/pxe_utils.h      |  3 ++
 test/boot/bootflow.c     | 51 +++++++++++++++++++++++++--
 test/boot/bootmeth.c     | 75 ++++++++++++++++++++++++++++++++++++++++
 test/py/tests/test_ut.py | 22 +++++++++---
 14 files changed, 238 insertions(+), 25 deletions(-)


base-commit: 03e45557e1f38a39a0c80fe30483130ff376cf92

Reply via email to