diff --git a/CHANGELOG.md b/CHANGELOG.md index 91f108bb1b3..bd35063dfba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ Changelog for NeoFS Node - Inability to deploy contract with non-standard zone via neofs-adm ### Changed +- Storage nodes no longer accept objects with header larger than 16KB (#xxx) ### Removed diff --git a/pkg/core/object/fmt.go b/pkg/core/object/fmt.go index c533e0c040d..416d6b7e963 100644 --- a/pkg/core/object/fmt.go +++ b/pkg/core/object/fmt.go @@ -12,6 +12,13 @@ import ( "github.com/nspcc-dev/neofs-sdk-go/storagegroup" ) +// MaxHeaderLen is a maximum allowed length of binary object header to be +// created via NeoFS API protocol. +const MaxHeaderLen = 16 << 10 + +// ErrMaxHeaderLenExceeded is returned when [MaxHeaderLen] is exceeded. +var ErrMaxHeaderLenExceeded = errors.New("max object header length exceeded") + // FormatValidator represents an object format validator. type FormatValidator struct { *cfg diff --git a/pkg/services/object/acl/v2/service.go b/pkg/services/object/acl/v2/service.go index 298b1a8f7ba..4f844cba631 100644 --- a/pkg/services/object/acl/v2/service.go +++ b/pkg/services/object/acl/v2/service.go @@ -8,6 +8,7 @@ import ( objectV2 "github.com/nspcc-dev/neofs-api-go/v2/object" "github.com/nspcc-dev/neofs-node/pkg/core/container" "github.com/nspcc-dev/neofs-node/pkg/core/netmap" + objectcore "github.com/nspcc-dev/neofs-node/pkg/core/object" "github.com/nspcc-dev/neofs-node/pkg/services/object" apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status" "github.com/nspcc-dev/neofs-sdk-go/container/acl" @@ -516,6 +517,14 @@ func (p putStreamBasicChecker) Send(request *objectV2.PutRequest) error { return err } + // if not a replication request, check max header size + if reqInfo.requestRole != acl.RoleContainer || request.GetMetaHeader().GetTTL() != 1 { + hdrLen := part.GetHeader().StableSize() + if hdrLen > objectcore.MaxHeaderLen { + return fmt.Errorf("%w: %d>%d", objectcore.ErrMaxHeaderLenExceeded, hdrLen, objectcore.MaxHeaderLen) + } + } + reqInfo.obj = obj if !p.source.checker.CheckBasicACL(reqInfo) || !p.source.checker.StickyBitCheck(reqInfo, idOwner) {