diff --git a/.nancy-ignore b/.nancy-ignore index e69de29bb..5cc7cd2d2 100644 --- a/.nancy-ignore +++ b/.nancy-ignore @@ -0,0 +1,6 @@ +CVE-2018-17075 +CVE-2018-17848 +CVE-2018-17846 +CVE-2018-17847 +CVE-2018-17143 +CVE-2018-17142 \ No newline at end of file diff --git a/cmd/bucket-replication.go b/cmd/bucket-replication.go index 189daa209..a2ac13d49 100644 --- a/cmd/bucket-replication.go +++ b/cmd/bucket-replication.go @@ -18,6 +18,7 @@ package cmd import ( "context" + "fmt" "net/http" "strings" "time" @@ -179,20 +180,24 @@ func replicateObject(ctx context.Context, bucket, object, versionID string, obje if tgt == nil { return } - gr, err := objectAPI.GetObjectNInfo(ctx, bucket, object, nil, http.Header{}, readLock, ObjectOptions{}) + gr, err := objectAPI.GetObjectNInfo(ctx, bucket, object, nil, http.Header{}, readLock, ObjectOptions{ + VersionID: versionID, + }) if err != nil { return } - defer gr.Close() + objInfo := gr.ObjInfo size, err := objInfo.GetActualSize() if err != nil { logger.LogIf(ctx, err) + gr.Close() return } dest := cfg.GetDestination() if dest.Bucket == "" { + gr.Close() return } // In the rare event that replication is in pending state either due to @@ -201,6 +206,7 @@ func replicateObject(ctx context.Context, bucket, object, versionID string, obje if healPending { _, err := tgt.StatObject(ctx, dest.Bucket, object, miniogo.StatObjectOptions{VersionID: objInfo.VersionID}) if err == nil { + gr.Close() // object with same VersionID already exists, replication kicked off by // PutObject might have completed. return @@ -210,6 +216,7 @@ func replicateObject(ctx context.Context, bucket, object, versionID string, obje replicationStatus := replication.Complete _, err = tgt.PutObject(ctx, dest.Bucket, object, gr, size, "", "", putOpts) + gr.Close() if err != nil { replicationStatus = replication.Failed // Notify replication failure event. @@ -231,8 +238,10 @@ func replicateObject(ctx context.Context, bucket, object, versionID string, obje objInfo.metadataOnly = true // Perform only metadata updates. if _, err = objectAPI.CopyObject(ctx, bucket, object, bucket, object, objInfo, ObjectOptions{ VersionID: objInfo.VersionID, - }, ObjectOptions{VersionID: objInfo.VersionID}); err != nil { - logger.LogIf(ctx, err) + }, ObjectOptions{ + VersionID: objInfo.VersionID, + }); err != nil { + logger.LogIf(ctx, fmt.Errorf("Unable to update replication metadata for %s: %s", objInfo.VersionID, err)) } } diff --git a/cmd/data-update-tracker.go b/cmd/data-update-tracker.go index 89130ac7b..e47a36df2 100644 --- a/cmd/data-update-tracker.go +++ b/cmd/data-update-tracker.go @@ -426,6 +426,8 @@ func (d *dataUpdateTracker) deserialize(src io.Reader, newerThan time.Time) erro } // Ignore what remains on the stream. // Update d: + d.mu.Lock() + defer d.mu.Unlock() d.Current = dst.Current d.History = dst.History d.Saved = dst.Saved diff --git a/cmd/erasure-object.go b/cmd/erasure-object.go index 754ed7c83..c7f6bdcba 100644 --- a/cmd/erasure-object.go +++ b/cmd/erasure-object.go @@ -72,6 +72,11 @@ func (er erasureObjects) CopyObject(ctx context.Context, srcBucket, srcObject, d return oi, NotImplemented{} } defer ObjectPathUpdated(path.Join(dstBucket, dstObject)) + lk := er.NewNSLock(ctx, dstBucket, dstObject) + if err := lk.GetLock(globalOperationTimeout); err != nil { + return oi, err + } + defer lk.Unlock() // Read metadata associated with the object from all disks. storageDisks := er.getDisks() @@ -112,12 +117,13 @@ func (er erasureObjects) CopyObject(ctx context.Context, srcBucket, srcObject, d fi.VersionID = versionID // set any new versionID we might have created fi.ModTime = modTime // set modTime for the new versionID + srcInfo.UserDefined["etag"] = srcInfo.ETag + // Update `xl.meta` content on each disks. for index := range metaArr { metaArr[index].ModTime = modTime metaArr[index].VersionID = versionID metaArr[index].Metadata = srcInfo.UserDefined - metaArr[index].Metadata["etag"] = srcInfo.ETag } tempObj := mustGetUUID() @@ -741,6 +747,12 @@ func (er erasureObjects) putObject(ctx context.Context, bucket string, object st return ObjectInfo{}, IncompleteBody{Bucket: bucket, Object: object} } + lk := er.NewNSLock(ctx, bucket, object) + if err := lk.GetLock(globalOperationTimeout); err != nil { + return ObjectInfo{}, err + } + defer lk.Unlock() + for i, w := range writers { if w == nil { onlineDisks[i] = nil @@ -780,12 +792,6 @@ func (er erasureObjects) putObject(ctx context.Context, bucket string, object st return ObjectInfo{}, toObjectErr(err, bucket, object) } - lk := er.NewNSLock(ctx, bucket, object) - if err := lk.GetLock(globalOperationTimeout); err != nil { - return ObjectInfo{}, err - } - defer lk.Unlock() - // Rename the successfully written temporary object to final location. if onlineDisks, err = renameData(ctx, onlineDisks, minioMetaTmpBucket, tempObj, fi.DataDir, bucket, object, writeQuorum, nil); err != nil { return ObjectInfo{}, toObjectErr(err, bucket, object) diff --git a/go.mod b/go.mod index 07cd239cc..e700b1010 100644 --- a/go.mod +++ b/go.mod @@ -79,9 +79,9 @@ require ( github.com/willf/bloom v2.0.3+incompatible github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c go.etcd.io/etcd/v3 v3.3.0-rc.0.0.20200707003333-58bb8ae09f8e - golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899 - golang.org/x/net v0.0.0-20200707034311-ab3426394381 - golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae + golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a + golang.org/x/net v0.0.0-20200904194848-62affa334b73 + golang.org/x/sys v0.0.0-20200915084602-288bc346aa39 golang.org/x/tools v0.0.0-20200814172026-c4923e618c08 // indirect google.golang.org/api v0.5.0 gopkg.in/jcmturner/gokrb5.v7 v7.3.0 diff --git a/go.sum b/go.sum index e58fb0222..4c78503df 100644 --- a/go.sum +++ b/go.sum @@ -501,6 +501,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnk golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899 h1:DZhuSZLsGlFL4CmhA8BcRA0mnthyA/nZ00AqCUo7vHg= golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -530,6 +532,8 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200904194848-62affa334b73 h1:MXfv8rhZWmFeqX3GNZRsd6vOLoaCHjYEX3qkRo3YBUA= +golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421 h1:Wo7BWFiOk0QRFMLYMqJGFMd9CgUAcGx7V+qEg/h5IBI= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -564,6 +568,8 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20u golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae h1:Ih9Yo4hSPImZOpfGuA4bR/ORKTAbhZo2AbWNRCnevdo= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200915084602-288bc346aa39 h1:356XA7ITklAU2//sYkjFeco+dH1bCRD8XCJ9FIEsvo4= +golang.org/x/sys v0.0.0-20200915084602-288bc346aa39/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db h1:6/JqlYfC1CCaLnGceQTI+sDGhC9UBSPAsBqI0Gun6kU=