Commit e8601dd5 authored by Cornelia Huck's avatar Cornelia Huck Committed by Christian Borntraeger
Browse files

s390x/css: catch ccw sequence errors



We must not allow chains of more than 255 ccws without data transfer.

Reviewed-by: default avatarDavid Hildenbrand <dahi@linux.vnet.ibm.com>
Signed-off-by: default avatarCornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: default avatarJens Freimann <jfrei@linux.vnet.ibm.com>
Signed-off-by: default avatarChristian Borntraeger <borntraeger@de.ibm.com>
parent a327c921
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -294,6 +294,13 @@ static int css_interpret_ccw(SubchDev *sch, hwaddr ccw_addr)

    check_len = !((ccw.flags & CCW_FLAG_SLI) && !(ccw.flags & CCW_FLAG_DC));

    if (!ccw.cda) {
        if (sch->ccw_no_data_cnt == 255) {
            return -EINVAL;
        }
        sch->ccw_no_data_cnt++;
    }

    /* Look at the command. */
    switch (ccw.cmd_code) {
    case CCW_CMD_NOOP:
@@ -396,6 +403,7 @@ static void sch_handle_start_func(SubchDev *sch, ORB *orb)
            return;
        }
        sch->ccw_fmt_1 = !!(orb->ctrl0 & ORB_CTRL0_MASK_FMT);
        sch->ccw_no_data_cnt = 0;
    } else {
        s->ctrl &= ~(SCSW_ACTL_SUSP | SCSW_ACTL_RESUME_PEND);
    }
@@ -1358,6 +1366,7 @@ void subch_device_save(SubchDev *s, QEMUFile *f)
        qemu_put_be16(f, s->id.ciw[i].count);
    }
    qemu_put_byte(f, s->ccw_fmt_1);
    qemu_put_byte(f, s->ccw_no_data_cnt);
    return;
}

@@ -1414,6 +1423,7 @@ int subch_device_load(SubchDev *s, QEMUFile *f)
        s->id.ciw[i].count = qemu_get_be16(f);
    }
    s->ccw_fmt_1 = qemu_get_byte(f);
    s->ccw_no_data_cnt = qemu_get_byte(f);
    return 0;
}

+1 −0
Original line number Diff line number Diff line
@@ -78,6 +78,7 @@ struct SubchDev {
    bool last_cmd_valid;
    bool ccw_fmt_1;
    bool thinint_active;
    uint8_t ccw_no_data_cnt;
    /* transport-provided data: */
    int (*ccw_cb) (SubchDev *, CCW1);
    SenseId id;