From 6cc7c8dd7a6fac493c648c607bec4c38c0b275b6 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Wed, 11 Nov 2020 12:03:09 -0500 Subject: [PATCH 09/18] s390/sclp: check sccb len before filling in data RH-Author: Thomas Huth Message-id: <20201111120316.707489-6-thuth@redhat.com> Patchwork-id: 99502 O-Subject: [RHEL-8.4.0 qemu-kvm PATCH v2 05/12] s390/sclp: check sccb len before filling in data Bugzilla: 1798506 RH-Acked-by: Jens Freimann RH-Acked-by: Cornelia Huck RH-Acked-by: David Hildenbrand From: Collin Walling The SCCB must be checked for a sufficient length before it is filled with any data. If the length is insufficient, then the SCLP command is suppressed and the proper response code is set in the SCCB header. While we're at it, let's cleanup the length check by placing the calculation inside a macro. Fixes: 832be0d8a3bb ("s390x: sclp: Report insufficient SCCB length") Signed-off-by: Collin Walling Reviewed-by: Janosch Frank Reviewed-by: David Hildenbrand Reviewed-by: Cornelia Huck Reviewed-by: Thomas Huth Reviewed-by: Claudio Imbrenda Message-Id: <20200915194416.107460-5-walling@linux.ibm.com> Signed-off-by: Cornelia Huck (cherry picked from commit 0260b97824495ebfacfa8bbae0be10b0ef986bf6) Signed-off-by: Thomas Huth Signed-off-by: Danilo C. L. de Paula --- hw/s390x/sclp.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c index cf1292beb22..2b4c6c5cfad 100644 --- a/hw/s390x/sclp.c +++ b/hw/s390x/sclp.c @@ -78,6 +78,8 @@ static void prepare_cpu_entries(MachineState *ms, CPUEntry *entry, int *count) } } +#define SCCB_REQ_LEN(s, max_cpus) (sizeof(s) + max_cpus * sizeof(CPUEntry)) + /* Provide information about the configuration, CPUs and storage */ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb) { @@ -86,6 +88,12 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb) int cpu_count; int rnsize, rnmax; IplParameterBlock *ipib = s390_ipl_get_iplb(); + int required_len = SCCB_REQ_LEN(ReadInfo, machine->possible_cpus->len); + + if (be16_to_cpu(sccb->h.length) < required_len) { + sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH); + return; + } /* CPU information */ prepare_cpu_entries(machine, read_info->entries, &cpu_count); @@ -95,12 +103,6 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb) read_info->ibc_val = cpu_to_be32(s390_get_ibc_val()); - if (be16_to_cpu(sccb->h.length) < - (sizeof(ReadInfo) + cpu_count * sizeof(CPUEntry))) { - sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH); - return; - } - /* Configuration Characteristic (Extension) */ s390_get_feat_block(S390_FEAT_TYPE_SCLP_CONF_CHAR, read_info->conf_char); @@ -146,18 +148,18 @@ static void sclp_read_cpu_info(SCLPDevice *sclp, SCCB *sccb) MachineState *machine = MACHINE(qdev_get_machine()); ReadCpuInfo *cpu_info = (ReadCpuInfo *) sccb; int cpu_count; + int required_len = SCCB_REQ_LEN(ReadCpuInfo, machine->possible_cpus->len); + + if (be16_to_cpu(sccb->h.length) < required_len) { + sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH); + return; + } prepare_cpu_entries(machine, cpu_info->entries, &cpu_count); cpu_info->nr_configured = cpu_to_be16(cpu_count); cpu_info->offset_configured = cpu_to_be16(offsetof(ReadCpuInfo, entries)); cpu_info->nr_standby = cpu_to_be16(0); - if (be16_to_cpu(sccb->h.length) < - (sizeof(ReadCpuInfo) + cpu_count * sizeof(CPUEntry))) { - sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH); - return; - } - /* The standby offset is 16-byte for each CPU */ cpu_info->offset_standby = cpu_to_be16(cpu_info->offset_configured + cpu_info->nr_configured*sizeof(CPUEntry)); -- 2.27.0