Project

General

Profile

Actions

Bug #42825

closed

partial copy problem

Added by Xinying Song over 4 years ago. Updated over 3 years ago.

Status:
Resolved
Priority:
Normal
Assignee:
-
Target version:
-
% Done:

0%

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

Description

When a user in a non-default tenant specify x-amz-copy-source=<bucket>/<object>, the source object will always be fetched from the bucket under default tenant without checking permissions.

For example, create two users as follows:
```
radosgw-admin user create --uid='test1' --display-name='test1-under-default-tenant' --access-key=test1 --secret=test1
radosgw-admin user create --uid='test2' --display-name='test2-under-test2-tenant' --access-key=test2 --secret=test2
```
User test1 creates bucket test1bucket, and puts an object named test.
User test2 creates bucket test2bucket.
Now user test2 can copy the test object under test1bucket to its own bucket, which shouldn't be allowed.

curl's output like this:

PUT /test2bucket/copytest HTTP/1.1
User-Agent: curl/7.29.0
Host: 127.0.0.1:7480
Accept: */*
Date: Fri, 15 Nov 2019 02:03:57 +0000
Content-Type: application/xml
Content-Length: 0
Authorization: AWS test2:OvMKLJtn3CuW48SrUZriAyaS9os=
x-amz-copy-source: test1bucket/test
x-amz-copy-source-range: bytes=0-4

< HTTP/1.1 200 OK
< x-amz-request-id: tx0000000000000000000e7-005dce078d-103e-default
< Content-Type: application/xml
< Content-Length: 217
< Date: Fri, 15 Nov 2019 02:03:57 GMT
<

Actions #2

Updated by Nathan Cutler over 4 years ago

  • Status changed from New to Fix Under Review
  • Pull request ID set to 31663
Actions #3

Updated by Xinying Song over 4 years ago

By the way, when do range copy from a multipart-object, read_obj_policy() will fail. Because it will try to read policy info from the part header of the source object.

My curl script likes this:
```
endpoint="127.0.0.1:7480"
uploadID="2~gNxoAeDQciWs9L58zVOKqesKQ1hwArU"
resource="/test2/big2?partNumber=1&uploadId=${uploadID}"
contentType="application/xml"
contentMD5=""
dateValue=`date R -u`
stringToSign="PUT
${contentMD5}
${contentType}
${dateValue}
x-amz-copy-source:test2/30MB
x-amz-copy-source-range:bytes=0-5242879
${resource}"
s3Key="tmp2"
s3Secret="tmp2"
signature=`/bin/echo -n "$stringToSign" | openssl sha1 -hmac ${s3Secret} -binary | base64`
curl -v -X PUT \
-H "Date: ${dateValue}" \
-H "Content-Type: ${contentType}" \
-H "Content-Length: 0" \
-H "Authorization: AWS ${s3Key}:${signature}" \
-H "x-amz-copy-source: test2/30MB" \
-H "x-amz-copy-source-range: bytes=0-5242879" \
"http://${endpoint}${resource}"
```
rgw log shows this:
```
2019-11-19T19:57:14.049+0800 7f9617b3e700 2 req 2 0.003000000s s3:put_obj verifying op permissions
2019-11-19T19:57:14.049+0800 7f9617b3e700 20 get_obj_state: rctx=0x7f9658545fd0 obj=test2:_multipart_30MB.2~gNxoAeDQciWs9L58zVOKqesKQ1hwArU.meta state=0x7f965856e098 s
>prefetch_data=0
2019-11-19T19:57:14.050+0800 7f9617b3e700 20 WARNING: blocking librados call
2019-11-19T19:57:14.050+0800 7f9617b3e700 0 WARNING: couldn't find acl header for bucket, generating default
2019-11-19T19:57:14.050+0800 7f9617b3e700 20 get_system_obj_state: rctx=0x7f9658544c48 obj=default.rgw.meta:users.uid:tmp2$tmp2 state=0x7f96574519c0 s->prefetch_data=0
2019-11-19T19:57:14.050+0800 7f9617b3e700 10 cache get: name=default.rgw.meta+users.uid+tmp2$tmp2 : hit (requested=0x6, cached=0x17)
2019-11-19T19:57:14.050+0800 7f9617b3e700 20 get_system_obj_state: s->obj_tag was set empty
2019-11-19T19:57:14.050+0800 7f9617b3e700 10 cache get: name=default.rgw.meta+users.uid+tmp2$tmp2 : hit (requested=0x1, cached=0x17)
2019-11-19T19:57:14.050+0800 7f9617b3e700 1 op->ERRORHANDLER: err_no=-13 new_err_no=-13
2019-11-19T19:57:14.051+0800 7f9617b3e700 2 req 2 0.005000000s s3:put_obj op status=0
2019-11-19T19:57:14.051+0800 7f9617b3e700 2 req 2 0.005000000s s3:put_obj http status=403
```

Apparently, rgw should read 'test2:30MB' to get correct policy info, however, it consults to 'test2:_multipart_30MB.2~gNxoAeDQciWs9L58zVOKqesKQ1hwArU.meta'

Actions #4

Updated by Xinying Song over 4 years ago

Xinying Song wrote:

By the way, when do range copy from a multipart-object, read_obj_policy() will fail. Because it will try to read policy info from the part header of the source object.

My curl script likes this:
```
endpoint="127.0.0.1:7480"
uploadID="2~gNxoAeDQciWs9L58zVOKqesKQ1hwArU"
resource="/test2/big2?partNumber=1&uploadId=${uploadID}"
contentType="application/xml"
contentMD5=""
dateValue=`date R -u`
stringToSign="PUT
${contentMD5}
${contentType}
${dateValue}
x-amz-copy-source:test2/30MB
x-amz-copy-source-range:bytes=0-5242879
${resource}"
s3Key="tmp2"
s3Secret="tmp2"
signature=`/bin/echo -n "$stringToSign" | openssl sha1 -hmac ${s3Secret} -binary | base64`
curl -v -X PUT \
-H "Date: ${dateValue}" \
-H "Content-Type: ${contentType}" \
-H "Content-Length: 0" \
-H "Authorization: AWS ${s3Key}:${signature}" \
-H "x-amz-copy-source: test2/30MB" \
-H "x-amz-copy-source-range: bytes=0-5242879" \
"http://${endpoint}${resource}"
```
rgw log shows this:
```
2019-11-19T19:57:14.049+0800 7f9617b3e700 2 req 2 0.003000000s s3:put_obj verifying op permissions
2019-11-19T19:57:14.049+0800 7f9617b3e700 20 get_obj_state: rctx=0x7f9658545fd0 obj=test2:_multipart_30MB.2~gNxoAeDQciWs9L58zVOKqesKQ1hwArU.meta state=0x7f965856e098 s
>prefetch_data=0
2019-11-19T19:57:14.050+0800 7f9617b3e700 20 WARNING: blocking librados call
2019-11-19T19:57:14.050+0800 7f9617b3e700 0 WARNING: couldn't find acl header for bucket, generating default
2019-11-19T19:57:14.050+0800 7f9617b3e700 20 get_system_obj_state: rctx=0x7f9658544c48 obj=default.rgw.meta:users.uid:tmp2$tmp2 state=0x7f96574519c0 s->prefetch_data=0
2019-11-19T19:57:14.050+0800 7f9617b3e700 10 cache get: name=default.rgw.meta+users.uid+tmp2$tmp2 : hit (requested=0x6, cached=0x17)
2019-11-19T19:57:14.050+0800 7f9617b3e700 20 get_system_obj_state: s->obj_tag was set empty
2019-11-19T19:57:14.050+0800 7f9617b3e700 10 cache get: name=default.rgw.meta+users.uid+tmp2$tmp2 : hit (requested=0x1, cached=0x17)
2019-11-19T19:57:14.050+0800 7f9617b3e700 1 op->ERRORHANDLER: err_no=-13 new_err_no=-13
2019-11-19T19:57:14.051+0800 7f9617b3e700 2 req 2 0.005000000s s3:put_obj op status=0
2019-11-19T19:57:14.051+0800 7f9617b3e700 2 req 2 0.005000000s s3:put_obj http status=403
```

Apparently, rgw should read 'test2:30MB' to get correct policy info, however, it consults to 'test2:_multipart_30MB.2~gNxoAeDQciWs9L58zVOKqesKQ1hwArU.meta'

Actually, I made a mistake describing this problem. It is not caused by doing a range copy from a multipart-object, instead, it is caused when doing a range copy with an uploadId in request query string. Despite whether we're donging a range copy from an atomic-object or multipart-object. The fix has been included in the pr mentioned above.

Actions #5

Updated by J. Eric Ivancich over 3 years ago

  • Status changed from Fix Under Review to Resolved

No backports are listed. If backports are appropriate please update this tracker, list the appropriate backports, and change the status to Pending Backport.

Actions

Also available in: Atom PDF