qemu-e2k/hw/nvram
Jason A. Donenfeld eac7a7791b x86: don't let decompressed kernel image clobber setup_data
The setup_data links are appended to the compressed kernel image. Since
the kernel image is typically loaded at 0x100000, setup_data lives at
`0x100000 + compressed_size`, which does not get relocated during the
kernel's boot process.

The kernel typically decompresses the image starting at address
0x1000000 (note: there's one more zero there than the compressed image
above). This usually is fine for most kernels.

However, if the compressed image is actually quite large, then
setup_data will live at a `0x100000 + compressed_size` that extends into
the decompressed zone at 0x1000000. In other words, if compressed_size
is larger than `0x1000000 - 0x100000`, then the decompression step will
clobber setup_data, resulting in crashes.

Visually, what happens now is that QEMU appends setup_data to the kernel
image:

          kernel image            setup_data
   |--------------------------||----------------|
0x100000                  0x100000+l1     0x100000+l1+l2

The problem is that this decompresses to 0x1000000 (one more zero). So
if l1 is > (0x1000000-0x100000), then this winds up looking like:

          kernel image            setup_data
   |--------------------------||----------------|
0x100000                  0x100000+l1     0x100000+l1+l2

                                 d e c o m p r e s s e d   k e r n e l
                     |-------------------------------------------------------------|
                0x1000000                                                     0x1000000+l3

The decompressed kernel seemingly overwriting the compressed kernel
image isn't a problem, because that gets relocated to a higher address
early on in the boot process, at the end of startup_64. setup_data,
however, stays in the same place, since those links are self referential
and nothing fixes them up.  So the decompressed kernel clobbers it.

Fix this by appending setup_data to the cmdline blob rather than the
kernel image blob, which remains at a lower address that won't get
clobbered.

This could have been done by overwriting the initrd blob instead, but
that poses big difficulties, such as no longer being able to use memory
mapped files for initrd, hurting performance, and, more importantly, the
initrd address calculation is hard coded in qboot, and it always grows
down rather than up, which means lots of brittle semantics would have to
be changed around, incurring more complexity. In contrast, using cmdline
is simple and doesn't interfere with anything.

The microvm machine has a gross hack where it fiddles with fw_cfg data
after the fact. So this hack is updated to account for this appending,
by reserving some bytes.

Fixup-by: Michael S. Tsirkin <mst@redhat.com>
Cc: x86@kernel.org
Cc: Philippe Mathieu-Daudé <philmd@linaro.org>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Message-Id: <20221230220725.618763-1-Jason@zx2c4.com>
Message-ID: <20230128061015-mutt-send-email-mst@kernel.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Tested-by: Eric Biggers <ebiggers@google.com>
Tested-by: Mathias Krause <minipli@grsecurity.net>
2023-01-28 06:21:29 -05:00
..
chrp_nvram.c nvram: Exit QEMU if NVRAM cannot contain all -prom-env data 2020-08-14 13:34:31 +10:00
ds1225y.c Use OBJECT_DECLARE_SIMPLE_TYPE when possible 2020-09-18 14:12:32 -04:00
eeprom93xx.c Drop useless casts from g_malloc() & friends to pointer 2022-10-22 23:15:40 +02:00
eeprom_at24c.c block: Change blk_{pread,pwrite}() param order 2022-07-12 12:14:56 +02:00
fw_cfg-interface.c hw/nvram: Always register FW_CFG_DATA_GENERATOR_INTERFACE 2020-10-12 11:50:20 -04:00
fw_cfg.c x86: don't let decompressed kernel image clobber setup_data 2023-01-28 06:21:29 -05:00
Kconfig hw/nvram: Introduce Xilinx battery-backed ram 2021-09-30 13:42:10 +01:00
mac_nvram.c hw/ppc/mac.h: Rename to include/hw/nvram/mac_nvram.h 2022-10-31 18:48:23 +00:00
meson.build hw/nvram: Restrict fw_cfg QOM interface to sysemu and tools 2022-01-18 10:45:35 +01:00
npcm7xx_otp.c hw/*: Use type casting for SysBusDevice in NPCM7XX 2021-01-12 21:19:02 +00:00
nrf51_nvm.c Do not include exec/address-spaces.h if it's not really necessary 2021-05-02 17:24:51 +02:00
spapr_nvram.c block: Change blk_{pread,pwrite}() param order 2022-07-12 12:14:56 +02:00
trace-events docs: fix references to docs/devel/tracing.rst 2021-06-02 06:51:09 +02:00
trace.h trace: switch position of headers to what Meson requires 2020-08-21 06:18:24 -04:00
xlnx-bbram.c block: Change blk_{pread,pwrite}() param order 2022-07-12 12:14:56 +02:00
xlnx-efuse-crc.c hw/nvram: Introduce Xilinx eFuse QOM 2021-09-30 13:42:09 +01:00
xlnx-efuse.c block: Change blk_{pread,pwrite}() param order 2022-07-12 12:14:56 +02:00
xlnx-versal-efuse-cache.c hw/nvram: Introduce Xilinx Versal eFuse device 2021-09-30 13:42:10 +01:00
xlnx-versal-efuse-ctrl.c hw/nvram: Fix Memory Leak in Xilinx Versal eFuse device 2021-10-23 18:50:33 +02:00
xlnx-zynqmp-efuse.c hw/nvram: Fix Memory Leak in Xilinx ZynqMP eFuse device 2021-10-23 18:50:33 +02:00