From: Jason Dillaman Date: Wed, 15 Nov 2017 14:09:15 +0000 (-0500) Subject: librbd: prevent overflow of discard API result code X-Git-Tag: v13.0.1~203^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=3effd324db181e625665be33b5c6529dca723cc5;p=ceph.git 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 --- 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; }