rbd: get/put img_request in rbd_img_request_submit()
authorIlya Dryomov <idryomov@gmail.com>
Mon, 16 May 2016 11:18:57 +0000 (13:18 +0200)
committerIlya Dryomov <idryomov@gmail.com>
Wed, 25 May 2016 22:36:20 +0000 (00:36 +0200)
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>
drivers/block/rbd.c

index 0ede6d7e25686cf768e3e74d7611e5e61319d6e7..c3089f32a3929453e810228a4e27166158b7de43 100644 (file)
@@ -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)