aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBoaz Harrosh <bharrosh@panasas.com>2009-02-03 01:47:29 -0500
committerJens Axboe <jens.axboe@oracle.com>2009-02-18 04:32:00 -0500
commitc1c201200a359cf3b6e2e36a4236cdca77a3cd8e (patch)
treee214a2773f20b814cb8cc8c5509066cd9ec98a1a
parent5955c7a2cfb6a35429adea5dc480002b15ca8cfc (diff)
bsg: Fix sense buffer bug in SG_IO
When submitting requests via SG_IO, which does a sync io, a bsg_command is not allocated. So an in-Kernel sense_buffer was not set. However when calling blk_execute_rq() with no sense buffer one is provided from the stack. Now bsg at blk_complete_sgv4_hdr_rq() would check if rq->sense_len and a sense was requested by sg_io_v4 the rq->sense was copy_user() back, but by now it is already mangled stack memory. I have fixed that by forcing a sense_buffer when calling bsg_map_hdr(). The bsg_command->sense is provided in the write/read path like before, and on-the-stack buffer is provided when doing SG_IO. I have also fixed a dprintk message to print rq->errors in hex because of the scsi bit-field use of this member. For other block devices it does not matter anyway. Signed-off-by: Boaz Harrosh <bharrosh@panasas.com> Acked-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
-rw-r--r--block/bsg.c17
1 files changed, 10 insertions, 7 deletions
diff --git a/block/bsg.c b/block/bsg.c
index d414bb5607e8..0ce8806dd0c1 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -244,7 +244,8 @@ bsg_validate_sgv4_hdr(struct request_queue *q, struct sg_io_v4 *hdr, int *rw)
244 * map sg_io_v4 to a request. 244 * map sg_io_v4 to a request.
245 */ 245 */
246static struct request * 246static struct request *
247bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm) 247bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm,
248 u8 *sense)
248{ 249{
249 struct request_queue *q = bd->queue; 250 struct request_queue *q = bd->queue;
250 struct request *rq, *next_rq = NULL; 251 struct request *rq, *next_rq = NULL;
@@ -306,6 +307,10 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm)
306 if (ret) 307 if (ret)
307 goto out; 308 goto out;
308 } 309 }
310
311 rq->sense = sense;
312 rq->sense_len = 0;
313
309 return rq; 314 return rq;
310out: 315out:
311 if (rq->cmd != rq->__cmd) 316 if (rq->cmd != rq->__cmd)
@@ -348,9 +353,6 @@ static void bsg_rq_end_io(struct request *rq, int uptodate)
348static void bsg_add_command(struct bsg_device *bd, struct request_queue *q, 353static void bsg_add_command(struct bsg_device *bd, struct request_queue *q,
349 struct bsg_command *bc, struct request *rq) 354 struct bsg_command *bc, struct request *rq)
350{ 355{
351 rq->sense = bc->sense;
352 rq->sense_len = 0;
353
354 /* 356 /*
355 * add bc command to busy queue and submit rq for io 357 * add bc command to busy queue and submit rq for io
356 */ 358 */
@@ -419,7 +421,7 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr,
419{ 421{
420 int ret = 0; 422 int ret = 0;
421 423
422 dprintk("rq %p bio %p %u\n", rq, bio, rq->errors); 424 dprintk("rq %p bio %p 0x%x\n", rq, bio, rq->errors);
423 /* 425 /*
424 * fill in all the output members 426 * fill in all the output members
425 */ 427 */
@@ -635,7 +637,7 @@ static int __bsg_write(struct bsg_device *bd, const char __user *buf,
635 /* 637 /*
636 * get a request, fill in the blanks, and add to request queue 638 * get a request, fill in the blanks, and add to request queue
637 */ 639 */
638 rq = bsg_map_hdr(bd, &bc->hdr, has_write_perm); 640 rq = bsg_map_hdr(bd, &bc->hdr, has_write_perm, bc->sense);
639 if (IS_ERR(rq)) { 641 if (IS_ERR(rq)) {
640 ret = PTR_ERR(rq); 642 ret = PTR_ERR(rq);
641 rq = NULL; 643 rq = NULL;
@@ -922,11 +924,12 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
922 struct request *rq; 924 struct request *rq;
923 struct bio *bio, *bidi_bio = NULL; 925 struct bio *bio, *bidi_bio = NULL;
924 struct sg_io_v4 hdr; 926 struct sg_io_v4 hdr;
927 u8 sense[SCSI_SENSE_BUFFERSIZE];
925 928
926 if (copy_from_user(&hdr, uarg, sizeof(hdr))) 929 if (copy_from_user(&hdr, uarg, sizeof(hdr)))
927 return -EFAULT; 930 return -EFAULT;
928 931
929 rq = bsg_map_hdr(bd, &hdr, file->f_mode & FMODE_WRITE); 932 rq = bsg_map_hdr(bd, &hdr, file->f_mode & FMODE_WRITE, sense);
930 if (IS_ERR(rq)) 933 if (IS_ERR(rq))
931 return PTR_ERR(rq); 934 return PTR_ERR(rq);
932 935