aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlya Dryomov <idryomov@gmail.com>2016-09-15 12:05:16 -0400
committerIlya Dryomov <idryomov@gmail.com>2016-10-03 10:13:49 -0400
commit04dc923c9e4c43df7d2d94f290189785d3172326 (patch)
tree1ff276268fd5d3029281e2fa0b31fe2d5d9df053
parent7c84883adf6dc614fc9e01304aa1813a55c43ad2 (diff)
rbd: img_data requests don't own their page array
Move the check into rbd_obj_request_destroy() to avoid use-after-free on errors in rbd_img_request_fill(..., OBJ_REQUEST_PAGES, ...), where pages, owned by the caller, gets freed in rbd_img_request_fill(). Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Alex Elder <elder@linaro.org> Reviewed-by: David Disseldorp <ddiss@suse.de>
-rw-r--r--drivers/block/rbd.c11
1 files changed, 3 insertions, 8 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 02e9a0f0bf7b..e46f4f05fb01 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -2147,7 +2147,9 @@ static void rbd_obj_request_destroy(struct kref *kref)
2147 bio_chain_put(obj_request->bio_list); 2147 bio_chain_put(obj_request->bio_list);
2148 break; 2148 break;
2149 case OBJ_REQUEST_PAGES: 2149 case OBJ_REQUEST_PAGES:
2150 if (obj_request->pages) 2150 /* img_data requests don't own their page array */
2151 if (obj_request->pages &&
2152 !obj_request_img_data_test(obj_request))
2151 ceph_release_page_vector(obj_request->pages, 2153 ceph_release_page_vector(obj_request->pages,
2152 obj_request->page_count); 2154 obj_request->page_count);
2153 break; 2155 break;
@@ -2368,13 +2370,6 @@ static bool rbd_img_obj_end_request(struct rbd_obj_request *obj_request)
2368 xferred = obj_request->length; 2370 xferred = obj_request->length;
2369 } 2371 }
2370 2372
2371 /* Image object requests don't own their page array */
2372
2373 if (obj_request->type == OBJ_REQUEST_PAGES) {
2374 obj_request->pages = NULL;
2375 obj_request->page_count = 0;
2376 }
2377
2378 if (img_request_child_test(img_request)) { 2373 if (img_request_child_test(img_request)) {
2379 rbd_assert(img_request->obj_request != NULL); 2374 rbd_assert(img_request->obj_request != NULL);
2380 more = obj_request->which < img_request->obj_request_count - 1; 2375 more = obj_request->which < img_request->obj_request_count - 1;