From: Casey Bodley Date: Fri, 27 Mar 2026 15:21:41 +0000 (-0400) Subject: rgw: authorization avoids sal::Object::get_instance() X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=273654c431bd3c12b270db18fd7dc93c268ffa91;p=ceph.git rgw: authorization avoids sal::Object::get_instance() s->object->get_instance() may not match the requested versionId. if no versionId was requested, reading from the sal::Object will follow the olh and change get_instance() to return the current version it found rely on the request parameters directly instead of going through sal::Object Signed-off-by: Casey Bodley --- diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index bd3cfe2a4e2d..bcad66e5ace4 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -1292,7 +1292,7 @@ int RGWGetObj::verify_permission(optional_yield y) if (is_replication_request) { // check for s3:GetObject(Version)Acl permission - action = s->object->get_instance().empty() ? rgw::IAM::s3GetObjectAcl : rgw::IAM::s3GetObjectVersionAcl; + action = s->object_key.instance.empty() ? rgw::IAM::s3GetObjectAcl : rgw::IAM::s3GetObjectVersionAcl; if (!verify_object_permission(this, s, action)) { s->err.message = fmt::format("missing {} permission", rgw::IAM::action_bit_string(action)); ldpp_dout(this, 4) << "ERROR: fetching object for replication object=" << s->object << " reason=" << s->err.message << dendl; @@ -1309,7 +1309,7 @@ int RGWGetObj::verify_permission(optional_yield y) } // fallback to s3:GetObject(Version) permission - action = s->object->get_instance().empty() ? rgw::IAM::s3GetObject : rgw::IAM::s3GetObjectVersion; + action = s->object_key.instance.empty() ? rgw::IAM::s3GetObject : rgw::IAM::s3GetObjectVersion; // sse-kms is not supported by s3:GetObject(Version) permission bufferlist bl; @@ -1320,9 +1320,9 @@ int RGWGetObj::verify_permission(optional_yield y) return -EACCES; } } else if (get_torrent) { - action = s->object->get_instance().empty() ? rgw::IAM::s3GetObjectTorrent : rgw::IAM::s3GetObjectVersionTorrent; + action = s->object_key.instance.empty() ? rgw::IAM::s3GetObjectTorrent : rgw::IAM::s3GetObjectVersionTorrent; } else { - action = s->object->get_instance().empty() ? rgw::IAM::s3GetObject : rgw::IAM::s3GetObjectVersion; + action = s->object_key.instance.empty() ? rgw::IAM::s3GetObject : rgw::IAM::s3GetObjectVersion; } if (!verify_object_permission(this, s, action)) { @@ -1362,7 +1362,7 @@ int RGWOp::verify_op_mask() int RGWGetObjTags::verify_permission(optional_yield y) { - auto iam_action = s->object->get_instance().empty()? + auto iam_action = s->object_key.instance.empty() ? rgw::IAM::s3GetObjectTagging: rgw::IAM::s3GetObjectVersionTagging; @@ -1401,7 +1401,7 @@ void RGWGetObjTags::execute(optional_yield y) int RGWPutObjTags::verify_permission(optional_yield y) { - auto iam_action = s->object->get_instance().empty() ? + auto iam_action = s->object_key.instance.empty() ? rgw::IAM::s3PutObjectTagging: rgw::IAM::s3PutObjectVersionTagging; @@ -1462,7 +1462,7 @@ void RGWDeleteObjTags::pre_exec() int RGWDeleteObjTags::verify_permission(optional_yield y) { if (!rgw::sal::Object::empty(s->object.get())) { - auto iam_action = s->object->get_instance().empty() ? + auto iam_action = s->object_key.instance.empty() ? rgw::IAM::s3DeleteObjectTagging: rgw::IAM::s3DeleteObjectVersionTagging; @@ -4370,7 +4370,7 @@ int RGWPutObj::verify_permission(optional_yield y) if (has_s3_existing_tag || has_s3_resource_tag) rgw_iam_add_objtags(this, s, cs_object.get(), has_s3_existing_tag, has_s3_resource_tag); - const auto action = cs_object->get_instance().empty() ? + const auto action = copy_source_version_id.empty() ? rgw::IAM::s3GetObject : rgw::IAM::s3GetObjectVersion; @@ -5693,7 +5693,7 @@ int RGWDeleteObj::verify_permission(optional_yield y) rgw_iam_add_objtags(this, s, has_s3_existing_tag, has_s3_resource_tag); const auto arn = ARN{s->object->get_obj()}; - const auto action = s->object->get_instance().empty() ? + const auto action = s->object_key.instance.empty() ? rgw::IAM::s3DeleteObject : rgw::IAM::s3DeleteObjectVersion; @@ -5707,7 +5707,7 @@ int RGWDeleteObj::verify_permission(optional_yield y) } if (s->bucket->get_info().mfa_enabled() && - !s->object->get_instance().empty() && + !s->object_key.instance.empty() && !s->mfa_verified) { ldpp_dout(this, 5) << "NOTICE: object delete request with a versioned object, mfa auth not provided" << dendl; return -ERR_MFA_REQUIRED; @@ -5794,7 +5794,7 @@ void RGWDeleteObj::execute(optional_yield y) // make reservation for notification if needed const auto versioned_object = s->bucket->versioning_enabled(); const auto event_type = versioned_object && - s->object->get_instance().empty() ? + s->object_key.instance.empty() ? rgw::notify::ObjectRemovedDeleteMarkerCreated : rgw::notify::ObjectRemovedDelete; std::unique_ptr res @@ -6179,7 +6179,7 @@ int RGWCopyObj::verify_permission(optional_yield y) if (has_s3_existing_tag || has_s3_resource_tag) rgw_iam_add_objtags(this, s, s->src_object.get(), has_s3_existing_tag, has_s3_resource_tag); - const auto action = s->src_object->get_instance().empty() ? + const auto action = s->src_object_key.instance.empty() ? rgw::IAM::s3GetObject : rgw::IAM::s3GetObjectVersion; @@ -6463,7 +6463,7 @@ int RGWGetACLs::verify_permission(optional_yield y) bool perm; auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s); if (!rgw::sal::Object::empty(s->object.get())) { - auto iam_action = s->object->get_instance().empty() ? + auto iam_action = s->object_key.instance.empty() ? rgw::IAM::s3GetObjectAcl : rgw::IAM::s3GetObjectVersionAcl; if (has_s3_existing_tag || has_s3_resource_tag) @@ -6507,7 +6507,7 @@ int RGWPutACLs::verify_permission(optional_yield y) rgw_add_grant_to_iam_environment(s->env, s); if (!rgw::sal::Object::empty(s->object.get())) { - auto iam_action = s->object->get_instance().empty() ? rgw::IAM::s3PutObjectAcl : rgw::IAM::s3PutObjectVersionAcl; + auto iam_action = s->object_key.instance.empty() ? rgw::IAM::s3PutObjectAcl : rgw::IAM::s3PutObjectVersionAcl; op_ret = rgw_iam_add_objtags(this, s, true, true); perm = verify_object_permission(this, s, iam_action); } else { @@ -6552,11 +6552,11 @@ int RGWGetObjAttrs::verify_permission(optional_yield y) if (! rgw::sal::Object::empty(s->object.get())) { - auto iam_action1 = s->object->get_instance().empty() ? + auto iam_action1 = s->object_key.instance.empty() ? rgw::IAM::s3GetObject : rgw::IAM::s3GetObjectVersion; - auto iam_action2 = s->object->get_instance().empty() ? + auto iam_action2 = s->object_key.instance.empty() ? rgw::IAM::s3GetObjectAttributes : rgw::IAM::s3GetObjectVersionAttributes; @@ -7973,7 +7973,7 @@ void RGWDeleteMultiObj::handle_individual_object(const RGWMultiDelObject& object // make reservation for notification if needed const auto versioned_object = s->bucket->versioning_enabled(); - const auto event_type = versioned_object && obj->get_instance().empty() ? + const auto event_type = versioned_object && o.instance.empty() ? rgw::notify::ObjectRemovedDeleteMarkerCreated : rgw::notify::ObjectRemovedDelete; std::unique_ptr res @@ -8848,7 +8848,7 @@ int RGWGetAttrs::verify_permission(optional_yield y) if (has_s3_existing_tag || has_s3_resource_tag) rgw_iam_add_objtags(this, s, has_s3_existing_tag, has_s3_resource_tag); - auto iam_action = s->object->get_instance().empty() ? + auto iam_action = s->object_key.instance.empty() ? rgw::IAM::s3GetObject : rgw::IAM::s3GetObjectVersion; diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 3fb322fa61e7..1dad169116e0 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -435,7 +435,7 @@ int RGWGetObj_ObjStore_S3::send_response_data(bufferlist& bl, off_t bl_ofs, dump_header(s, "Rgwx-Perm-Checked", "true"); // check for GetObject(Version)Tagging permission to include tags in response - auto action = s->object->get_instance().empty() ? rgw::IAM::s3GetObjectTagging : rgw::IAM::s3GetObjectVersionTagging; + auto action = s->object_key.instance.empty() ? rgw::IAM::s3GetObjectTagging : rgw::IAM::s3GetObjectVersionTagging; // since we are already under s->system_request, if the request is not impersonating, // it can be assumed that it is not a user-mode replication. bool keep_tags = s->auth.identity->is_admin() || verify_object_permission(this, s, action); @@ -3880,7 +3880,7 @@ int RGWCopyObj_ObjStore_S3::get_params(optional_yield y) (s->bucket->get_tenant() == s->src_tenant_name) && (s->bucket->get_name() == s->src_bucket_name) && (s->object->get_name() == s->src_object->get_name()) && - s->src_object->get_instance().empty() && + s->src_object_key.instance.empty() && (attrs_mod != rgw::sal::ATTRSMOD_REPLACE)) { need_to_check_storage_class = true; }