summaryrefslogtreecommitdiffstats
path: root/hw/s390x
diff options
context:
space:
mode:
authorClaudio Imbrenda2019-09-27 15:33:23 +0200
committerChristian Borntraeger2019-09-30 13:51:50 +0200
commit832be0d8a3bb7b54d64730f7a37d674f30ca0427 (patch)
tree7dd690912652ffe110dc9323d668cada5be38939 /hw/s390x
parents390x: sclp: fix error handling for oversize control blocks (diff)
downloadqemu-832be0d8a3bb7b54d64730f7a37d674f30ca0427.tar.gz
qemu-832be0d8a3bb7b54d64730f7a37d674f30ca0427.tar.xz
qemu-832be0d8a3bb7b54d64730f7a37d674f30ca0427.zip
s390x: sclp: Report insufficient SCCB length
Return the correct error code when the SCCB buffer is too small to contain all of the output, for the Read SCP Information and Read CPU Information commands. Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com> Reviewed-by: Jason J. Herne <jjherne@linux.ibm.com> Message-Id: <1569591203-15258-5-git-send-email-imbrenda@linux.ibm.com> Reviewed-by: David Hildenbrand <david@redhat.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Diffstat (limited to 'hw/s390x')
-rw-r--r--hw/s390x/sclp.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index abb6e5011f..f57ce7b739 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -68,6 +68,12 @@ 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);
@@ -118,6 +124,12 @@ static void sclp_read_cpu_info(SCLPDevice *sclp, SCCB *sccb)
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));