aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/boot
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2012-03-23 12:35:05 -0400
committerH. Peter Anvin <hpa@linux.intel.com>2012-03-26 16:10:01 -0400
commite31be363df3092821bf179cf4baa076f501b8ae6 (patch)
treee35eb913df39beebd30dfcf07a916c39f4dcd4f3 /arch/x86/boot
parent2e064b1e131eba262c0ba4268cb79dbc72edeece (diff)
x86, efi: Fix .text section overlapping image header for EFI_STUB
This change modifes the PE .text section to start after the first sector of the kernel image. The header may be modified by the UEFI secure boot signing, so it is not appropriate for it to be included in one of the image sections. Since the sections are part of the secure boot hash, this modification to the .text section contents would invalidate the secure boot signed hash. Note: UEFI secure boot does hash the image header, but fields that are changed by the signing process are excluded from the hash calculation. This exclusion process is only handled for the image header, and not image sections. Luckily, we can still easily boot without the first sector by initializing a few fields in arch/x86/boot/compressed/eboot.c. Signed-off-by: Matt Fleming <matt.fleming@intel.com> Link: http://lkml.kernel.org/r/1332520506-6472-3-git-send-email-jordan.l.justen@intel.com [jordan.l.justen@intel.com: set .text vma & file offset] Signed-off-by: Jordan Justen <jordan.l.justen@intel.com> Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'arch/x86/boot')
-rw-r--r--arch/x86/boot/compressed/eboot.c14
-rw-r--r--arch/x86/boot/header.S2
-rw-r--r--arch/x86/boot/tools/build.c25
3 files changed, 34 insertions, 7 deletions
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index fec216f4fbc3..01cbb8707a31 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -904,11 +904,19 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table)
904 904
905 memset(boot_params, 0x0, 0x4000); 905 memset(boot_params, 0x0, 0x4000);
906 906
907 /* Copy first two sectors to boot_params */
908 memcpy(boot_params, image->image_base, 1024);
909
910 hdr = &boot_params->hdr; 907 hdr = &boot_params->hdr;
911 908
909 /* Copy the second sector to boot_params */
910 memcpy(&hdr->jump, image->image_base + 512, 512);
911
912 /*
913 * Fill out some of the header fields ourselves because the
914 * EFI firmware loader doesn't load the first sector.
915 */
916 hdr->root_flags = 1;
917 hdr->vid_mode = 0xffff;
918 hdr->boot_flag = 0xAA55;
919
912 /* 920 /*
913 * The EFI firmware loader could have placed the kernel image 921 * The EFI firmware loader could have placed the kernel image
914 * anywhere in memory, but the kernel has various restrictions 922 * anywhere in memory, but the kernel has various restrictions
diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
index 4e9124b148c2..4ceb56e9a4ce 100644
--- a/arch/x86/boot/header.S
+++ b/arch/x86/boot/header.S
@@ -147,7 +147,7 @@ optional_header:
147 # Filled in by build.c 147 # Filled in by build.c
148 .long 0x0000 # AddressOfEntryPoint 148 .long 0x0000 # AddressOfEntryPoint
149 149
150 .long 0x0000 # BaseOfCode 150 .long 0x0200 # BaseOfCode
151#ifdef CONFIG_X86_32 151#ifdef CONFIG_X86_32
152 .long 0 # data 152 .long 0 # data
153#endif 153#endif
diff --git a/arch/x86/boot/tools/build.c b/arch/x86/boot/tools/build.c
index 4e9bd6bcafa6..2aeab3dc9e5f 100644
--- a/arch/x86/boot/tools/build.c
+++ b/arch/x86/boot/tools/build.c
@@ -202,12 +202,19 @@ int main(int argc, char ** argv)
202 202
203 pe_header = *(unsigned int *)&buf[0x3c]; 203 pe_header = *(unsigned int *)&buf[0x3c];
204 204
205 /* Size of code */
206 *(unsigned int *)&buf[pe_header + 0x1c] = file_sz;
207
208 /* Size of image */ 205 /* Size of image */
209 *(unsigned int *)&buf[pe_header + 0x50] = file_sz; 206 *(unsigned int *)&buf[pe_header + 0x50] = file_sz;
210 207
208 /*
209 * Subtract the size of the first section (512 bytes) which
210 * includes the header and .reloc section. The remaining size
211 * is that of the .text section.
212 */
213 file_sz -= 512;
214
215 /* Size of code */
216 *(unsigned int *)&buf[pe_header + 0x1c] = file_sz;
217
211#ifdef CONFIG_X86_32 218#ifdef CONFIG_X86_32
212 /* Address of entry point */ 219 /* Address of entry point */
213 *(unsigned int *)&buf[pe_header + 0x28] = i; 220 *(unsigned int *)&buf[pe_header + 0x28] = i;
@@ -215,8 +222,14 @@ int main(int argc, char ** argv)
215 /* .text size */ 222 /* .text size */
216 *(unsigned int *)&buf[pe_header + 0xb0] = file_sz; 223 *(unsigned int *)&buf[pe_header + 0xb0] = file_sz;
217 224
225 /* .text vma */
226 *(unsigned int *)&buf[pe_header + 0xb4] = 0x200;
227
218 /* .text size of initialised data */ 228 /* .text size of initialised data */
219 *(unsigned int *)&buf[pe_header + 0xb8] = file_sz; 229 *(unsigned int *)&buf[pe_header + 0xb8] = file_sz;
230
231 /* .text file offset */
232 *(unsigned int *)&buf[pe_header + 0xbc] = 0x200;
220#else 233#else
221 /* 234 /*
222 * Address of entry point. startup_32 is at the beginning and 235 * Address of entry point. startup_32 is at the beginning and
@@ -228,8 +241,14 @@ int main(int argc, char ** argv)
228 /* .text size */ 241 /* .text size */
229 *(unsigned int *)&buf[pe_header + 0xc0] = file_sz; 242 *(unsigned int *)&buf[pe_header + 0xc0] = file_sz;
230 243
244 /* .text vma */
245 *(unsigned int *)&buf[pe_header + 0xc4] = 0x200;
246
231 /* .text size of initialised data */ 247 /* .text size of initialised data */
232 *(unsigned int *)&buf[pe_header + 0xc8] = file_sz; 248 *(unsigned int *)&buf[pe_header + 0xc8] = file_sz;
249
250 /* .text file offset */
251 *(unsigned int *)&buf[pe_header + 0xcc] = 0x200;
233#endif /* CONFIG_X86_32 */ 252#endif /* CONFIG_X86_32 */
234#endif /* CONFIG_EFI_STUB */ 253#endif /* CONFIG_EFI_STUB */
235 254