From: Tejun Heo Date: Tue, 1 Nov 2005 08:23:49 +0000 (+0900) Subject: [PATCH] blk: fix dangling pointer access in __elv_add_request X-Git-Tag: v3.12-rc1~40274^2~26 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ca23509fbaac0ea662ab0e287bebb72f743f9e1f;p=kernel%2Fkernel-generic.git [PATCH] blk: fix dangling pointer access in __elv_add_request cfq's add_req_fn callback may invoke q->request_fn directly and depending on low-level driver used and timing, a queued request may be finished & deallocated before add_req_fn callback returns. So, __elv_add_request must not access rq after it's passed to add_req_fn callback. This patch moves rq_mergeable test above add_req_fn(). This may result in q->last_merge pointing to REQ_NOMERGE request if add_req_fn callback sets it but as RQ_NOMERGE is checked again when blk layer actually tries to merge requests, this does not cause any problem. Signed-off-by: Tejun Heo Signed-off-by: Linus Torvalds --- diff --git a/drivers/block/elevator.c b/drivers/block/elevator.c index 36f1057..d4a49a3 100644 --- a/drivers/block/elevator.c +++ b/drivers/block/elevator.c @@ -369,9 +369,14 @@ void __elv_add_request(request_queue_t *q, struct request *rq, int where, case ELEVATOR_INSERT_SORT: BUG_ON(!blk_fs_request(rq)); rq->flags |= REQ_SORTED; - q->elevator->ops->elevator_add_req_fn(q, rq); if (q->last_merge == NULL && rq_mergeable(rq)) q->last_merge = rq; + /* + * Some ioscheds (cfq) run q->request_fn directly, so + * rq cannot be accessed after calling + * elevator_add_req_fn. + */ + q->elevator->ops->elevator_add_req_fn(q, rq); break; default: