Skip to content

Commit e7a952e

Browse files
roypatzulinx86
authored andcommitted
fix: avoid potential panic when restoring malformed MMDS
If a snapshot file is malformed in a way that a field that is expected to never be zero ends up being zero, Firecracker would panic. Fix this by consistency typing this field as `NonZeroUsize` through the code base. For the `NonZero*` types, serde already has support. Now if a snapshot file is malformed and has zeroes here, serde will return an error, which causes Firecracker to exit gracefully instead of panicking. Signed-off-by: Patrick Roy <[email protected]>
1 parent 5f5bb4a commit e7a952e

File tree

2 files changed

+14
-15
lines changed

2 files changed

+14
-15
lines changed

src/vmm/src/dumbo/tcp/handler.rs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ pub struct TcpIPv4Handler {
129129
// This map holds the currently active endpoints, identified by their connection tuple.
130130
connections: HashMap<ConnectionTuple, Endpoint>,
131131
// Maximum number of concurrent connections we are willing to handle.
132-
max_connections: usize,
132+
max_connections: NonZeroUsize,
133133
// Holds connections which are able to send segments immediately.
134134
active_connections: HashSet<ConnectionTuple>,
135135
// Remembers the closest timestamp into the future when one of the connections has to deal
@@ -138,7 +138,7 @@ pub struct TcpIPv4Handler {
138138
// RST segments awaiting to be sent.
139139
rst_queue: Vec<(ConnectionTuple, RstConfig)>,
140140
// Maximum size of the RST queue.
141-
max_pending_resets: usize,
141+
max_pending_resets: NonZeroUsize,
142142
}
143143

144144
// Only used locally, in the receive_packet method, to differentiate between different outcomes
@@ -164,16 +164,14 @@ impl TcpIPv4Handler {
164164
max_connections: NonZeroUsize,
165165
max_pending_resets: NonZeroUsize,
166166
) -> Self {
167-
let max_connections = max_connections.get();
168-
let max_pending_resets = max_pending_resets.get();
169167
TcpIPv4Handler {
170168
local_ipv4_addr,
171169
local_port,
172-
connections: HashMap::with_capacity(max_connections),
170+
connections: HashMap::with_capacity(max_connections.get()),
173171
max_connections,
174-
active_connections: HashSet::with_capacity(max_connections),
172+
active_connections: HashSet::with_capacity(max_connections.get()),
175173
next_timeout: None,
176-
rst_queue: Vec::with_capacity(max_pending_resets),
174+
rst_queue: Vec::with_capacity(max_pending_resets.get()),
177175
max_pending_resets,
178176
}
179177
}
@@ -194,12 +192,12 @@ impl TcpIPv4Handler {
194192
}
195193

196194
/// Returns the max connections of this TCP handler.
197-
pub fn max_connections(&self) -> usize {
195+
pub fn max_connections(&self) -> NonZeroUsize {
198196
self.max_connections
199197
}
200198

201199
/// Returns the max pending resets of this TCP handler.
202-
pub fn max_pending_resets(&self) -> usize {
200+
pub fn max_pending_resets(&self) -> NonZeroUsize {
203201
self.max_pending_resets
204202
}
205203

@@ -257,7 +255,7 @@ impl TcpIPv4Handler {
257255
Err(_) => return Ok(RecvEvent::FailedNewConnection),
258256
};
259257

260-
if self.connections.len() >= self.max_connections {
258+
if self.connections.len() >= self.max_connections.get() {
261259
if let Some(evict_tuple) = self.find_evictable_connection() {
262260
let rst_config = self.connections[&evict_tuple]
263261
.connection()
@@ -363,7 +361,7 @@ impl TcpIPv4Handler {
363361

364362
fn enqueue_rst_config(&mut self, tuple: ConnectionTuple, cfg: RstConfig) {
365363
// We simply forgo sending any RSTs if the queue is already full.
366-
if self.rst_queue.len() < self.max_pending_resets {
364+
if self.rst_queue.len() < self.max_pending_resets.get() {
367365
self.rst_queue.push((tuple, cfg));
368366
}
369367
}

src/vmm/src/mmds/persist.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
//! Defines the structures needed for saving/restoring MmdsNetworkStack.
55
66
use std::net::Ipv4Addr;
7+
use std::num::NonZeroUsize;
78
use std::sync::{Arc, Mutex};
89

910
use serde::{Deserialize, Serialize};
@@ -19,8 +20,8 @@ pub struct MmdsNetworkStackState {
1920
mac_addr: [u8; MAC_ADDR_LEN as usize],
2021
ipv4_addr: u32,
2122
tcp_port: u16,
22-
max_connections: usize,
23-
max_pending_resets: usize,
23+
max_connections: NonZeroUsize,
24+
max_pending_resets: NonZeroUsize,
2425
}
2526

2627
impl Persist<'_> for MmdsNetworkStack {
@@ -49,8 +50,8 @@ impl Persist<'_> for MmdsNetworkStack {
4950
MacAddr::from_bytes_unchecked(&state.mac_addr),
5051
Ipv4Addr::from(state.ipv4_addr),
5152
state.tcp_port,
52-
std::num::NonZeroUsize::new(state.max_connections).unwrap(),
53-
std::num::NonZeroUsize::new(state.max_pending_resets).unwrap(),
53+
state.max_connections,
54+
state.max_pending_resets,
5455
mmds,
5556
))
5657
}

0 commit comments

Comments
 (0)