diff options
author | Alexander Yarygin <yarygin@linux.vnet.ibm.com> | 2015-08-10 13:57:03 +0300 |
---|---|---|
committer | Cornelia Huck <cornelia.huck@de.ibm.com> | 2016-05-17 15:50:29 +0200 |
commit | 9946a9113cf5d84c9381342100343aa97f736ee0 (patch) | |
tree | 42f6113e51f56e7c584d01c2bfc682e4f5aac873 /target-s390x | |
parent | 04ca4b92ecb33703b03b8501bfb3d8b0c551e2e5 (diff) | |
download | qemu-9946a9113cf5d84c9381342100343aa97f736ee0.zip qemu-9946a9113cf5d84c9381342100343aa97f736ee0.tar.gz qemu-9946a9113cf5d84c9381342100343aa97f736ee0.tar.bz2 |
s390x/ipl: Add type and length checks for IplParameterBlock values
We can check for valid type and lengths of the IplParameterBlock fields
when receiving the struct from the guest.
Length of the IplParameterBlock can be less than 4K. To play safe we can
read and write only required amount of data.
Signed-off-by: Alexander Yarygin <yarygin@linux.vnet.ibm.com>
Reviewed-by: David Hildenband <dahi@linux.vnet.ibm.com>
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Diffstat (limited to 'target-s390x')
-rw-r--r-- | target-s390x/misc_helper.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c index fab7f87..462cfc8 100644 --- a/target-s390x/misc_helper.c +++ b/target-s390x/misc_helper.c @@ -233,9 +233,22 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3) return; } iplb = g_malloc0(sizeof(IplParameterBlock)); - cpu_physical_memory_read(addr, iplb, S390_IPLB_MIN_CCW_LEN); + cpu_physical_memory_read(addr, iplb, sizeof(iplb->len)); + if (!iplb_valid_len(iplb)) { + env->regs[r1 + 1] = DIAG_308_RC_INVALID; + goto out; + } + + cpu_physical_memory_read(addr, iplb, be32_to_cpu(iplb->len)); + + if (!iplb_valid_ccw(iplb) && !iplb_valid_fcp(iplb)) { + env->regs[r1 + 1] = DIAG_308_RC_INVALID; + goto out; + } + s390_ipl_update_diag308(iplb); env->regs[r1 + 1] = DIAG_308_RC_OK; +out: g_free(iplb); return; case 6: @@ -250,7 +263,7 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3) } iplb = s390_ipl_get_iplb(); if (iplb) { - cpu_physical_memory_write(addr, iplb, S390_IPLB_MIN_CCW_LEN); + cpu_physical_memory_write(addr, iplb, be32_to_cpu(iplb->len)); env->regs[r1 + 1] = DIAG_308_RC_OK; } else { env->regs[r1 + 1] = DIAG_308_RC_NO_CONF; |