One s390x fix:
- correctly handle the case where the guest ccw payload points to invalid memory areas -----BEGIN PGP SIGNATURE----- iQJGBAABCAAwFiEEw9DWbcNiT/aowBjO3s9rk8bwL68FAmBwaCESHGNvaHVja0By ZWRoYXQuY29tAAoJEN7Pa5PG8C+vcJsQAKJO6tlZx/dEr00FeuXN0J1o25pw1PtQ N2wgWn7hQ5KEvfppNxiiARlZY13ki94hoPNKGW+XISEoyZ9Zx1HsbhCYE80oa1SZ 4paCbGj5sauTNjjMhuwrl3FlchszoC9oUg9Ev7GeGsFbtHP+gvR7X9giE3xfHjO4 2AlghUVxo2N5IL3yEgmdTBWEbpSlqMm18yDn7cZsgYRr+s/cUNlTvhTcwR7PmYsK KnBFeM1PbOXl+8MqdP5xZevXpzhlUpIR+Dwfo1TcNKscj6hHE1GHJhAUGMDvDG/K 4dair5/l4HxxaF2G4HvVU5dr4pJwZ1QXEvfpIykN2vGW6dwwP15xIknqgMCtEcU8 MD7lpvGpq1x2ScEs2AIlK5ElD2vZiK3zZSYNah634f034RSIz6T3RFAKEMdVYmKJ 6r3NqYp7ZCsIDHttOSzE9b+5mwU0FYx21XNCC2YNe1cHNqegfxCFefvggN+c7RGv /AZA7URPW11wj760ySeg1pzeTygtlpkwDU39UYTz/lG0vhkMPwOrd0R2njuL3jJy pIXAJZ9Ha6hYLNPFie81VrGLu/dBoLeKwqe70HYDMdPTafPtJRDAlvo8r6oc4FwG 1y8fqrafSpFVZsmO0qWkoCUmObq+aQY1MnuASA8MoRDS+xVT6LXJVv/PWf1m0DjR wxYGQaRrFsnT =6cYM -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/cohuck-gitlab/tags/s390x-20210409' into staging One s390x fix: - correctly handle the case where the guest ccw payload points to invalid memory areas # gpg: Signature made Fri 09 Apr 2021 15:43:45 BST # gpg: using RSA key C3D0D66DC3624FF6A8C018CEDECF6B93C6F02FAF # gpg: issuer "cohuck@redhat.com" # gpg: Good signature from "Cornelia Huck <conny@cornelia-huck.de>" [unknown] # gpg: aka "Cornelia Huck <huckc@linux.vnet.ibm.com>" [full] # gpg: aka "Cornelia Huck <cornelia.huck@de.ibm.com>" [full] # gpg: aka "Cornelia Huck <cohuck@kernel.org>" [unknown] # gpg: aka "Cornelia Huck <cohuck@redhat.com>" [unknown] # Primary key fingerprint: C3D0 D66D C362 4FF6 A8C0 18CE DECF 6B93 C6F0 2FAF * remotes/cohuck-gitlab/tags/s390x-20210409: s390x: css: report errors from ccw_dstream_read/write Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
471387aa14
@ -200,9 +200,13 @@ static int read_payload_3270(EmulatedCcw3270Device *dev)
|
||||
{
|
||||
Terminal3270 *t = TERMINAL_3270(dev);
|
||||
int len;
|
||||
int ret;
|
||||
|
||||
len = MIN(ccw_dstream_avail(get_cds(t)), t->in_len);
|
||||
ccw_dstream_write_buf(get_cds(t), t->inv, len);
|
||||
ret = ccw_dstream_write_buf(get_cds(t), t->inv, len);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
t->in_len -= len;
|
||||
|
||||
return len;
|
||||
@ -260,7 +264,10 @@ static int write_payload_3270(EmulatedCcw3270Device *dev, uint8_t cmd)
|
||||
|
||||
t->outv[out_len++] = cmd;
|
||||
do {
|
||||
ccw_dstream_read_buf(get_cds(t), &t->outv[out_len], len);
|
||||
retval = ccw_dstream_read_buf(get_cds(t), &t->outv[out_len], len);
|
||||
if (retval < 0) {
|
||||
return retval;
|
||||
}
|
||||
count = ccw_dstream_avail(get_cds(t));
|
||||
out_len += len;
|
||||
|
||||
|
@ -31,6 +31,9 @@ static int handle_payload_3270_read(EmulatedCcw3270Device *dev, CCW1 *ccw)
|
||||
}
|
||||
|
||||
len = ck->read_payload_3270(dev);
|
||||
if (len < 0) {
|
||||
return len;
|
||||
}
|
||||
ccw_dev->sch->curr_status.scsw.count = ccw->count - len;
|
||||
|
||||
return 0;
|
||||
@ -50,7 +53,7 @@ static int handle_payload_3270_write(EmulatedCcw3270Device *dev, CCW1 *ccw)
|
||||
len = ck->write_payload_3270(dev, ccw->cmd_code);
|
||||
|
||||
if (len <= 0) {
|
||||
return -EIO;
|
||||
return len ? len : -EIO;
|
||||
}
|
||||
|
||||
ccw_dev->sch->curr_status.scsw.count = ccw->count - len;
|
||||
|
@ -1055,10 +1055,11 @@ static int css_interpret_ccw(SubchDev *sch, hwaddr ccw_addr,
|
||||
}
|
||||
}
|
||||
len = MIN(ccw.count, sizeof(sch->sense_data));
|
||||
ccw_dstream_write_buf(&sch->cds, sch->sense_data, len);
|
||||
ret = ccw_dstream_write_buf(&sch->cds, sch->sense_data, len);
|
||||
sch->curr_status.scsw.count = ccw_dstream_residual_count(&sch->cds);
|
||||
memset(sch->sense_data, 0, sizeof(sch->sense_data));
|
||||
ret = 0;
|
||||
if (!ret) {
|
||||
memset(sch->sense_data, 0, sizeof(sch->sense_data));
|
||||
}
|
||||
break;
|
||||
case CCW_CMD_SENSE_ID:
|
||||
{
|
||||
@ -1083,9 +1084,10 @@ static int css_interpret_ccw(SubchDev *sch, hwaddr ccw_addr,
|
||||
} else {
|
||||
sense_id[0] = 0;
|
||||
}
|
||||
ccw_dstream_write_buf(&sch->cds, sense_id, len);
|
||||
sch->curr_status.scsw.count = ccw_dstream_residual_count(&sch->cds);
|
||||
ret = 0;
|
||||
ret = ccw_dstream_write_buf(&sch->cds, sense_id, len);
|
||||
if (!ret) {
|
||||
sch->curr_status.scsw.count = ccw_dstream_residual_count(&sch->cds);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CCW_CMD_TIC:
|
||||
|
@ -288,14 +288,20 @@ static int virtio_ccw_handle_set_vq(SubchDev *sch, CCW1 ccw, bool check_len,
|
||||
return -EFAULT;
|
||||
}
|
||||
if (is_legacy) {
|
||||
ccw_dstream_read(&sch->cds, linfo);
|
||||
ret = ccw_dstream_read(&sch->cds, linfo);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
linfo.queue = be64_to_cpu(linfo.queue);
|
||||
linfo.align = be32_to_cpu(linfo.align);
|
||||
linfo.index = be16_to_cpu(linfo.index);
|
||||
linfo.num = be16_to_cpu(linfo.num);
|
||||
ret = virtio_ccw_set_vqs(sch, NULL, &linfo);
|
||||
} else {
|
||||
ccw_dstream_read(&sch->cds, info);
|
||||
ret = ccw_dstream_read(&sch->cds, info);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
info.desc = be64_to_cpu(info.desc);
|
||||
info.index = be16_to_cpu(info.index);
|
||||
info.num = be16_to_cpu(info.num);
|
||||
@ -371,7 +377,10 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
|
||||
VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
|
||||
|
||||
ccw_dstream_advance(&sch->cds, sizeof(features.features));
|
||||
ccw_dstream_read(&sch->cds, features.index);
|
||||
ret = ccw_dstream_read(&sch->cds, features.index);
|
||||
if (ret) {
|
||||
break;
|
||||
}
|
||||
if (features.index == 0) {
|
||||
if (dev->revision >= 1) {
|
||||
/* Don't offer legacy features for modern devices. */
|
||||
@ -392,9 +401,10 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
|
||||
}
|
||||
ccw_dstream_rewind(&sch->cds);
|
||||
features.features = cpu_to_le32(features.features);
|
||||
ccw_dstream_write(&sch->cds, features.features);
|
||||
sch->curr_status.scsw.count = ccw.count - sizeof(features);
|
||||
ret = 0;
|
||||
ret = ccw_dstream_write(&sch->cds, features.features);
|
||||
if (!ret) {
|
||||
sch->curr_status.scsw.count = ccw.count - sizeof(features);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CCW_CMD_WRITE_FEAT:
|
||||
@ -411,7 +421,10 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
|
||||
if (!ccw.cda) {
|
||||
ret = -EFAULT;
|
||||
} else {
|
||||
ccw_dstream_read(&sch->cds, features);
|
||||
ret = ccw_dstream_read(&sch->cds, features);
|
||||
if (ret) {
|
||||
break;
|
||||
}
|
||||
features.features = le32_to_cpu(features.features);
|
||||
if (features.index == 0) {
|
||||
virtio_set_features(vdev,
|
||||
@ -454,9 +467,10 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
|
||||
ret = -EFAULT;
|
||||
} else {
|
||||
virtio_bus_get_vdev_config(&dev->bus, vdev->config);
|
||||
ccw_dstream_write_buf(&sch->cds, vdev->config, len);
|
||||
sch->curr_status.scsw.count = ccw.count - len;
|
||||
ret = 0;
|
||||
ret = ccw_dstream_write_buf(&sch->cds, vdev->config, len);
|
||||
if (ret) {
|
||||
sch->curr_status.scsw.count = ccw.count - len;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CCW_CMD_WRITE_CONF:
|
||||
@ -511,7 +525,10 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
|
||||
if (!ccw.cda) {
|
||||
ret = -EFAULT;
|
||||
} else {
|
||||
ccw_dstream_read(&sch->cds, status);
|
||||
ret = ccw_dstream_read(&sch->cds, status);
|
||||
if (ret) {
|
||||
break;
|
||||
}
|
||||
if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) {
|
||||
virtio_ccw_stop_ioeventfd(dev);
|
||||
}
|
||||
@ -554,7 +571,10 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
|
||||
if (!ccw.cda) {
|
||||
ret = -EFAULT;
|
||||
} else {
|
||||
ccw_dstream_read(&sch->cds, indicators);
|
||||
ret = ccw_dstream_read(&sch->cds, indicators);
|
||||
if (ret) {
|
||||
break;
|
||||
}
|
||||
indicators = be64_to_cpu(indicators);
|
||||
dev->indicators = get_indicator(indicators, sizeof(uint64_t));
|
||||
sch->curr_status.scsw.count = ccw.count - sizeof(indicators);
|
||||
@ -575,7 +595,10 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
|
||||
if (!ccw.cda) {
|
||||
ret = -EFAULT;
|
||||
} else {
|
||||
ccw_dstream_read(&sch->cds, indicators);
|
||||
ret = ccw_dstream_read(&sch->cds, indicators);
|
||||
if (ret) {
|
||||
break;
|
||||
}
|
||||
indicators = be64_to_cpu(indicators);
|
||||
dev->indicators2 = get_indicator(indicators, sizeof(uint64_t));
|
||||
sch->curr_status.scsw.count = ccw.count - sizeof(indicators);
|
||||
@ -596,7 +619,10 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
|
||||
if (!ccw.cda) {
|
||||
ret = -EFAULT;
|
||||
} else {
|
||||
ccw_dstream_read(&sch->cds, vq_config.index);
|
||||
ret = ccw_dstream_read(&sch->cds, vq_config.index);
|
||||
if (ret) {
|
||||
break;
|
||||
}
|
||||
vq_config.index = be16_to_cpu(vq_config.index);
|
||||
if (vq_config.index >= VIRTIO_QUEUE_MAX) {
|
||||
ret = -EINVAL;
|
||||
@ -605,9 +631,10 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
|
||||
vq_config.num_max = virtio_queue_get_num(vdev,
|
||||
vq_config.index);
|
||||
vq_config.num_max = cpu_to_be16(vq_config.num_max);
|
||||
ccw_dstream_write(&sch->cds, vq_config.num_max);
|
||||
sch->curr_status.scsw.count = ccw.count - sizeof(vq_config);
|
||||
ret = 0;
|
||||
ret = ccw_dstream_write(&sch->cds, vq_config.num_max);
|
||||
if (!ret) {
|
||||
sch->curr_status.scsw.count = ccw.count - sizeof(vq_config);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CCW_CMD_SET_IND_ADAPTER:
|
||||
@ -664,7 +691,10 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
}
|
||||
ccw_dstream_read_buf(&sch->cds, &revinfo, 4);
|
||||
ret = ccw_dstream_read_buf(&sch->cds, &revinfo, 4);
|
||||
if (ret < 0) {
|
||||
break;
|
||||
}
|
||||
revinfo.revision = be16_to_cpu(revinfo.revision);
|
||||
revinfo.length = be16_to_cpu(revinfo.length);
|
||||
if (ccw.count < len + revinfo.length ||
|
||||
|
Loading…
Reference in New Issue
Block a user