aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2011-08-18 18:44:22 +0100
committerMatt Fleming <matt.fleming@intel.com>2011-08-18 20:55:56 +0100
commitc7615edf9fe977f072f7ea3287884d36343761d2 (patch)
treed85e697a4154db04a4b111defda273403fe38ad7
parenta51c96f8d934c02dcf6fdec4e47905584d18f9f1 (diff)
downloadefilinux-c7615edf9fe977f072f7ea3287884d36343761d2.tar.gz
bzimage: Fix typecast bug on i386
Before 32-bit support we were playing fast and loose with casts. The problem was that we were casting away legimate warnings, such as the compiler telling us that the value it was storing into a variable to was too big to fit. emalloc() was a prime example, in various places we passed a pointer to a pointer as the third argument to emalloc which has type EFI_PHYSICALL_ADDRESS *, where EFI_PHYSICAL_ADDRESS is a 64-bit type, like so, emalloc(UINTN size, UINTN align, EFI_PHYSICAL_ADDRESS *addr) Then inside emalloc() we do, *addr = aligned; On 64-bit this is fine because, sizeof(void *) == sizeof(EFI_PHYSICAL_ADDRESS) but if we have a 32-bit pointer we attempt to store a 64-bit value into a 32-bit data type. This led to stack corruption when we passed the address of a pointer on the stack to emalloc(). Signed-off-by: Matt Fleming <matt.fleming@intel.com>
-rw-r--r--loaders/bzimage/bzimage.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/loaders/bzimage/bzimage.c b/loaders/bzimage/bzimage.c
index cab1431..335fc9e 100644
--- a/loaders/bzimage/bzimage.c
+++ b/loaders/bzimage/bzimage.c
@@ -56,7 +56,7 @@ EFI_STATUS
load_kernel(EFI_HANDLE image, CHAR16 *name, char *cmdline)
{
UINTN map_size, _map_size, map_key;
- EFI_PHYSICAL_ADDRESS kernel_start;
+ EFI_PHYSICAL_ADDRESS kernel_start, addr;
struct boot_params *boot_params;
EFI_MEMORY_DESCRIPTOR *map_buf;
struct e820_entry *e820_map;
@@ -155,11 +155,12 @@ load_kernel(EFI_HANDLE image, CHAR16 *name, char *cmdline)
goto out;
file_size(rdfile, &size);
- err = emalloc(size, 1, (EFI_PHYSICAL_ADDRESS *)&rd);
+ err = emalloc(size, 1, &addr);
if (err != EFI_SUCCESS) {
file_close(rdfile);
goto out;
}
+ rd = (void *)(UINTN)addr;
if ((UINT32)(UINT64)rd > buf->hdr.ramdisk_max) {
Print(L"ramdisk address is too high!\n");
@@ -204,10 +205,12 @@ load_kernel(EFI_HANDLE image, CHAR16 *name, char *cmdline)
*
* Max kernel size is 8MB
*/
- err = emalloc(16384, 1, (EFI_PHYSICAL_ADDRESS *)&boot_params);
+ err = emalloc(16384, 1, &addr);
if (err != EFI_SUCCESS)
goto out;
+ boot_params = (struct boot_params *)(UINTN)addr;
+
memset((void *)boot_params, 0x0, 16384);
/* Copy first two sectors to boot_params */
@@ -252,10 +255,11 @@ load_kernel(EFI_HANDLE image, CHAR16 *name, char *cmdline)
again:
_map_size = map_size;
- err = emalloc(map_size, 1, (EFI_PHYSICAL_ADDRESS *)&map_buf);
+ err = emalloc(map_size, 1, &addr);
if (err != EFI_SUCCESS)
goto out;
+ map_buf = (EFI_MEMORY_DESCRIPTOR *)(UINTN)addr;
size = 0x800000;
err = emalloc(size, buf->hdr.kernel_alignment, &kernel_start);
if (err != EFI_SUCCESS)