Bug #58035
openCopying an object to itself crashes de RGW if executed as admin user.
0%
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.