Blame SOURCES/kvm-s390-sclp-check-sccb-len-before-filling-in-data.patch

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