qemu/hw
Greg Kurz 37035df51e nvram: Exit QEMU if NVRAM cannot contain all -prom-env data
Since commit 61f20b9dc5 ("spapr_nvram: Pre-initialize the NVRAM to
support the -prom-env parameter"), pseries machines can pre-initialize
the "system" partition in the NVRAM with the data passed to all -prom-env
parameters on the QEMU command line.

In this case it is assumed that all the data fits in 64 KiB, but the user
can easily pass more and crash QEMU:

$ qemu-system-ppc64 -M pseries $(for ((x=0;x<128;x++)); do \
  echo -n " -prom-env " ; printf "%0.sx" {1..1024}; \
  done) # this requires ~128 Kib
malloc(): corrupted top size
Aborted (core dumped)

This happens because we don't check if all the prom-env data fits in
the NVRAM and chrp_nvram_set_var() happily memcpy() it passed the
buffer.

This crash affects basically all ppc/ppc64 machine types that use -prom-env:
- pseries (all versions)
- g3beige
- mac99

and also sparc/sparc64 machine types:
- LX
- SPARCClassic
- SPARCbook
- SS-10
- SS-20
- SS-4
- SS-5
- SS-600MP
- Voyager
- sun4u
- sun4v

Add a max_len argument to chrp_nvram_create_system_partition() so that
it can check the available size before writing to memory.

Since NVRAM is populated at machine init, it seems reasonable to consider
this error as fatal. So, instead of reporting an error when we detect that
the NVRAM is too small and adapt all machine types to handle it, we simply
exit QEMU in all cases. This is still better than crashing. If someone
wants another behavior, I guess this can be reworked later.

Tested with:

$ yes q | \
  (for arch in ppc ppc64 sparc sparc64; do \
       echo == $arch ==; \
       qemu=${arch}-softmmu/qemu-system-$arch; \
       for mach in $($qemu -M help | awk '! /^Supported/ { print $1 }'); do \
           echo $mach; \
           $qemu -M $mach -monitor stdio -nodefaults -nographic \
           $(for ((x=0;x<128;x++)); do \
                 echo -n " -prom-env " ; printf "%0.sx" {1..1024}; \
             done) >/dev/null; \
        done; echo; \
   done)

Without the patch, affected machine types cause QEMU to report some
memory corruption and crash:

malloc(): corrupted top size

free(): invalid size

*** stack smashing detected ***: terminated

With the patch, QEMU prints the following message and exits:

NVRAM is too small. Try to pass less data to -prom-env

It seems that the conditions for the crash have always existed, but it
affects pseries, the machine type I care for, since commit 61f20b9dc5
only.

Fixes: 61f20b9dc5 ("spapr_nvram: Pre-initialize the NVRAM to support the -prom-env parameter")
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1867739
Reported-by: John Snow <jsnow@redhat.com>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <159736033937.350502.12402444542194031035.stgit@bahia.lan>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2020-08-14 13:34:31 +10:00
..
9pfs virtio-9p: Use ERRP_GUARD() 2020-07-10 15:18:09 +02:00
acpi ACPI: Assert that we don't run out of the preallocated memory 2020-07-27 16:12:10 +01:00
adc hw/adc/stm32f2xx_adc: Correct memory region size and access size 2020-06-05 17:23:09 +01:00
alpha sysbus: Convert to sysbus_realize() etc. with Coccinelle 2020-06-15 22:05:28 +02:00
arm hw/arm/nrf51_soc: Set system_clock_scale 2020-08-03 17:55:31 +01:00
audio audio: set default value for pcspk.iobase property 2020-07-06 17:01:11 +02:00
avr hw/avr/boot: Fix memory leak in avr_load_firmware() 2020-07-21 16:13:04 +02:00
block qom: Change object_get_canonical_path_component() not to malloc 2020-07-21 16:23:43 +02:00
char hw/char: Convert the Ibex UART to use the registerfields API 2020-07-13 17:25:37 -07:00
core hw/pci-host: save/restore pci host config register 2020-07-27 10:24:39 -04:00
cpu error: Eliminate error_propagate() with Coccinelle, part 1 2020-07-10 15:18:08 +02:00
cris sysbus: Convert to sysbus_realize() etc. with Coccinelle 2020-06-15 22:05:28 +02:00
display qxl: fix modular builds with dtrace 2020-07-21 10:56:47 +02:00
dma hw: Mark nd_table[] misuse in realize methods FIXME 2020-07-21 08:41:15 +02:00
gpio error: Eliminate error_propagate() with Coccinelle, part 1 2020-07-10 15:18:08 +02:00
hppa sysbus: Convert to sysbus_realize() etc. with Coccinelle 2020-06-15 22:05:28 +02:00
hyperv error: Avoid unnecessary error_propagate() after error_setg() 2020-07-10 15:18:08 +02:00
i2c hw/i2c: Rename i2c_create_slave() as i2c_slave_create_simple() 2020-07-16 12:30:54 -05:00
i386 hw/pci-host: save/restore pci host config register 2020-07-27 10:24:39 -04:00
ide qom: Put name parameter before value / visitor parameter 2020-07-10 15:18:08 +02:00
input hw/input/virtio-input-hid.c: Don't undef CONFIG_CURSES 2020-07-24 16:15:28 +02:00
intc spapr/xive: Simplify error handling of kvmppc_xive_cpu_synchronize_state() 2020-08-13 21:09:38 +10:00
ipack qdev: Unrealize must not fail 2020-05-15 07:08:14 +02:00
ipmi ipmi: add SET_SENSOR_READING command 2020-07-17 11:39:46 -05:00
isa error: Eliminate error_propagate() with Coccinelle, part 1 2020-07-10 15:18:08 +02:00
lm32 sysbus: Convert to sysbus_realize() etc. with Coccinelle 2020-06-15 22:05:28 +02:00
m68k qom: Put name parameter before value / visitor parameter 2020-07-10 15:18:08 +02:00
mem qom: Change object_get_canonical_path_component() not to malloc 2020-07-21 16:23:43 +02:00
microblaze error: Eliminate error_propagate() with Coccinelle, part 1 2020-07-10 15:18:08 +02:00
mips error: Eliminate error_propagate() with Coccinelle, part 1 2020-07-10 15:18:08 +02:00
misc hw/misc/aspeed_sdmc: Fix incorrect memory size 2020-07-27 16:12:10 +01:00
moxie hw: Make MachineClass::is_default a boolean type 2020-02-28 14:57:19 -05:00
net hw/net/net_tx_pkt: fix assertion failure in net_tx_pkt_add_raw_fragment() 2020-08-04 14:14:48 +08:00
nios2 hw/nios2: exit to main CPU loop only when unmasking interrupts 2020-07-13 14:36:11 +01:00
nubus hw: Remove unnecessary DEVICE() cast 2020-05-15 07:08:52 +02:00
nvram nvram: Exit QEMU if NVRAM cannot contain all -prom-env data 2020-08-14 13:34:31 +10:00
openrisc sysbus: Convert to sysbus_realize() etc. with Coccinelle 2020-06-15 22:05:28 +02:00
pci hw/pci-host: save/restore pci host config register 2020-07-27 10:24:39 -04:00
pci-bridge sysbus: Convert to sysbus_realize() etc. with Coccinelle 2020-06-15 22:05:28 +02:00
pci-host xen: Use ERRP_GUARD() 2020-07-10 15:18:09 +02:00
pcmcia sysbus: Convert to sysbus_realize() etc. with Coccinelle 2020-06-15 22:05:28 +02:00
ppc spapr: Simplify error handling in spapr_phb_realize() 2020-08-13 21:00:52 +10:00
rdma lockable: Replace locks with lock guard macros 2020-05-04 16:07:43 +01:00
riscv hw/riscv: sifive_e: Correct debug block size 2020-07-22 09:39:46 -07:00
rtc goldfish_rtc: Fix non-atomic read behaviour of TIME_LOW/TIME_HIGH 2020-07-22 09:39:46 -07:00
rx qom: Put name parameter before value / visitor parameter 2020-07-10 15:18:08 +02:00
s390x s390x/s390-virtio-ccw: fix off-by-one in loadparm getter 2020-07-30 16:53:34 +02:00
scsi error: Avoid error_propagate() after migrate_add_blocker() 2020-07-10 15:18:08 +02:00
sd sd/milkymist-memcard: Fix format string 2020-07-24 15:03:09 +02:00
semihosting semihosting: don't send the trailing '\0' 2020-07-27 09:40:08 +01:00
sh4 hw/sh4: Extract timer definitions to 'hw/timer/tmu012.h' 2020-06-22 18:37:12 +02:00
smbios error: Eliminate error_propagate() with Coccinelle, part 1 2020-07-10 15:18:08 +02:00
sparc nvram: Exit QEMU if NVRAM cannot contain all -prom-env data 2020-08-14 13:34:31 +10:00
sparc64 nvram: Exit QEMU if NVRAM cannot contain all -prom-env data 2020-08-14 13:34:31 +10:00
ssi ssi: Add ssi_realize_and_unref() 2020-07-03 16:59:44 +01:00
timer hw/timer/imx_epit: Avoid assertion when CR.SWR is written 2020-08-03 17:56:11 +01:00
tpm tpm: tpm_spapr: Exit on TPM backend failures 2020-07-15 14:57:33 -04:00
tricore hw: Do not initialize MachineClass::is_default to 0 2020-02-28 14:57:19 -05:00
unicore32 hw/unicore32/puv3: Use qemu_log_mask(ERROR) instead of debug printf() 2020-06-09 19:01:56 +02:00
usb hw: Only compile the usb-dwc2 controller if it is really needed 2020-07-24 16:15:28 +02:00
vfio vfio: fix use-after-free in display 2020-07-16 10:20:12 +02:00
virtio virtio-mem: Correct format specifier mismatch for RISC-V 2020-08-04 11:48:17 -04:00
watchdog hw/watchdog/cmsdk-apb-watchdog: Add trace event for lock status 2020-06-23 11:39:47 +01:00
xen osdep.h: Always include <sys/signal.h> if it exists 2020-07-13 14:36:09 +01:00
xenpv trivial: Remove xenfb_enabled from sysemu.h 2020-02-04 09:00:57 +01:00
xtensa qdev: Make qdev_prop_set_drive() match the other helpers 2020-06-23 16:07:07 +02:00
Kconfig hw/avr: Add limited support for some Arduino boards 2020-07-11 11:02:05 +02:00
Makefile.objs vga: build qxl as module 2020-07-07 15:33:59 +02:00