Skip to content

Commit dd46c24

Browse files
tangdeyileonrayang
authored andcommitted
fix(objectnode): fix read body entirely into memory and without an upper boundary
Signed-off-by: tangdeyi <tangdeyi@oppo.com>
1 parent 972f027 commit dd46c24

File tree

5 files changed

+67
-28
lines changed

5 files changed

+67
-28
lines changed

Diff for: objectnode/api_handler_bucket.go

+26-24
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import (
2323
"io/ioutil"
2424
"net/http"
2525
"regexp"
26-
"strconv"
2726
"strings"
2827

2928
"github.com/cubefs/cubefs/proto"
@@ -86,30 +85,29 @@ func (o *ObjectNode) createBucketHandler(w http.ResponseWriter, r *http.Request)
8685
}
8786
defer rateLimit.ReleaseLimitResource(userInfo.UserID, param.apiName)
8887

89-
// get LocationConstraint if any
90-
contentLenStr := r.Header.Get(ContentLength)
91-
if contentLen, errConv := strconv.Atoi(contentLenStr); errConv == nil && contentLen > 0 {
92-
var requestBytes []byte
93-
requestBytes, err = ioutil.ReadAll(r.Body)
94-
if err != nil && err != io.EOF {
95-
log.LogErrorf("createBucketHandler: read request body fail: requestID(%v) err(%v)", GetRequestID(r), err)
96-
return
97-
}
88+
_, errorCode = VerifyContentLength(r, BodyLimit)
89+
if errorCode != nil {
90+
return
91+
}
92+
requestBytes, err := ioutil.ReadAll(r.Body)
93+
if err != nil && err != io.EOF {
94+
log.LogErrorf("createBucketHandler: read request body fail: requestID(%v) err(%v)", GetRequestID(r), err)
95+
return
96+
}
9897

99-
createBucketRequest := &CreateBucketRequest{}
100-
err = UnmarshalXMLEntity(requestBytes, createBucketRequest)
101-
if err != nil {
102-
log.LogErrorf("createBucketHandler: unmarshal xml fail: requestID(%v) err(%v)",
103-
GetRequestID(r), err)
104-
errorCode = InvalidArgument
105-
return
106-
}
107-
if createBucketRequest.LocationConstraint != o.region {
108-
log.LogErrorf("createBucketHandler: location constraint not match the service: requestID(%v) LocationConstraint(%v) region(%v)",
109-
GetRequestID(r), createBucketRequest.LocationConstraint, o.region)
110-
errorCode = InvalidLocationConstraint
111-
return
112-
}
98+
createBucketRequest := &CreateBucketRequest{}
99+
err = UnmarshalXMLEntity(requestBytes, createBucketRequest)
100+
if err != nil {
101+
log.LogErrorf("createBucketHandler: unmarshal xml fail: requestID(%v) err(%v)",
102+
GetRequestID(r), err)
103+
errorCode = InvalidArgument
104+
return
105+
}
106+
if createBucketRequest.LocationConstraint != o.region {
107+
log.LogErrorf("createBucketHandler: location constraint not match the service: requestID(%v) LocationConstraint(%v) region(%v)",
108+
GetRequestID(r), createBucketRequest.LocationConstraint, o.region)
109+
errorCode = InvalidLocationConstraint
110+
return
113111
}
114112

115113
var acl *AccessControlPolicy
@@ -397,6 +395,10 @@ func (o *ObjectNode) putBucketTaggingHandler(w http.ResponseWriter, r *http.Requ
397395
}
398396
defer rateLimit.ReleaseLimitResource(vol.owner, param.apiName)
399397

398+
_, errorCode = VerifyContentLength(r, BodyLimit)
399+
if errorCode != nil {
400+
return
401+
}
400402
var body []byte
401403
if body, err = ioutil.ReadAll(r.Body); err != nil {
402404
log.LogErrorf("putBucketTaggingHandler: read request body data fail: requestID(%v) err(%v)",

Diff for: objectnode/api_handler_multipart.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -651,8 +651,11 @@ func (o *ObjectNode) completeMultipartUploadHandler(w http.ResponseWriter, r *ht
651651
defer rateLimit.ReleaseLimitResource(vol.owner, param.apiName)
652652

653653
// get uploaded part info in request
654-
var requestBytes []byte
655-
requestBytes, err = ioutil.ReadAll(r.Body)
654+
_, errorCode = VerifyContentLength(r, BodyLimit)
655+
if errorCode != nil {
656+
return
657+
}
658+
requestBytes, err := ioutil.ReadAll(r.Body)
656659
if err != nil && err != io.EOF {
657660
log.LogErrorf("completeMultipartUploadHandler: read request body fail: requestID(%v) err(%v)",
658661
GetRequestID(r), err)

Diff for: objectnode/api_handler_object.go

+31-2
Original file line numberDiff line numberDiff line change
@@ -557,8 +557,11 @@ func (o *ObjectNode) deleteObjectsHandler(w http.ResponseWriter, r *http.Request
557557
return
558558
}
559559

560-
var bytes []byte
561-
bytes, err = ioutil.ReadAll(r.Body)
560+
_, errorCode = VerifyContentLength(r, BodyLimit)
561+
if errorCode != nil {
562+
return
563+
}
564+
bytes, err := ioutil.ReadAll(r.Body)
562565
if err != nil {
563566
log.LogErrorf("deleteObjectsHandler: read request body fail: requestID(%v) volume(%v) err(%v)",
564567
GetRequestID(r), param.Bucket(), err)
@@ -1552,6 +1555,10 @@ func (o *ObjectNode) putObjectTaggingHandler(w http.ResponseWriter, r *http.Requ
15521555
}
15531556
defer rateLimit.ReleaseLimitResource(vol.owner, param.apiName)
15541557

1558+
_, errorCode = VerifyContentLength(r, BodyLimit)
1559+
if errorCode != nil {
1560+
return
1561+
}
15551562
var requestBody []byte
15561563
if requestBody, err = ioutil.ReadAll(r.Body); err != nil {
15571564
log.LogErrorf("putObjectTaggingHandler: read request body data fail: requestID(%v) err(%v)",
@@ -1660,6 +1667,10 @@ func (o *ObjectNode) putObjectXAttrHandler(w http.ResponseWriter, r *http.Reques
16601667
}
16611668
defer rateLimit.ReleaseLimitResource(vol.owner, param.apiName)
16621669

1670+
_, errorCode = VerifyContentLength(r, BodyLimit)
1671+
if errorCode != nil {
1672+
return
1673+
}
16631674
var requestBody []byte
16641675
if requestBody, err = ioutil.ReadAll(r.Body); err != nil {
16651676
errorCode = &ErrorCode{
@@ -1962,3 +1973,21 @@ func GetContentLength(r *http.Request) int64 {
19621973
}
19631974
return r.ContentLength
19641975
}
1976+
1977+
func VerifyContentLength(r *http.Request, bodyLimit int64) (int64, *ErrorCode) {
1978+
dcl := r.Header.Get(HeaderNameXAmzDecodedContentLength)
1979+
var length = r.ContentLength
1980+
if dcl != "" {
1981+
l, err := strconv.ParseInt(dcl, 10, 64)
1982+
if err == nil {
1983+
length = l
1984+
}
1985+
}
1986+
if length > bodyLimit {
1987+
return 0, EntityTooLarge
1988+
}
1989+
if length <= 0 {
1990+
return 0, MissingContentLength
1991+
}
1992+
return length, nil
1993+
}

Diff for: objectnode/const.go

+1
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ const (
133133
MaxParts = 1000
134134
MaxUploads = 1000
135135
SinglePutLimit = 5 * 1 << 30 // 5G
136+
BodyLimit = 1 << 20
136137
)
137138

138139
const (

Diff for: objectnode/lifecycle_handler.go

+4
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ func (o *ObjectNode) putBucketLifecycleConfigurationHandler(w http.ResponseWrite
106106
return
107107
}
108108

109+
_, errorCode = VerifyContentLength(r, BodyLimit)
110+
if errorCode != nil {
111+
return
112+
}
109113
var requestBody []byte
110114
if requestBody, err = ioutil.ReadAll(r.Body); err != nil && err != io.EOF {
111115
log.LogErrorf("putBucketLifecycle failed: read request body data err: requestID(%v) err(%v)", GetRequestID(r), err)

0 commit comments

Comments
 (0)