The various indicators pointers allow them to be overwritten,
but leak any existing structs that might be there. The adapter
indicators path checks that it isn't converting from regular
to thin interrupts, but a check in the reverse direction isn't
performed.

Rather than unwinding the existing allocations to allow additional
assignments, just reject these duplicates.

Signed-off-by: Eric Farman <[email protected]>
---
 hw/s390x/virtio-ccw.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index eb6378ea4c..d700db405b 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -565,6 +565,11 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
             ret = -EINVAL;
             break;
         }
+        if (dev->indicators) {
+            /* Do not set without un-setting first */
+            ret = -ENOSYS;
+            break;
+        }
         if (sch->thinint_active) {
             /* Trigger a command reject. */
             ret = -ENOSYS;
@@ -599,6 +604,11 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
             ret = -EINVAL;
             break;
         }
+        if (dev->indicators2) {
+            /* Do not set without un-setting first */
+            ret = -ENOSYS;
+            break;
+        }
         if (!ccw.cda) {
             ret = -EFAULT;
         } else {
@@ -657,7 +667,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
         }
         if (!ccw.cda) {
             ret = -EFAULT;
-        } else if (dev->indicators && !sch->thinint_active) {
+        } else if (dev->indicators || dev->summary_indicator) {
             /* Trigger a command reject. */
             ret = -ENOSYS;
         } else {
-- 
2.53.0


Reply via email to