summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2008-06-24 14:03:14 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-07-06 11:33:08 -0500
commitbdb2b8cab4392ce41ddfbd6773a3da3334daf836 (patch)
tree1d7804a10bc8af816af41a2e7d1ce73f9e0e72d3 /drivers
parentb7279469d66b55119784b8b9529c99c1955fe747 (diff)
downloadlinux-3.10-bdb2b8cab4392ce41ddfbd6773a3da3334daf836.tar.gz
linux-3.10-bdb2b8cab4392ce41ddfbd6773a3da3334daf836.tar.bz2
linux-3.10-bdb2b8cab4392ce41ddfbd6773a3da3334daf836.zip
[SCSI] erase invalid data returned by device
This patch (as1108) fixes a problem that can occur with certain USB mass-storage devices: They return invalid data together with a residue indicating that the data should be ignored. Rather than leave the invalid data in a transfer buffer, where it can get misinterpreted, the patch clears the invalid portion of the buffer. This solves a problem (wrong write-protect setting detected) reported by Maciej Rutecki and Peter Teoh. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Tested-by: Peter Teoh <htmldeveloper@gmail.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/scsi_lib.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index a82d2fe80fb..cbf55d59a54 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -207,6 +207,15 @@ int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
*/
blk_execute_rq(req->q, NULL, req, 1);
+ /*
+ * Some devices (USB mass-storage in particular) may transfer
+ * garbage data together with a residue indicating that the data
+ * is invalid. Prevent the garbage from being misinterpreted
+ * and prevent security leaks by zeroing out the excess data.
+ */
+ if (unlikely(req->data_len > 0 && req->data_len <= bufflen))
+ memset(buffer + (bufflen - req->data_len), 0, req->data_len);
+
ret = req->errors;
out:
blk_put_request(req);