Skip to content

Commit cf0fb42

Browse files
authored
Merge pull request #561 from openmina/fix/vulnerability/p2p
Fix vulnerability similar to CVE-2024-32984
2 parents 12050a4 + 08d2365 commit cf0fb42

File tree

1 file changed

+21
-6
lines changed
  • p2p/src/service_impl/mio

1 file changed

+21
-6
lines changed

p2p/src/service_impl/mio/mod.rs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ impl MioError {
3838
}
3939
}
4040

41+
// maximal ammount of queued data to send per peer is 64 MiB
42+
const MAX_QUEUED_BYTES: usize = 0x4000000;
43+
4144
#[derive(Debug)]
4245
#[allow(clippy::large_enum_variant)]
4346
pub enum MioService {
@@ -181,6 +184,7 @@ struct Listener {
181184
struct Connection {
182185
stream: TcpStream,
183186
transmits: VecDeque<(Box<[u8]>, usize)>,
187+
queued_bytes: usize,
184188
connected: bool,
185189
incoming_ready: bool,
186190
}
@@ -272,8 +276,10 @@ where
272276
}
273277
} else {
274278
while let Some((buf, mut offset)) = connection.transmits.pop_front() {
279+
connection.queued_bytes -= buf.len() - offset;
275280
match connection.stream.write(&buf[offset..]) {
276281
Err(err) if err.kind() == io::ErrorKind::WouldBlock => {
282+
connection.queued_bytes += buf.len() - offset;
277283
connection.transmits.push_front((buf, offset));
278284
rereg = true;
279285
break;
@@ -292,6 +298,7 @@ where
292298
if offset == buf.len() {
293299
self.send(MioEvent::OutgoingDataDidSend(addr, Ok(())));
294300
} else {
301+
connection.queued_bytes += buf.len() - offset;
295302
connection.transmits.push_front((buf, offset));
296303
}
297304
}
@@ -383,6 +390,7 @@ where
383390
let connection = Connection {
384391
stream,
385392
transmits: VecDeque::default(),
393+
queued_bytes: 0,
386394
connected: true,
387395
incoming_ready: false,
388396
};
@@ -449,6 +457,7 @@ where
449457
Connection {
450458
stream,
451459
transmits: VecDeque::default(),
460+
queued_bytes: 0,
452461
connected: false,
453462
incoming_ready: false,
454463
},
@@ -516,7 +525,17 @@ where
516525
}
517526
Send(addr, buf) => {
518527
if let Some(connection) = self.connections.get_mut(&addr) {
528+
connection.queued_bytes += buf.len();
519529
connection.transmits.push_back((buf, 0));
530+
if connection.transmits.len() > 1 && connection.queued_bytes > MAX_QUEUED_BYTES
531+
{
532+
self.connections.remove(&addr);
533+
// the peer is too slow, it requires us to send more and more,
534+
// but cannot accept the data
535+
let msg = "probably malicious".to_string();
536+
self.send(MioEvent::ConnectionDidClose(addr, Err(msg)));
537+
return;
538+
}
520539
let interests =
521540
match (connection.incoming_ready, connection.transmits.is_empty()) {
522541
(false, false) => {
@@ -541,12 +560,8 @@ where
541560
}
542561
}
543562
Disconnect(addr) => {
544-
if let Some(connection) = self.connections.remove(&addr) {
545-
connection
546-
.stream
547-
.shutdown(Shutdown::Both)
548-
.unwrap_or_default();
549-
}
563+
// drop the connection and destructor will close it
564+
self.connections.remove(&addr);
550565
}
551566
}
552567
}

0 commit comments

Comments
 (0)