From 3effd324db181e625665be33b5c6529dca723cc5 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Wed, 15 Nov 2017 09:09:15 -0500 Subject: [PATCH] librbd: prevent overflow of discard API result code Prevent discard/writesame lengths larger than 2GB. Fixes: http://tracker.ceph.com/issues/21966 Signed-off-by: Jason Dillaman --- PendingReleaseNotes | 7 +++++++ src/librbd/librbd.cc | 14 +++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/PendingReleaseNotes b/PendingReleaseNotes index f88857dad600..22ac3955c996 100644 --- a/PendingReleaseNotes +++ b/PendingReleaseNotes @@ -50,3 +50,10 @@ pg-upmap-items` command), we recommend that all mappings be removed (via the `ceph osd rm-pg-upmap-items` command) before upgrading to this point release. + +13.0.0 +------ + +* The RBD C API's rbd_discard method now enforces a maximum length of + 2GB to match the C++ API's Image::discard method. This restriction + prevents overflow of the result code. diff --git a/src/librbd/librbd.cc b/src/librbd/librbd.cc index 86b690815da1..ddcf11be4e7f 100644 --- a/src/librbd/librbd.cc +++ b/src/librbd/librbd.cc @@ -1669,7 +1669,8 @@ namespace librbd { tracepoint(librbd, writesame_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, ofs, len, bl.length() <= 0 ? NULL : bl.c_str(), bl.length(), op_flags); - if (bl.length() <= 0 || len % bl.length()) { + if (bl.length() <= 0 || len % bl.length() || + len > std::numeric_limits::max()) { tracepoint(librbd, writesame_exit, -EINVAL); return -EINVAL; } @@ -3724,7 +3725,13 @@ extern "C" ssize_t rbd_write2(rbd_image_t image, uint64_t ofs, size_t len, extern "C" int rbd_discard(rbd_image_t image, uint64_t ofs, uint64_t len) { librbd::ImageCtx *ictx = (librbd::ImageCtx *)image; - tracepoint(librbd, discard_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, ofs, len); + tracepoint(librbd, discard_enter, ictx, ictx->name.c_str(), + ictx->snap_name.c_str(), ictx->read_only, ofs, len); + if (len > std::numeric_limits::max()) { + tracepoint(librbd, discard_exit, -EINVAL); + return -EINVAL; + } + int r = ictx->io_work_queue->discard(ofs, len, ictx->skip_partial_discard); tracepoint(librbd, discard_exit, r); return r; @@ -3737,7 +3744,8 @@ extern "C" ssize_t rbd_writesame(rbd_image_t image, uint64_t ofs, size_t len, tracepoint(librbd, writesame_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, ofs, len, data_len == 0 ? NULL : buf, data_len, op_flags); - if (data_len == 0 || len % data_len) { + if (data_len == 0 || len % data_len || + len > std::numeric_limits::max()) { tracepoint(librbd, writesame_exit, -EINVAL); return -EINVAL; } -- 2.47.3