Commit 1cd96c242a829d52f7a5ae98f554ca9775429685

Authored by Boaz Harrosh
Committed by Jens Axboe
1 parent f028f3b2f9

block: WARN in __blk_put_request() for potential bio leak

Put a WARN_ON in __blk_put_request if it is about to
leak bio(s). This is a serious bug that can happen in error
handling code paths.

For this to work I have fixed a couple of places in block/ where
request->bio != NULL ownership was not honored. And a small cleanup
at sg_io() while at it.

Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>

Showing 3 changed files with 9 additions and 17 deletions Side-by-side Diff

... ... @@ -1062,6 +1062,9 @@
1062 1062  
1063 1063 elv_completed_request(q, req);
1064 1064  
  1065 + /* this is a bio leak */
  1066 + WARN_ON(req->bio != NULL);
  1067 +
1065 1068 /*
1066 1069 * Request may not have originated from ll_rw_blk. if not,
1067 1070 * it didn't come out of our reserved rq pools
... ... @@ -403,6 +403,8 @@
403 403 if (blk_rq_cpu_valid(next))
404 404 req->cpu = next->cpu;
405 405  
  406 + /* owner-ship of bio passed from next to req */
  407 + next->bio = NULL;
406 408 __blk_put_request(q, next);
407 409 return 1;
408 410 }
... ... @@ -214,21 +214,10 @@
214 214 return 0;
215 215 }
216 216  
217   -/*
218   - * unmap a request that was previously mapped to this sg_io_hdr. handles
219   - * both sg and non-sg sg_io_hdr.
220   - */
221   -static int blk_unmap_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr)
222   -{
223   - blk_rq_unmap_user(rq->bio);
224   - blk_put_request(rq);
225   - return 0;
226   -}
227   -
228 217 static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
229 218 struct bio *bio)
230 219 {
231   - int r, ret = 0;
  220 + int ret = 0;
232 221  
233 222 /*
234 223 * fill in all the output members
235 224  
... ... @@ -253,12 +242,10 @@
253 242 ret = -EFAULT;
254 243 }
255 244  
256   - rq->bio = bio;
257   - r = blk_unmap_sghdr_rq(rq, hdr);
258   - if (ret)
259   - r = ret;
  245 + blk_rq_unmap_user(bio);
  246 + blk_put_request(rq);
260 247  
261   - return r;
  248 + return ret;
262 249 }
263 250  
264 251 static int sg_io(struct request_queue *q, struct gendisk *bd_disk,