Skip to content

Commit 292b389

Browse files
knotgregkh
authored andcommitted
st: fix race in st_scsi_execute_end
commit c68bf8e 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 <petr.uzel@suse.cz> Reported-by: Juergen Groß <juergen.gross@ts.fujitsu.com> Reviewed-by: Jan Kara <jack@suse.cz> Acked-by: Kai Mäkisara <kai.makisara@kolumbus.fi> Signed-off-by: James Bottomley <JBottomley@Parallels.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
1 parent fef5471 commit 292b389

1 file changed

Lines changed: 3 additions & 1 deletion

File tree

drivers/scsi/st.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -462,14 +462,16 @@ static void st_scsi_execute_end(struct request *req, int uptodate)
462462
{
463463
struct st_request *SRpnt = req->end_io_data;
464464
struct scsi_tape *STp = SRpnt->stp;
465+
struct bio *tmp;
465466

466467
STp->buffer->cmdstat.midlevel_result = SRpnt->result = req->errors;
467468
STp->buffer->cmdstat.residual = req->resid_len;
468469

470+
tmp = SRpnt->bio;
469471
if (SRpnt->waiting)
470472
complete(SRpnt->waiting);
471473

472-
blk_rq_unmap_user(SRpnt->bio);
474+
blk_rq_unmap_user(tmp);
473475
__blk_put_request(req->q, req);
474476
}
475477

0 commit comments

Comments
 (0)