From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932384Ab1KWAef (ORCPT ); Tue, 22 Nov 2011 19:34:35 -0500 Received: from cantor2.suse.de ([195.135.220.15]:42263 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932365Ab1KWAe3 (ORCPT ); Tue, 22 Nov 2011 19:34:29 -0500 X-Mailbox-Line: From gregkh@clark.kroah.org Tue Nov 22 16:22:07 2011 Message-Id: <20111123002207.094973608@clark.kroah.org> User-Agent: quilt/0.48-20.1.2 Date: Tue, 22 Nov 2011 16:20:51 -0800 From: Greg KH To: linux-kernel@vger.kernel.org, stable@kernel.org Cc: stable-review@kernel.org, torvalds@linux-foundation.org, akpm@linux-foundation.org, alan@lxorguk.ukuu.org.uk, Petr Uzel , =?UTF-8?q?Kai=20M=C3=A4kisara?= , James Bottomley Subject: [01/25] [SCSI] st: fix race in st_scsi_execute_end In-Reply-To: <20111123002222.GA2376@kroah.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 2.6.32-longterm review patch. If anyone has any objections, please let me know. ------------------ Content-Length: 1355 Lines: 44 From: Petr Uzel commit c68bf8eeaa57c852e74adcf597237be149eef830 upstream. The call to complete() in st_scsi_execute_end() wakes up sleeping thread in write_behind_check(), which frees the st_request, thus invalidating the pointer to the associated bio structure, which is then passed to the blk_rq_unmap_user(). Fix by storing pointer to bio structure into temporary local variable. This bug is present since at least linux-2.6.32. Signed-off-by: Petr Uzel Reported-by: Juergen Groß Reviewed-by: Jan Kara Acked-by: Kai Mäkisara Signed-off-by: James Bottomley Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/st.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -461,14 +461,16 @@ static void st_scsi_execute_end(struct r { struct st_request *SRpnt = req->end_io_data; struct scsi_tape *STp = SRpnt->stp; + struct bio *tmp; STp->buffer->cmdstat.midlevel_result = SRpnt->result = req->errors; STp->buffer->cmdstat.residual = req->resid_len; + tmp = SRpnt->bio; if (SRpnt->waiting) complete(SRpnt->waiting); - blk_rq_unmap_user(SRpnt->bio); + blk_rq_unmap_user(tmp); __blk_put_request(req->q, req); }