VYPR
Moderate severityNVD Advisory· Published May 20, 2022· Updated Apr 23, 2025

Buffer for inbound DTLS fragments has no limit

CVE-2022-29189

Description

Pion DTLS before 2.1.4 lacks an upper bound on inbound network buffer, allowing remote attackers to cause excessive memory usage.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Pion DTLS before 2.1.4 lacks an upper bound on inbound network buffer, allowing remote attackers to cause excessive memory usage.

Vulnerability

Pion DTLS, a Go implementation of Datagram Transport Layer Security, prior to version 2.1.4 contains a vulnerability in its fragment buffer used for inbound network traffic. The buffer had no upper limit, causing it to accumulate all network traffic from a remote peer until the handshake completes or times out. This affects all versions before 2.1.4 [1][2][4].

Exploitation

An attacker with network access to a Pion DTLS endpoint can send a large volume of DTLS handshake fragments. No authentication or special privileges are required. By continuously sending fragments, the attacker can cause the buffer to grow without bound, leading to excessive memory consumption [1][4].

Impact

Successful exploitation results in excessive memory usage on the target system, potentially leading to a denial of service (DoS) due to memory exhaustion. No other impacts such as code execution or information disclosure are described [1].

Mitigation

The issue is fixed in version 2.1.4, released on 2022-05-20. The fix introduces a maximum size limit for the fragment buffer, as shown in commit a6397ff [2][4]. No workarounds are available; users should upgrade to 2.1.4 or later [1][3].

AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
github.com/pion/dtlsGo
< 2.1.42.1.4
github.com/pion/dtls/v2Go
< 2.1.42.1.4

Affected products

3

Patches

1
a6397ff7282b

Add limit to fragmentBuffer

https://github.com/pion/dtlsSean DuBoisMay 10, 2022via ghsa
3 files changed · +36 1
  • errors.go+1 0 modified
    @@ -62,6 +62,7 @@ var (
     	errSequenceNumberOverflow            = &InternalError{Err: errors.New("sequence number overflow")}                        //nolint:goerr113
     	errInvalidFSMTransition              = &InternalError{Err: errors.New("invalid state machine transition")}                //nolint:goerr113
     	errFailedToAccessPoolReadBuffer      = &InternalError{Err: errors.New("failed to access pool read buffer")}               //nolint:goerr113
    +	errFragmentBufferOverflow            = &InternalError{Err: errors.New("fragment buffer overflow")}                        //nolint:goerr113
     )
     
     // FatalError indicates that the DTLS connection is no longer available.
    
  • fragment_buffer.go+18 0 modified
    @@ -6,6 +6,9 @@ import (
     	"github.com/pion/dtls/v2/pkg/protocol/recordlayer"
     )
     
    +// 2 megabytes
    +const fragmentBufferMaxSize = 2000000
    +
     type fragment struct {
     	recordLayerHeader recordlayer.Header
     	handshakeHeader   handshake.Header
    @@ -23,10 +26,25 @@ func newFragmentBuffer() *fragmentBuffer {
     	return &fragmentBuffer{cache: map[uint16][]*fragment{}}
     }
     
    +// current total size of buffer
    +func (f *fragmentBuffer) size() int {
    +	size := 0
    +	for i := range f.cache {
    +		for j := range f.cache[i] {
    +			size += len(f.cache[i][j].data)
    +		}
    +	}
    +	return size
    +}
    +
     // Attempts to push a DTLS packet to the fragmentBuffer
     // when it returns true it means the fragmentBuffer has inserted and the buffer shouldn't be handled
     // when an error returns it is fatal, and the DTLS connection should be stopped
     func (f *fragmentBuffer) push(buf []byte) (bool, error) {
    +	if f.size()+len(buf) >= fragmentBufferMaxSize {
    +		return false, errFragmentBufferOverflow
    +	}
    +
     	frag := new(fragment)
     	if err := frag.recordLayerHeader.Unmarshal(buf); err != nil {
     		return false, err
    
  • fragment_buffer_test.go+17 1 modified
    @@ -1,6 +1,7 @@
     package dtls
     
     import (
    +	"errors"
     	"reflect"
     	"testing"
     )
    @@ -57,7 +58,7 @@ func TestFragmentBuffer(t *testing.T) {
     			Epoch: 0,
     		},
     		{
    -			Name: "Multiple Handshakes in Signle Fragment",
    +			Name: "Multiple Handshakes in Single Fragment",
     			In: [][]byte{
     				{
     					0x16, 0xfe, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x30, /* record header */
    @@ -113,3 +114,18 @@ func TestFragmentBuffer(t *testing.T) {
     		}
     	}
     }
    +
    +func TestFragmentBuffer_Overflow(t *testing.T) {
    +	fragmentBuffer := newFragmentBuffer()
    +
    +	// Push a buffer that doesn't exceed size limits
    +	if _, err := fragmentBuffer.push([]byte{0x16, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfe, 0xff, 0x00}); err != nil {
    +		t.Fatal(err)
    +	}
    +
    +	// Allocate a buffer that exceeds cache size
    +	largeBuffer := make([]byte, fragmentBufferMaxSize)
    +	if _, err := fragmentBuffer.push(largeBuffer); !errors.Is(err, errFragmentBufferOverflow) {
    +		t.Fatalf("Pushing a large buffer returned (%s) expected(%s)", err, errFragmentBufferOverflow)
    +	}
    +}
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

7

News mentions

0

No linked articles in our index yet.