An invalid length in an SCCB header correctly generates a specification exception for the regular (non-PV) codepath that processes an SCLP instruction intercept. The PV case doesn't, even though such a thing should already be sanitized. Since a short length will cause problems later down the line with the storage that will be allocated based on that size, put up a defensive check and return if it is too short.
Cc: Janosch Frank <[email protected]> Fixes: c1db53a591 ("s390/sclp: read sccb from mem based on provided length") Signed-off-by: Eric Farman <[email protected]> --- hw/s390x/sclp.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c index d8b655efcc..ad8129a5d8 100644 --- a/hw/s390x/sclp.c +++ b/hw/s390x/sclp.c @@ -277,6 +277,11 @@ int sclp_service_call_protected(S390CPU *cpu, uint64_t sccb, uint32_t code) s390_cpu_pv_mem_read(env_archcpu(env), 0, &header, sizeof(SCCBHeader)); + /* Do nothing if the header appears malformed */ + if (be16_to_cpu(header.length) < sizeof(SCCBHeader)) { + goto out_no_write; + } + work_sccb = g_malloc0(be16_to_cpu(header.length)); s390_cpu_pv_mem_read(env_archcpu(env), 0, work_sccb, be16_to_cpu(header.length)); @@ -290,6 +295,7 @@ int sclp_service_call_protected(S390CPU *cpu, uint64_t sccb, uint32_t code) out_write: s390_cpu_pv_mem_write(env_archcpu(env), 0, work_sccb, be16_to_cpu(header.length)); +out_no_write: sclp_c->service_interrupt(sclp, SCLP_PV_DUMMY_ADDR); return 0; } -- 2.53.0
