diff --git a/CHANGELOG.md b/CHANGELOG.md index a6f096214..4934da5d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ Changelog for NeoFS Node - Do not replicate object twice to the same node (#1410) - Concurrent object handling by the Policer (#1411) - Attaching API version to the forwarded requests (#1581) +- Node OOM panics on `GetRange` request with extremely huge range length (#1590) ### Removed diff --git a/pkg/services/object/get/v2/util.go b/pkg/services/object/get/v2/util.go index 01c5ce47c..7ab7fd038 100644 --- a/pkg/services/object/get/v2/util.go +++ b/pkg/services/object/get/v2/util.go @@ -250,7 +250,8 @@ func (s *Service) toRangePrm(req *objectV2.GetRangeRequest, stream objectSvc.Get return nil, fmt.Errorf("could not create Get payload range stream: %w", err) } - payload := make([]byte, 0, body.GetRange().GetLength()) + // allocate memory only after receiving a successful response + var payload []byte resp := new(objectV2.GetRangeResponse) @@ -283,6 +284,10 @@ func (s *Service) toRangePrm(req *objectV2.GetRangeRequest, stream objectSvc.Get case nil: return nil, fmt.Errorf("unexpected range type %T", v) case *objectV2.GetRangePartChunk: + if payload == nil { + payload = make([]byte, 0, body.GetRange().GetLength()) + } + payload = append(payload, v.GetChunk()...) case *objectV2.SplitInfo: si := object.NewSplitInfoFromV2(v)