Skip to content

Commit 16b3388

Browse files
authored
Merge pull request #345 from Dstack-TEE/fix-overflow
dstack-mr: Fix potential panic due to int overflow
2 parents ddfd3c3 + dd91bff commit 16b3388

File tree

2 files changed

+54
-17
lines changed

2 files changed

+54
-17
lines changed

dstack-mr/src/kernel.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ fn authenticode_sha384_hash(data: &[u8]) -> Result<Vec<u8>> {
9999
let trailing_data_len = file_size - sum_of_bytes_hashed;
100100

101101
if trailing_data_len > cert_table_size {
102-
let hashed_trailing_len = trailing_data_len - cert_table_size;
102+
let hashed_trailing_len = trailing_data_len.saturating_sub(cert_table_size);
103103
let trailing_start = sum_of_bytes_hashed;
104104

105105
if trailing_start + hashed_trailing_len <= data.len() {
@@ -142,14 +142,14 @@ fn patch_kernel(
142142
}
143143
if protocol >= 0x201 {
144144
kd[0x211] |= 0x80; // loadflags |= CAN_USE_HEAP
145-
let heap_end_ptr = cmdline_addr - real_addr - 0x200;
145+
let heap_end_ptr = cmdline_addr.saturating_sub(real_addr).saturating_sub(0x200);
146146
kd[0x224..0x228].copy_from_slice(&heap_end_ptr.to_le_bytes());
147147
}
148148
if protocol >= 0x202 {
149149
kd[0x228..0x22C].copy_from_slice(&cmdline_addr.to_le_bytes());
150150
} else {
151151
kd[0x20..0x22].copy_from_slice(&0xa33f_u16.to_le_bytes());
152-
let offset = (cmdline_addr - real_addr) as u16;
152+
let offset = cmdline_addr.saturating_sub(real_addr) as u16;
153153
kd[0x22..0x24].copy_from_slice(&offset.to_le_bytes());
154154
}
155155

@@ -186,14 +186,23 @@ fn patch_kernel(
186186
mem_size as u32
187187
};
188188

189-
if initrd_max >= below_4g_mem_size - acpi_data_size {
190-
initrd_max = below_4g_mem_size - acpi_data_size - 1;
189+
if let Some(available_mem) = below_4g_mem_size.checked_sub(acpi_data_size) {
190+
if initrd_max >= available_mem {
191+
initrd_max = available_mem.saturating_sub(1);
192+
}
193+
} else {
194+
// If acpi_data_size >= below_4g_mem_size, we have no memory available
195+
bail!(
196+
"ACPI data size ({}) exceeds available memory ({})",
197+
acpi_data_size,
198+
below_4g_mem_size
199+
);
191200
}
192201
if initrd_size >= initrd_max {
193202
bail!("initrd is too large");
194203
}
195204

196-
let initrd_addr = (initrd_max - initrd_size) & !4095;
205+
let initrd_addr = initrd_max.saturating_sub(initrd_size) & !4095;
197206
kd[0x218..0x21C].copy_from_slice(&initrd_addr.to_le_bytes());
198207
kd[0x21C..0x220].copy_from_slice(&initrd_size.to_le_bytes());
199208
}

dstack-mr/src/tdvf.rs

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -82,20 +82,30 @@ impl<'a> Tdvf<'a> {
8282
const TABLE_FOOTER_GUID: &str = "96b582de-1fb2-45f7-baea-a366c55a082d";
8383
const BYTES_AFTER_TABLE_FOOTER: usize = 32;
8484

85+
if fw.len() < BYTES_AFTER_TABLE_FOOTER {
86+
bail!("TDVF firmware too small");
87+
}
8588
let offset = fw.len() - BYTES_AFTER_TABLE_FOOTER;
8689
let encoded_footer_guid = encode_guid(TABLE_FOOTER_GUID)?;
90+
if offset < 16 {
91+
bail!("TDVF firmware offset too small for GUID");
92+
}
8793
let guid = &fw[offset - 16..offset];
8894

8995
if guid != encoded_footer_guid {
9096
bail!("Failed to parse TDVF metadata: Invalid footer GUID");
9197
}
9298

99+
if offset < 18 {
100+
bail!("TDVF firmware offset too small for tables length");
101+
}
93102
let tables_len =
94103
u16::from_le_bytes(fw[offset - 18..offset - 16].try_into().unwrap()) as usize;
95-
if tables_len == 0 || tables_len > offset - 18 {
104+
if tables_len == 0 || tables_len > offset.saturating_sub(18) {
96105
bail!("Failed to parse TDVF metadata: Invalid tables length");
97106
}
98-
let tables = &fw[offset - 18 - tables_len..offset - 18];
107+
let table_start = offset.saturating_sub(18).saturating_sub(tables_len);
108+
let tables = &fw[table_start..offset - 18];
99109
let mut offset = tables.len();
100110

101111
let mut data: Option<&[u8]> = None;
@@ -106,21 +116,28 @@ impl<'a> Tdvf<'a> {
106116
}
107117
let guid = &tables[offset - 16..offset];
108118
let entry_len = read_le::<u16>(tables, offset - 18, "entry length")? as usize;
109-
if entry_len > offset - 18 {
119+
if entry_len > offset.saturating_sub(18) {
110120
bail!("Failed to parse TDVF metadata: Invalid entry length");
111121
}
112122
if guid == encoded_guid {
113-
data = Some(&tables[offset - 18 - entry_len..offset - 18]);
123+
let entry_start = offset.saturating_sub(18).saturating_sub(entry_len);
124+
data = Some(&tables[entry_start..offset - 18]);
114125
break;
115126
}
116-
offset -= entry_len;
127+
offset = offset.saturating_sub(entry_len);
117128
}
118129

119130
let data = data.context("Failed to parse TDVF metadata: Missing TDVF metadata")?;
120131

121-
let tdvf_meta_offset =
132+
if data.len() < 4 {
133+
bail!("TDVF metadata data too small");
134+
}
135+
let tdvf_meta_offset_raw =
122136
u32::from_le_bytes(data[data.len() - 4..].try_into().unwrap()) as usize;
123-
let tdvf_meta_offset = fw.len() - tdvf_meta_offset;
137+
if tdvf_meta_offset_raw > fw.len() {
138+
bail!("TDVF metadata offset exceeds firmware size");
139+
}
140+
let tdvf_meta_offset = fw.len() - tdvf_meta_offset_raw;
124141
let tdvf_meta_desc = &fw[tdvf_meta_offset..tdvf_meta_offset + 16];
125142

126143
if &tdvf_meta_desc[..4] != b"TDVF" {
@@ -311,16 +328,27 @@ impl<'a> Tdvf<'a> {
311328
let (_, last_start, last_end) = memory_acceptor.ranges.pop().expect("No ranges");
312329

313330
for (accepted, start, end) in memory_acceptor.ranges {
331+
if end < start {
332+
bail!("Invalid memory range: end < start");
333+
}
334+
let size = end - start;
314335
if accepted {
315-
add_memory_resource_hob(0x00, start, end - start);
336+
add_memory_resource_hob(0x00, start, size);
316337
} else {
317-
add_memory_resource_hob(0x07, start, end - start);
338+
add_memory_resource_hob(0x07, start, size);
318339
}
319340
}
320341

342+
if last_end < last_start {
343+
bail!("Invalid last memory range: end < start");
344+
}
321345
if memory_size >= 0xB0000000 {
322-
add_memory_resource_hob(0x07, last_start, 0x80000000u64 - last_start);
323-
add_memory_resource_hob(0x07, 0x100000000, last_end - 0x80000000u64);
346+
if last_start < 0x80000000u64 {
347+
add_memory_resource_hob(0x07, last_start, 0x80000000u64 - last_start);
348+
}
349+
if last_end > 0x80000000u64 {
350+
add_memory_resource_hob(0x07, 0x100000000, last_end - 0x80000000u64);
351+
}
324352
} else {
325353
add_memory_resource_hob(0x07, last_start, last_end - last_start);
326354
}

0 commit comments

Comments
 (0)