[PATCH v2] scsi: address leak in scsi_setup_discard_cmnd error path (was: Re: scsi: unify the error handling of the prep functions)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Jul 05 2010 at  9:45am -0400,
Mike Snitzer <snitzer@xxxxxxxxxx> wrote:

> On Mon, Jul 05 2010 at 12:00am -0400,
> FUJITA Tomonori <fujita.tomonori@xxxxxxxxxxxxx> wrote:
> 
> > This can be applied to the block's for-2.6.36.
> > 
> > =
> > From: FUJITA Tomonori <fujita.tomonori@xxxxxxxxxxxxx>
> > Subject: [PATCH] scsi: unify the error handling of the prep functions
> > 
> > This unifies the error handling of the prep functions (and fix the
> > leak of a page allocated for discard in the case of BLKPREP_KILL or
> > BLK_PREP_DEFER).
> > 
> > The error handling of the prep path is very messy. Some errors are
> > handled in the prep functions while some are in scsi_prep_return().
> > 
> > Let's handle all the errors in scsi_prep_return().
> > 
> > Signed-off-by: FUJITA Tomonori <fujita.tomonori@xxxxxxxxxxxxx>
> 
> This patch addresses the discard page leak too (scsi_prep_error calls
> scsi_unprep_request which calls blk_unprep_request).
> 
> Acked-by: Mike Snitzer <snitzer@xxxxxxxxxx>

Hi,

Your unified error handling forces a BLKPREP_KILL or BLKPREP_DEFER
return from scsi_setup_discard_cmnd to depend on prep cleanup even
though BLKPREP_OK was not returned.  And this works, but it runs counter
to the rules James previously shared: http://lkml.org/lkml/2010/7/1/512

"The rules are pretty clear:  Unprep is only called if the request gets
prepped ... that means you have to return BLKPREP_OK.  Defer or kill
assume there's no teardown to do, so the allocation (if it took place)
must be reversed before returning them."

All this being said, I'm OK with your patch (as my ack implies) but I
can see that it will take the request prep error handling in a direction
James may prefer to avoid.

Here is a minimalist patch that 1) removes the discard request's page
leak 2) preserves the prep cleanup rules covered above.  Fixing the leak
is a priority, introducing additional error path code sharing/cleanup is
secondary and can come later.

=
From: Mike Snitzer <snitzer@xxxxxxxxxx>
Subject: [PATCH v2] scsi: address leak in scsi_setup_discard_cmnd error path

Currently, a discard request's page will not get cleaned up in the
scsi_setup_discard_cmnd error path.  A scsi_setup_discard_cmnd return
other than BLKPREP_OK will not cause a discard request to get completely
cleaned up (scsi_prep_return will not set REQ_DONTPREP unless BLKPREP_OK
was returned).

This fix eliminates the leak while preserving the rule that:
Unprep is only called if the request gets prepped (meaning a return
BLKPREP_OK).  Defer or kill assume there's no teardown to do, so any
allocation must be reversed before returning them.

Signed-off-by: Mike Snitzer <snitzer@xxxxxxxxxx>
---
 drivers/scsi/sd.c |    8 +++++++-
 1 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 0994ab6..08e08bd 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -468,6 +468,10 @@ static int scsi_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq)
 	blk_add_request_payload(rq, page, len);
 	ret = scsi_setup_blk_pc_cmnd(sdp, rq);
 	rq->buffer = page_address(page);
+	if (ret != BLKPREP_OK) {
+		__free_page(page);
+		rq->buffer = NULL;
+	}
 	return ret;
 }
 
@@ -485,8 +489,10 @@ static int scsi_setup_flush_cmnd(struct scsi_device *sdp, struct request *rq)
 
 static void sd_unprep_fn(struct request_queue *q, struct request *rq)
 {
-	if (rq->cmd_flags & REQ_DISCARD)
+	if (rq->cmd_flags & REQ_DISCARD) {
 		__free_page(virt_to_page(rq->buffer));
+		rq->buffer = NULL;
+	}
 }
 
 /**
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux