Skip to content

Commit d2885ea

Browse files
aljimenezbalxiord
authored andcommitted
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. Related to #12 Signed-off-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com>
1 parent c1aad5f commit d2885ea

File tree

2 files changed

+22
-2
lines changed

2 files changed

+22
-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: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// Copyright © 2020, Oracle and/or its affiliates.
12
// Copyright (c) 2019 Intel Corporation. All rights reserved.
23
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
34
//
@@ -48,6 +49,8 @@ pub enum Error {
4849
InvalidImage,
4950
/// Invalid Image magic number.
5051
InvalidImageMagicNumber,
52+
/// Invalid base address alignment
53+
InvalidBaseAddrAlignment,
5154
}
5255

5356
impl error::Error for Error {
@@ -63,6 +66,7 @@ impl error::Error for Error {
6366
Error::InvalidImageMagicNumber => "Invalid Image magic number",
6467
Error::DtbTooBig => "Device tree image too big",
6568
Error::ReadKernelImage => "Unable to read kernel image",
69+
Error::InvalidBaseAddrAlignment => "Base address not aligned to 2 MB",
6670
}
6771
}
6872
}
@@ -96,7 +100,7 @@ impl KernelLoader for PE {
96100
/// # Arguments
97101
///
98102
/// * `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.
103+
/// * `kernel_offset` - 2MB-aligned base addres in guest memory at which to load the kernel.
100104
/// * `kernel_image` - Input Image format kernel image.
101105
/// * `highmem_start_address` - ignored on ARM64.
102106
///
@@ -135,6 +139,14 @@ impl KernelLoader for PE {
135139
text_offset = 0x80000;
136140
}
137141

142+
// Validate that kernel_offset is 2 MB aligned, as required by the
143+
// arm64 boot protocol
144+
if let Some(kernel_offset) = kernel_offset {
145+
if kernel_offset.raw_value() % 0x0020_0000 != 0 {
146+
return Err(Error::InvalidBaseAddrAlignment.into());
147+
}
148+
}
149+
138150
let mem_offset = kernel_offset
139151
.unwrap_or(GuestAddress(0))
140152
.checked_add(text_offset)
@@ -218,6 +230,14 @@ mod tests {
218230
assert_eq!(loader_result.kernel_load.raw_value(), 0x280000);
219231
assert_eq!(loader_result.kernel_end, 0x281000);
220232

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

0 commit comments

Comments
 (0)