Skip to content

Commit 0652e53

Browse files
authored
Merge pull request #17 from k0nserv/fix-fragment-buffer-max-size
Backport buffer limit fix from Pion
2 parents d70593d + 2d5c99d commit 0652e53

File tree

3 files changed

+43
-0
lines changed

3 files changed

+43
-0
lines changed

crates/dtls/src/error.rs

+5
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,11 @@ pub enum Error {
144144
#[error("Alert is Fatal or Close Notify")]
145145
ErrAlertFatalOrClose,
146146

147+
#[error(
148+
"Fragment buffer overflow. New size {new_size} is greater than specified max {max_size}"
149+
)]
150+
ErrFragmentBufferOverflow { new_size: usize, max_size: usize },
151+
147152
#[error("{0}")]
148153
Io(#[source] IoError),
149154
#[error("{0}")]

crates/dtls/src/fragment_buffer/fragment_buffer_test.rs

+20
Original file line numberDiff line numberDiff line change
@@ -143,3 +143,23 @@ fn test_fragment_buffer() -> Result<()> {
143143

144144
Ok(())
145145
}
146+
147+
#[test]
148+
fn test_fragment_buffer_overflow() -> Result<()> {
149+
let mut fragment_buffer = FragmentBuffer::new();
150+
151+
fragment_buffer.push(&[
152+
0x16, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x03, 0x00,
153+
0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfe, 0xff, 0x00,
154+
])?;
155+
156+
let big_buffer = vec![0; 2_000_000];
157+
let result = fragment_buffer.push(&big_buffer);
158+
159+
assert!(
160+
result.is_err(),
161+
"Pushing a buffer of size 2MB should have caused FragmentBuffer::push to return an error"
162+
);
163+
164+
Ok(())
165+
}

crates/dtls/src/fragment_buffer/mod.rs

+18
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ use crate::record_layer::record_layer_header::*;
99
use std::collections::HashMap;
1010
use std::io::{BufWriter, Cursor};
1111

12+
// 2 mb max buffer size
13+
const FRAGMENT_BUFFER_MAX_SIZE: usize = 2_000_000;
14+
1215
pub(crate) struct Fragment {
1316
record_layer_header: RecordLayerHeader,
1417
handshake_header: HandshakeHeader,
@@ -34,6 +37,14 @@ impl FragmentBuffer {
3437
// when it returns true it means the FragmentBuffer has inserted and the buffer shouldn't be handled
3538
// when an error returns it is fatal, and the DTLS connection should be stopped
3639
pub fn push(&mut self, mut buf: &[u8]) -> Result<bool> {
40+
let current_size = self.size();
41+
if current_size + buf.len() >= FRAGMENT_BUFFER_MAX_SIZE {
42+
return Err(Error::ErrFragmentBufferOverflow {
43+
new_size: current_size + buf.len(),
44+
max_size: FRAGMENT_BUFFER_MAX_SIZE,
45+
});
46+
}
47+
3748
let mut reader = Cursor::new(buf);
3849
let record_layer_header = RecordLayerHeader::unmarshal(&mut reader)?;
3950

@@ -113,6 +124,13 @@ impl FragmentBuffer {
113124

114125
Ok((content, epoch))
115126
}
127+
128+
fn size(&self) -> usize {
129+
self.cache
130+
.iter()
131+
.map(|(_, fragment)| fragment.iter().map(|f| f.data.len()).sum::<usize>())
132+
.sum()
133+
}
116134
}
117135

118136
fn append_message(target_offset: u32, frags: &[Fragment], raw_message: &mut Vec<u8>) -> bool {

0 commit comments

Comments
 (0)