Skip to content

Commit 34b0516

Browse files
committed
aarch64: Verify alignment of load base address
According to https://www.kernel.org/doc/Documentation/arm64/booting.txt: "The Image must be placed text_offset bytes from a 2MB aligned base address anywhere in usable system RAM and called there." For the aarch64 case, the kernel_offset parameter allows a VMM to specify the desired base address at which to load the image in guest memory, while text_offset is contained in the Image header. Ensure that the base address requested by the VMM meets the 2 MB alignment requirement. Signed-off-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com>
1 parent 0de8918 commit 34b0516

File tree

2 files changed

+21
-2
lines changed

2 files changed

+21
-2
lines changed

coverage_config_aarch64.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"coverage_score": 80.8,
2+
"coverage_score": 80.7,
33
"exclude_path": "",
44
"crate_features": "pe"
55
}

src/loader/aarch64/pe/mod.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ pub enum Error {
4848
InvalidImage,
4949
/// Invalid Image magic number.
5050
InvalidImageMagicNumber,
51+
/// Invalid base address alignment
52+
InvalidBaseAddrAlignment,
5153
}
5254

5355
impl error::Error for Error {
@@ -63,6 +65,7 @@ impl error::Error for Error {
6365
Error::InvalidImageMagicNumber => "Invalid Image magic number",
6466
Error::DtbTooBig => "Device tree image too big",
6567
Error::ReadKernelImage => "Unable to read kernel image",
68+
Error::InvalidBaseAddrAlignment => "Base address not aligned to 2 MB",
6669
}
6770
}
6871
}
@@ -96,7 +99,7 @@ impl KernelLoader for PE {
9699
/// # Arguments
97100
///
98101
/// * `guest_mem` - The guest memory where the kernel image is loaded.
99-
/// * `kernel_offset` - 2MB-aligned base addres in guest memory at at which to load the kernel.
102+
/// * `kernel_offset` - 2MB-aligned base addres in guest memory at which to load the kernel.
100103
/// * `kernel_image` - Input Image format kernel image.
101104
/// * `highmem_start_address` - ignored on ARM64.
102105
///
@@ -135,6 +138,14 @@ impl KernelLoader for PE {
135138
text_offset = 0x80000;
136139
}
137140

141+
// Validate that kernel_offset is 2 MB aligned, as required by the
142+
// arm64 boot protocol
143+
if let Some(kernel_offset) = kernel_offset {
144+
if kernel_offset.raw_value() % 0x0020_0000 != 0 {
145+
return Err(Error::InvalidBaseAddrAlignment.into());
146+
}
147+
}
148+
138149
let mem_offset = kernel_offset
139150
.unwrap_or(GuestAddress(0))
140151
.checked_add(text_offset)
@@ -218,6 +229,14 @@ mod tests {
218229
assert_eq!(loader_result.kernel_load.raw_value(), 0x280000);
219230
assert_eq!(loader_result.kernel_end, 0x281000);
220231

232+
// Attempt to load the kernel at an address that is not aligned to 2MB boundary
233+
let kernel_offset = GuestAddress(0x0030_0000);
234+
let loader_result = PE::load(&gm, Some(kernel_offset), &mut Cursor::new(&image), None);
235+
assert_eq!(
236+
loader_result,
237+
Err(KernelLoaderError::Pe(Error::InvalidBaseAddrAlignment))
238+
);
239+
221240
image[0x39] = 0x0;
222241
let loader_result = PE::load(&gm, Some(kernel_addr), &mut Cursor::new(&image), None);
223242
assert_eq!(

0 commit comments

Comments
 (0)