diff options
author | Christoph Hellwig <hch@lst.de> | 2017-01-09 10:56:23 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-01-19 14:18:03 -0500 |
commit | 199c89fd32b2a127f12d5614a701e275f7f5a10f (patch) | |
tree | 8ffb046ec65de51d5e4282b9322ac422a66985a4 | |
parent | 6c6ae8c43df99284b3260082b43b5858b701bd5e (diff) |
virtio_blk: avoid DMA to stack for the sense buffer
commit a14d749fcebe97ddf6af6db3d1f6ece85c9ddcb9 upstream.
Most users of BLOCK_PC requests allocate the sense buffer on the stack,
so to avoid DMA to the stack copy them to a field in the heap allocated
virtblk_req structure. Without that any attempt at SCSI passthrough I/O,
including the SG_IO ioctl from userspace will crash the kernel. Note that
this includes running tools like hdparm even when the host does not have
SCSI passthrough enabled.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jens Axboe <axboe@fb.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/block/virtio_blk.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 5545a679abd8..3c3b8f601469 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
@@ -56,6 +56,7 @@ struct virtblk_req { | |||
56 | struct virtio_blk_outhdr out_hdr; | 56 | struct virtio_blk_outhdr out_hdr; |
57 | struct virtio_scsi_inhdr in_hdr; | 57 | struct virtio_scsi_inhdr in_hdr; |
58 | u8 status; | 58 | u8 status; |
59 | u8 sense[SCSI_SENSE_BUFFERSIZE]; | ||
59 | struct scatterlist sg[]; | 60 | struct scatterlist sg[]; |
60 | }; | 61 | }; |
61 | 62 | ||
@@ -102,7 +103,8 @@ static int __virtblk_add_req(struct virtqueue *vq, | |||
102 | } | 103 | } |
103 | 104 | ||
104 | if (type == cpu_to_virtio32(vq->vdev, VIRTIO_BLK_T_SCSI_CMD)) { | 105 | if (type == cpu_to_virtio32(vq->vdev, VIRTIO_BLK_T_SCSI_CMD)) { |
105 | sg_init_one(&sense, vbr->req->sense, SCSI_SENSE_BUFFERSIZE); | 106 | memcpy(vbr->sense, vbr->req->sense, SCSI_SENSE_BUFFERSIZE); |
107 | sg_init_one(&sense, vbr->sense, SCSI_SENSE_BUFFERSIZE); | ||
106 | sgs[num_out + num_in++] = &sense; | 108 | sgs[num_out + num_in++] = &sense; |
107 | sg_init_one(&inhdr, &vbr->in_hdr, sizeof(vbr->in_hdr)); | 109 | sg_init_one(&inhdr, &vbr->in_hdr, sizeof(vbr->in_hdr)); |
108 | sgs[num_out + num_in++] = &inhdr; | 110 | sgs[num_out + num_in++] = &inhdr; |