diff options
author | Helge Deller <deller@gmx.de> | 2024-03-22 12:07:22 +0100 |
---|---|---|
committer | Helge Deller <deller@gmx.de> | 2024-05-15 15:50:06 +0200 |
commit | e25c7c98c513feae3c6d60d008e352293d79a2f9 (patch) | |
tree | cbca8283a0b59c0d3baf1e3abdfb32b686c3dbd9 /src/parisc/parisc.c | |
parent | 8c0e08f088b94d1a5dd09aac90d7347a20cdb11f (diff) | |
download | seabios-hppa-e25c7c98c513feae3c6d60d008e352293d79a2f9.zip seabios-hppa-e25c7c98c513feae3c6d60d008e352293d79a2f9.tar.gz seabios-hppa-e25c7c98c513feae3c6d60d008e352293d79a2f9.tar.bz2 |
parisc: Avoid trashing MPE IPL bootloader stack
The MPE IPL boot loader calls PDC_MODEL when running in narrow mode.
The return buffer pointed to by arg2 holds space for eigth 32-bit integers
directly followed by the stack used by MPE.
So, when pdc_model() writes 32 64-bit integers to arg2, it unintentionally
overwrites MPE's call stack.
Fix it by limiting returned bytes depending if PDC_MODEL was called
in WIDE or NARROW mode.
Signed-off-by: Helge Deller <deller@gmx.de>
Diffstat (limited to 'src/parisc/parisc.c')
-rw-r--r-- | src/parisc/parisc.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/src/parisc/parisc.c b/src/parisc/parisc.c index 1c7b109..2d1f833 100644 --- a/src/parisc/parisc.c +++ b/src/parisc/parisc.c @@ -1499,11 +1499,14 @@ static int pdc_pim(unsigned long *arg) return PDC_BAD_OPTION; } -static int pdc_model(unsigned long *arg) +static int pdc_model(unsigned long *arg, unsigned long narrow_mode) { const char *model_str = current_machine->pdc_modelstr; unsigned long option = ARG1; unsigned long *result = (unsigned long *)ARG2; + unsigned int *result_narrow = (unsigned int *)ARG2; + unsigned long *source; + int i; switch (option) { case PDC_MODEL_INFO: @@ -1512,10 +1515,21 @@ static int pdc_model(unsigned long *arg) * with old qemu versions which will try to run 64-bit instructions * kernel sr_disable_hash() function */ - memset(result, 0, 32 * sizeof(unsigned long)); - memcpy(result, (is_64bit_CPU()) ? - ¤t_machine->pdc_model : &machine_B160L.pdc_model, - sizeof(current_machine->pdc_model)); + source = is_64bit_CPU() ? ¤t_machine->pdc_model.hversion + : &machine_B160L.pdc_model.hversion; + + /* make sure to only copy the necessary bytes. */ + NO_COMPAT_RETURN_VALUE(ARG2); + for (i = 0; i < sizeof(machine_B160L.pdc_model)/sizeof(unsigned long); i++) { + if (is_64bit_PDC() && narrow_mode) { + *result_narrow = *source; + result_narrow++; + } else { + *result = *source; + result++; + } + source++; + } return PDC_OK; case PDC_MODEL_VERSIONS: switch (ARG3) { @@ -2387,7 +2401,7 @@ int __VISIBLE parisc_pdc_entry(unsigned long *arg, unsigned long narrow_mode) return pdc_pim(arg); case PDC_MODEL: /* model information */ - return pdc_model(arg); + return pdc_model(arg, narrow_mode); case PDC_CACHE: return pdc_cache(arg); |