aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHelge Deller <deller@gmx.de>2024-03-22 12:07:22 +0100
committerHelge Deller <deller@gmx.de>2024-04-02 14:22:45 +0200
commita7d0b38d0df1dac5e799fe19ac1faa1e013ddf1b (patch)
treecbca8283a0b59c0d3baf1e3abdfb32b686c3dbd9
parent38c0692926bf2827d08239b7801b36223c5c19af (diff)
downloadseabios-hppa-a7d0b38d0df1dac5e799fe19ac1faa1e013ddf1b.zip
seabios-hppa-a7d0b38d0df1dac5e799fe19ac1faa1e013ddf1b.tar.gz
seabios-hppa-a7d0b38d0df1dac5e799fe19ac1faa1e013ddf1b.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>
-rw-r--r--src/parisc/parisc.c26
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()) ?
- &current_machine->pdc_model : &machine_B160L.pdc_model,
- sizeof(current_machine->pdc_model));
+ source = is_64bit_CPU() ? &current_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);