From: Casey Bodley Date: Sun, 19 Feb 2023 22:24:48 +0000 (-0500) Subject: rgw: catch manifest decode errors in GetObj/PutObj/CopyObj X-Git-Tag: v18.1.0~8^2~11 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=9e476ee3ef98fdec447000755a1493b6461b9b04;p=ceph.git rgw: catch manifest decode errors in GetObj/PutObj/CopyObj 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 (cherry picked from commit 77e0b9848cb458427b5dcf86d2c19769ea65e0bc) --- diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index d208e5d2c5ef..d166a22a457b 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -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; } }