]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: prevent overflow of discard API result code 19058/head
authorJason Dillaman <dillaman@redhat.com>
Wed, 15 Nov 2017 14:09:15 +0000 (09:09 -0500)
committerShinobu Kinjo <shinobu@redhat.com>
Mon, 20 Nov 2017 22:16:01 +0000 (07:16 +0900)
Prevent discard/writesame lengths larger than 2GB.

Fixes: http://tracker.ceph.com/issues/21966
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
(cherry picked from commit 3effd324db181e625665be33b5c6529dca723cc5)

Conflicts:
PendingReleaseNotes
src/librbd/librbd.cc: i chosed to pick code from 3effd32 in order to prevent discard/writesame against lengths larger than 2GB. `len` used in picked code was already in luminous. so it's safe to pick.

PendingReleaseNotes
src/librbd/librbd.cc

index b46d1dce10090862177cb1e654105b437d6e3cab..34d2cab0cec1b47bc83119a4a0c446e6a1f782c0 100644 (file)
   make the number of PGs per OSD exceed the configured
   ``mon_max_pg_per_osd`` limit.  The option can be adjusted if it
   is really necessary to create a pool with more PGs.
+
+* There was a bug in the PG mapping behavior of the new *upmap*
+  feature. If you made use of this feature (e.g., via the `ceph osd
+  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.
index 31889b822a6d9e3622a2004c833e3641f5ea98d3..db07e5e2275bb9138de81ac95e71a09aeb722c46 100644 (file)
@@ -1507,7 +1507,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<int>::max()) {
       tracepoint(librbd, writesame_exit, -EINVAL);
       return -EINVAL;
     }
@@ -3450,7 +3451,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<int>::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;
@@ -3463,7 +3470,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<int>::max()) {
     tracepoint(librbd, writesame_exit, -EINVAL);
     return -EINVAL;
   }