diff options
author | Bijan Mottahedeh <bijan.mottahedeh@oracle.com> | 2018-12-03 19:48:23 -0500 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2019-01-14 20:28:08 -0500 |
commit | 8e5dadfe76cf2862ebf3e4f22adef29982df7766 (patch) | |
tree | d5be0bca9014695f3b8abaa89e26d7256605333f | |
parent | 74ad7419489ddade8044e3c9ab064ad656520306 (diff) |
vhost/scsi: Use copy_to_iter() to send control queue response
Uses copy_to_iter() instead of __copy_to_user() in order to ensure we
support arbitrary layouts and an input buffer split across iov entries.
Fixes: 0d02dbd68c47b ("vhost/scsi: Respond to control queue operations")
Signed-off-by: Bijan Mottahedeh <bijan.mottahedeh@oracle.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
-rw-r--r-- | drivers/vhost/scsi.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index 8e10ab436d1f..344684f3e2e4 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c | |||
@@ -1127,16 +1127,18 @@ vhost_scsi_send_tmf_reject(struct vhost_scsi *vs, | |||
1127 | struct vhost_virtqueue *vq, | 1127 | struct vhost_virtqueue *vq, |
1128 | struct vhost_scsi_ctx *vc) | 1128 | struct vhost_scsi_ctx *vc) |
1129 | { | 1129 | { |
1130 | struct virtio_scsi_ctrl_tmf_resp __user *resp; | ||
1131 | struct virtio_scsi_ctrl_tmf_resp rsp; | 1130 | struct virtio_scsi_ctrl_tmf_resp rsp; |
1131 | struct iov_iter iov_iter; | ||
1132 | int ret; | 1132 | int ret; |
1133 | 1133 | ||
1134 | pr_debug("%s\n", __func__); | 1134 | pr_debug("%s\n", __func__); |
1135 | memset(&rsp, 0, sizeof(rsp)); | 1135 | memset(&rsp, 0, sizeof(rsp)); |
1136 | rsp.response = VIRTIO_SCSI_S_FUNCTION_REJECTED; | 1136 | rsp.response = VIRTIO_SCSI_S_FUNCTION_REJECTED; |
1137 | resp = vq->iov[vc->out].iov_base; | 1137 | |
1138 | ret = __copy_to_user(resp, &rsp, sizeof(rsp)); | 1138 | iov_iter_init(&iov_iter, READ, &vq->iov[vc->out], vc->in, sizeof(rsp)); |
1139 | if (!ret) | 1139 | |
1140 | ret = copy_to_iter(&rsp, sizeof(rsp), &iov_iter); | ||
1141 | if (likely(ret == sizeof(rsp))) | ||
1140 | vhost_add_used_and_signal(&vs->dev, vq, vc->head, 0); | 1142 | vhost_add_used_and_signal(&vs->dev, vq, vc->head, 0); |
1141 | else | 1143 | else |
1142 | pr_err("Faulted on virtio_scsi_ctrl_tmf_resp\n"); | 1144 | pr_err("Faulted on virtio_scsi_ctrl_tmf_resp\n"); |
@@ -1147,16 +1149,18 @@ vhost_scsi_send_an_resp(struct vhost_scsi *vs, | |||
1147 | struct vhost_virtqueue *vq, | 1149 | struct vhost_virtqueue *vq, |
1148 | struct vhost_scsi_ctx *vc) | 1150 | struct vhost_scsi_ctx *vc) |
1149 | { | 1151 | { |
1150 | struct virtio_scsi_ctrl_an_resp __user *resp; | ||
1151 | struct virtio_scsi_ctrl_an_resp rsp; | 1152 | struct virtio_scsi_ctrl_an_resp rsp; |
1153 | struct iov_iter iov_iter; | ||
1152 | int ret; | 1154 | int ret; |
1153 | 1155 | ||
1154 | pr_debug("%s\n", __func__); | 1156 | pr_debug("%s\n", __func__); |
1155 | memset(&rsp, 0, sizeof(rsp)); /* event_actual = 0 */ | 1157 | memset(&rsp, 0, sizeof(rsp)); /* event_actual = 0 */ |
1156 | rsp.response = VIRTIO_SCSI_S_OK; | 1158 | rsp.response = VIRTIO_SCSI_S_OK; |
1157 | resp = vq->iov[vc->out].iov_base; | 1159 | |
1158 | ret = __copy_to_user(resp, &rsp, sizeof(rsp)); | 1160 | iov_iter_init(&iov_iter, READ, &vq->iov[vc->out], vc->in, sizeof(rsp)); |
1159 | if (!ret) | 1161 | |
1162 | ret = copy_to_iter(&rsp, sizeof(rsp), &iov_iter); | ||
1163 | if (likely(ret == sizeof(rsp))) | ||
1160 | vhost_add_used_and_signal(&vs->dev, vq, vc->head, 0); | 1164 | vhost_add_used_and_signal(&vs->dev, vq, vc->head, 0); |
1161 | else | 1165 | else |
1162 | pr_err("Faulted on virtio_scsi_ctrl_an_resp\n"); | 1166 | pr_err("Faulted on virtio_scsi_ctrl_an_resp\n"); |