summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorCornelia Huck <cornelia.huck@de.ibm.com>2016-08-15 11:10:28 +0200
committerCornelia Huck <cornelia.huck@de.ibm.com>2016-09-05 15:15:16 +0200
commit882b3b97697affb36ca3d174f42f846232008979 (patch)
treeea3362a34f6f6d6390ec5c13dca304a7ecf16a3b /hw
parent5759db1936b52a7f5d0cd4e1377ed74054d555f9 (diff)
downloadqemu-882b3b97697affb36ca3d174f42f846232008979.tar.gz
qemu-882b3b97697affb36ca3d174f42f846232008979.tar.bz2
qemu-882b3b97697affb36ca3d174f42f846232008979.zip
s390x/css: handle cssid 255 correctly
The cssid 255 is reserved but still valid from an architectural point of view. However, feeding a bogus schid of 0xffffffff into the virtio hypercall will lead to a crash: Stack trace of thread 138363: #0 0x00000000100d168c css_find_subch (qemu-system-s390x) #1 0x00000000100d3290 virtio_ccw_hcall_notify #2 0x00000000100cbf60 s390_virtio_hypercall #3 0x000000001010ff7a handle_hypercall #4 0x0000000010079ed4 kvm_cpu_exec (qemu-system-s390x) #5 0x00000000100609b4 qemu_kvm_cpu_thread_fn #6 0x000003ff8b887bb4 start_thread (libpthread.so.0) #7 0x000003ff8b78df0a thread_start (libc.so.6) This is because the css array was only allocated for 0..254 instead of 0..255. Let's fix this by bumping MAX_CSSID to 255 and fencing off the reserved cssid of 255 during css image allocation. Reported-by: Christian Borntraeger <borntraeger@de.ibm.com> Tested-by: Christian Borntraeger <borntraeger@de.ibm.com> Cc: qemu-stable@nongnu.org Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/s390x/css.c8
1 files changed, 3 insertions, 5 deletions
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index bb8e4be339..b0e81efc27 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -141,7 +141,8 @@ out_err:
int css_create_css_image(uint8_t cssid, bool default_image)
{
trace_css_new_image(cssid, default_image ? "(default)" : "");
- if (cssid > MAX_CSSID) {
+ /* 255 is reserved */
+ if (cssid == 255) {
return -EINVAL;
}
if (channel_subsys.css[cssid]) {
@@ -1267,7 +1268,7 @@ bool css_schid_final(int m, uint8_t cssid, uint8_t ssid, uint16_t schid)
uint8_t real_cssid;
real_cssid = (!m && (cssid == 0)) ? channel_subsys.default_cssid : cssid;
- if (real_cssid > MAX_CSSID || ssid > MAX_SSID ||
+ if (ssid > MAX_SSID ||
!channel_subsys.css[real_cssid] ||
!channel_subsys.css[real_cssid]->sch_set[ssid]) {
return true;
@@ -1282,9 +1283,6 @@ static int css_add_virtual_chpid(uint8_t cssid, uint8_t chpid, uint8_t type)
CssImage *css;
trace_css_chpid_add(cssid, chpid, type);
- if (cssid > MAX_CSSID) {
- return -EINVAL;
- }
css = channel_subsys.css[cssid];
if (!css) {
return -EINVAL;