aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@HansenPartnership.com>2008-01-22 14:43:48 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-01-23 12:27:54 -0500
commitd0ad3bc97c06fba5d37b4ca03c03b7eeeda39c47 (patch)
tree5aaecdc97e807dc9be911243604c9b9e0f22bde6
parent465ff3185e0cb76d46137335a4d21d0d9d3ac8a2 (diff)
[SCSI] libata: fix corruption induced by relaxed DMA alignment in SCSI
Hugh Dickens noticed that SMART commands issued from user space can end up corupting memory. The problem occurs if the buffer used to read data spans two pages. The reason is that the PIO sector routines in libata are expecting physically contiguous pages when they do sector operations, so the left overs on the second page go into the next physically adjacent page rather than the next page in the sg mapping. Fix this by enforcing strict 512 byte alignment on all buffers from userspace. Acked-by: Hugh Dickins <hugh@veritas.com> Acked-by: Jeff Garzik <jeff@garzik.org> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r--drivers/ata/libata-scsi.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 4bb268b9aaeb..bc5cf6b8a4b8 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -824,9 +824,6 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev)
824 * requests. 824 * requests.
825 */ 825 */
826 sdev->max_device_blocked = 1; 826 sdev->max_device_blocked = 1;
827
828 /* set the min alignment */
829 blk_queue_update_dma_alignment(sdev->request_queue, ATA_DMA_PAD_SZ - 1);
830} 827}
831 828
832static void ata_scsi_dev_config(struct scsi_device *sdev, 829static void ata_scsi_dev_config(struct scsi_device *sdev,
@@ -842,7 +839,14 @@ static void ata_scsi_dev_config(struct scsi_device *sdev,
842 if (dev->class == ATA_DEV_ATAPI) { 839 if (dev->class == ATA_DEV_ATAPI) {
843 struct request_queue *q = sdev->request_queue; 840 struct request_queue *q = sdev->request_queue;
844 blk_queue_max_hw_segments(q, q->max_hw_segments - 1); 841 blk_queue_max_hw_segments(q, q->max_hw_segments - 1);
845 } 842
843 /* set the min alignment */
844 blk_queue_update_dma_alignment(sdev->request_queue,
845 ATA_DMA_PAD_SZ - 1);
846 } else
847 /* ATA devices must be sector aligned */
848 blk_queue_update_dma_alignment(sdev->request_queue,
849 ATA_SECT_SIZE - 1);
846 850
847 if (dev->flags & ATA_DFLAG_AN) 851 if (dev->flags & ATA_DFLAG_AN)
848 set_bit(SDEV_EVT_MEDIA_CHANGE, sdev->supported_events); 852 set_bit(SDEV_EVT_MEDIA_CHANGE, sdev->supported_events);