summaryrefslogtreecommitdiff
path: root/drivers/block/rbd.c
diff options
context:
space:
mode:
authorIlya Dryomov <idryomov@gmail.com>2016-05-16 14:18:57 +0300
committerIlya Dryomov <idryomov@gmail.com>2016-05-26 01:36:20 +0300
commit663ae2cc04773608e1e741f693e41200fd4faf14 (patch)
treea466793ccab81b82ae6bc36440db64bb0e6c512a /drivers/block/rbd.c
parent2dcd0af568b0cf583645c8a317dd12e344b1c72a (diff)
downloadlinux-663ae2cc04773608e1e741f693e41200fd4faf14.tar.xz
rbd: get/put img_request in rbd_img_request_submit()
By the time we get to checking for_each_obj_request_safe(img_request) terminating condition, all obj_requests may be complete and img_request ref, that rbd_img_request_submit() takes away from its caller, may be put. Moving the next_obj_request cursor is then a use-after-free on img_request. It's totally benign, as the value that's read is never used, but I think it's still worth fixing. Cc: Alex Elder <elder@linaro.org> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'drivers/block/rbd.c')
-rw-r--r--drivers/block/rbd.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 0ede6d7e2568..c3089f32a392 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -2973,17 +2973,20 @@ static int rbd_img_request_submit(struct rbd_img_request *img_request)
{
struct rbd_obj_request *obj_request;
struct rbd_obj_request *next_obj_request;
+ int ret = 0;
dout("%s: img %p\n", __func__, img_request);
- for_each_obj_request_safe(img_request, obj_request, next_obj_request) {
- int ret;
+ rbd_img_request_get(img_request);
+ for_each_obj_request_safe(img_request, obj_request, next_obj_request) {
ret = rbd_img_obj_request_submit(obj_request);
if (ret)
- return ret;
+ goto out_put_ireq;
}
- return 0;
+out_put_ireq:
+ rbd_img_request_put(img_request);
+ return ret;
}
static void rbd_img_parent_read_callback(struct rbd_img_request *img_request)