Skip to content

Commit cf89a8a

Browse files
bchaliosroypat
authored andcommitted
fix: potential underflow in AML bytecode creation
acpi_tables::aml::AddressSpace<T> type is describing an address space with a minimum address `min: T` and a maximum address `max: T`. Currently, we do not perform any checks on these values when creating the AddressSpace objects. This means that the starting address `min` can be bigger than the last address `max`, which can cause underflows when calculating the length of this address space, i.e. `max - min + 1`. Add a check in the constructor methods of AddressSpace objects and return an error when `min > max`. Signed-off-by: Babis Chalios <[email protected]>
1 parent c9009f1 commit cf89a8a

File tree

1 file changed

+42
-17
lines changed

1 file changed

+42
-17
lines changed

src/acpi-tables/src/aml.rs

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ pub enum AmlError {
1414
NameEmpty,
1515
/// Invalid name part length
1616
InvalidPartLength,
17+
/// Invalid address range
18+
AddressRange,
1719
}
1820

1921
pub trait Aml {
@@ -420,32 +422,49 @@ pub struct AddressSpace<T> {
420422
type_flags: u8,
421423
}
422424

423-
impl<T> AddressSpace<T> {
424-
pub fn new_memory(cacheable: AddressSpaceCacheable, read_write: bool, min: T, max: T) -> Self {
425-
AddressSpace {
425+
impl<T> AddressSpace<T>
426+
where
427+
T: PartialOrd,
428+
{
429+
pub fn new_memory(
430+
cacheable: AddressSpaceCacheable,
431+
read_write: bool,
432+
min: T,
433+
max: T,
434+
) -> Result<Self, AmlError> {
435+
if min > max {
436+
return Err(AmlError::AddressRange);
437+
}
438+
Ok(AddressSpace {
426439
r#type: AddressSpaceType::Memory,
427440
min,
428441
max,
429442
type_flags: (cacheable as u8) << 1 | u8::from(read_write),
430-
}
443+
})
431444
}
432445

433-
pub fn new_io(min: T, max: T) -> Self {
434-
AddressSpace {
446+
pub fn new_io(min: T, max: T) -> Result<Self, AmlError> {
447+
if min > max {
448+
return Err(AmlError::AddressRange);
449+
}
450+
Ok(AddressSpace {
435451
r#type: AddressSpaceType::Io,
436452
min,
437453
max,
438454
type_flags: 3, // EntireRange
439-
}
455+
})
440456
}
441457

442-
pub fn new_bus_number(min: T, max: T) -> Self {
443-
AddressSpace {
458+
pub fn new_bus_number(min: T, max: T) -> Result<Self, AmlError> {
459+
if min > max {
460+
return Err(AmlError::AddressRange);
461+
}
462+
Ok(AddressSpace {
444463
r#type: AddressSpaceType::BusNumber,
445464
min,
446465
max,
447466
type_flags: 0,
448-
}
467+
})
449468
}
450469

451470
fn push_header(&self, bytes: &mut Vec<u8>, descriptor: u8, length: usize) {
@@ -1340,7 +1359,9 @@ mod tests {
13401359
assert_eq!(
13411360
Name::new(
13421361
"_CRS".try_into().unwrap(),
1343-
&ResourceTemplate::new(vec![&AddressSpace::new_bus_number(0x0u16, 0xffu16),])
1362+
&ResourceTemplate::new(vec![
1363+
&AddressSpace::new_bus_number(0x0u16, 0xffu16).unwrap(),
1364+
])
13441365
)
13451366
.unwrap()
13461367
.to_aml_bytes()
@@ -1360,8 +1381,8 @@ mod tests {
13601381
Name::new(
13611382
"_CRS".try_into().unwrap(),
13621383
&ResourceTemplate::new(vec![
1363-
&AddressSpace::new_io(0x0u16, 0xcf7u16),
1364-
&AddressSpace::new_io(0xd00u16, 0xffffu16),
1384+
&AddressSpace::new_io(0x0u16, 0xcf7u16).unwrap(),
1385+
&AddressSpace::new_io(0xd00u16, 0xffffu16).unwrap(),
13651386
])
13661387
)
13671388
.unwrap()
@@ -1388,13 +1409,15 @@ mod tests {
13881409
true,
13891410
0xa_0000u32,
13901411
0xb_ffffu32
1391-
),
1412+
)
1413+
.unwrap(),
13921414
&AddressSpace::new_memory(
13931415
AddressSpaceCacheable::NotCacheable,
13941416
true,
13951417
0xc000_0000u32,
13961418
0xfebf_ffffu32
1397-
),
1419+
)
1420+
.unwrap(),
13981421
])
13991422
)
14001423
.unwrap()
@@ -1420,7 +1443,8 @@ mod tests {
14201443
true,
14211444
0x8_0000_0000u64,
14221445
0xf_ffff_ffffu64
1423-
)])
1446+
)
1447+
.unwrap()])
14241448
)
14251449
.unwrap()
14261450
.to_aml_bytes()
@@ -1988,7 +2012,8 @@ mod tests {
19882012
true,
19892013
0x0000_0000_0000_0000u64,
19902014
0xFFFF_FFFF_FFFF_FFFEu64
1991-
)])
2015+
)
2016+
.unwrap()])
19922017
)
19932018
.unwrap(),
19942019
&CreateField::<u64>::new(

0 commit comments

Comments
 (0)