]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: catch manifest decode errors in GetObj/PutObj/CopyObj
authorCasey Bodley <cbodley@redhat.com>
Sun, 19 Feb 2023 22:24:48 +0000 (17:24 -0500)
committerSoumya Koduri <skoduri@redhat.com>
Tue, 23 May 2023 16:50:07 +0000 (22:20 +0530)
if we read an object that doesn't have a manifest attribute,
RGWRados::get_obj_state_impl() adds an empty one and causes decode to
throw an end_of_buffer exception

Fixes: https://tracker.ceph.com/issues/58794
Signed-off-by: Casey Bodley <cbodley@redhat.com>
(cherry picked from commit 77e0b9848cb458427b5dcf86d2c19769ea65e0bc)

src/rgw/rgw_op.cc

index d208e5d2c5ef20739434cc972c4e0d621cc81ca3..d166a22a457be14f9678b28dab604f3964d01d61 100644 (file)
@@ -2278,13 +2278,20 @@ void RGWGetObj::execute(optional_yield y)
   attr_iter = attrs.find(RGW_ATTR_MANIFEST);
   if (attr_iter != attrs.end() && get_type() == RGW_OP_GET_OBJ && get_data) {
     RGWObjManifest m;
-    decode(m, attr_iter->second);
-    if (m.get_tier_type() == "cloud-s3") {
-      /* XXX: Instead send presigned redirect or read-through */
-      op_ret = -ERR_INVALID_OBJECT_STATE;
-      ldpp_dout(this, 0) << "ERROR: Cannot get cloud tiered object. Failing with "
-                      << op_ret << dendl;
-      goto done_err;
+    try {
+      decode(m, attr_iter->second);
+      if (m.get_tier_type() == "cloud-s3") {
+        /* XXX: Instead send presigned redirect or read-through */
+        op_ret = -ERR_INVALID_OBJECT_STATE;
+        ldpp_dout(this, 0) << "ERROR: Cannot get cloud tiered object. Failing with "
+                         << op_ret << dendl;
+        goto done_err;
+      }
+    } catch (const buffer::end_of_buffer&) {
+      // ignore empty manifest; it's not cloud-tiered
+    } catch (const std::exception& e) {
+      ldpp_dout(this, 1) << "WARNING: failed to decode object manifest for "
+          << *s->object << ": " << e.what() << dendl;
     }
   }
 
@@ -4079,12 +4086,19 @@ void RGWPutObj::execute(optional_yield y)
     bufferlist bl;
     if (astate->get_attr(RGW_ATTR_MANIFEST, bl)) {
       RGWObjManifest m;
-      decode(m, bl);
-      if (m.get_tier_type() == "cloud-s3") {
-        op_ret = -ERR_INVALID_OBJECT_STATE;
-        ldpp_dout(this, 0) << "ERROR: Cannot copy cloud tiered object. Failing with "
-                      << op_ret << dendl;
-        return;
+      try{
+        decode(m, bl);
+        if (m.get_tier_type() == "cloud-s3") {
+          op_ret = -ERR_INVALID_OBJECT_STATE;
+          ldpp_dout(this, 0) << "ERROR: Cannot copy cloud tiered object. Failing with "
+                         << op_ret << dendl;
+          return;
+        }
+      } catch (const buffer::end_of_buffer&) {
+        // ignore empty manifest; it's not cloud-tiered
+      } catch (const std::exception& e) {
+        ldpp_dout(this, 1) << "WARNING: failed to decode object manifest for "
+            << *s->object << ": " << e.what() << dendl;
       }
     }
 
@@ -5529,12 +5543,19 @@ void RGWCopyObj::execute(optional_yield y)
     bufferlist bl;
     if (astate->get_attr(RGW_ATTR_MANIFEST, bl)) {
       RGWObjManifest m;
-      decode(m, bl);
-      if (m.get_tier_type() == "cloud-s3") {
-        op_ret = -ERR_INVALID_OBJECT_STATE;
-        ldpp_dout(this, 0) << "ERROR: Cannot copy cloud tiered object. Failing with "
-                      << op_ret << dendl;
-        return;
+      try{
+        decode(m, bl);
+        if (m.get_tier_type() == "cloud-s3") {
+          op_ret = -ERR_INVALID_OBJECT_STATE;
+          ldpp_dout(this, 0) << "ERROR: Cannot copy cloud tiered object. Failing with "
+                         << op_ret << dendl;
+          return;
+        }
+      } catch (const buffer::end_of_buffer&) {
+        // ignore empty manifest; it's not cloud-tiered
+      } catch (const std::exception& e) {
+        ldpp_dout(this, 1) << "WARNING: failed to decode object manifest for "
+            << *s->object << ": " << e.what() << dendl;
       }
     }