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