Project

General

Profile

Bug #58035

Copying an object to itself crashes de RGW if executed as admin user.

Added by Xavi Garcia 3 months ago. Updated 3 months ago.

Status:
Fix Under Review
Priority:
Normal
Assignee:
-
Target version:
-
% Done:

0%

Source:
Tags:
Backport:
pacific quincy
Regression:
No
Severity:
3 - minor
Reviewed:
Affected Versions:
ceph-qa-suite:
Pull request ID:
Crash signature (v1):
Crash signature (v2):

Description

This was observed after executing the test s3tests_boto3.functional.test_s3:test_object_copy_to_itself with a user with admin flag active.

Code gets to this point:

int RGWCopyObj_ObjStore_S3::check_storage_class(const rgw_placement_rule& src_placement)
{
  if (src_placement == s->dest_placement) {
    /* can only copy object into itself if replacing attrs */
    s->err.message = "This copy request is illegal because it is trying to copy " 
      "an object to itself without changing the object's metadata, " 
      "storage class, website redirect location or encryption attributes.";
    ldpp_dout(this, 0) << s->err.message << dendl;
    return -ERR_INVALID_REQUEST;
  }
  return 0;
}

and returns the expected error.

This is called from RGWCopyObj::verify_permission

      op_ret  = check_storage_class(src_placement);
      if (op_ret < 0) {
        return op_ret;
      }

and error is returned as expected.

But later on the RGWCopyObj::verify_permission method the destination bucket and destination object were not initialised as the -ERR_INVALID_REQUEST was detected before.

Later, on rgw_process_authenticated we have this:

  if (ret < 0) {
    if (s->system_request) {
      dout(2) << "overriding permissions due to system operation" << dendl;
    } else if (s->auth.identity->is_admin_of(s->user->get_id())) {
      dout(2) << "overriding permissions due to admin operation" << dendl;
    } else {
      return ret;
    }
  }

Which basically means the error is ignored and keeps going (but the destination bucket and destination object were not initialised as stated before).

Finally, the RGWCopyObj::execute method crashes.

void RGWCopyObj::execute(optional_yield y)
{
  if (init_common() < 0)
    return;

  // make reservation for notification if needed
  std::unique_ptr<rgw::sal::Notification> res
                   = store->get_notification(
                     s->object.get(), s->src_object.get(),
                     s, rgw::notify::ObjectCreatedCopy);
  op_ret = res->publish_reserve(this);
  if (op_ret < 0) {
    return;
  }

  if ( ! version_id.empty()) {
    dest_object->set_instance(version_id);
  } else if (dest_bucket->versioning_enabled()) {    // THIS IS THE LINE CRASHING (dest_bucket == nulltptr)
    dest_object->gen_rand_obj_instance_name();
  }

This could affect other operations executed as admin user, as the error could be detected before the rgw operation is fully initialised.

This was observed in the main branch.

History

#1 Updated by Casey Bodley 3 months ago

  • Status changed from New to Fix Under Review
  • Backport set to pacific quincy
  • Pull request ID set to 48912

Also available in: Atom PDF