From esk@ira.uka.de  Mon Jun 17 06:01:22 2002
Return-Path: <esk@ira.uka.de>
Received: from iraun2.uka.de (iraun2.uka.de [129.13.10.91])
	by hub.freebsd.org (Postfix) with ESMTP id C30B537B40D
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 17 Jun 2002 06:01:21 -0700 (PDT)
Received: from i30nb20.ira.uka.de ([129.13.30.70])
	by iraun2.uka.de with esmtp (Exim 3.30 #7 (Debian))
	id 17Jw8G-0002V0-01
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 17 Jun 2002 15:01:20 +0200
Received: from i30nb20.ira.uka.de (localhost [127.0.0.1])
	by i30nb20.ira.uka.de (8.12.3/8.12.3) with ESMTP id g5EKWwMK016169
	for <FreeBSD-gnats-submit@freebsd.org>; Fri, 14 Jun 2002 22:32:58 +0200 (CEST)
	(envelope-from esk@i30nb20.ira.uka.de)
Received: (from esk@localhost)
	by i30nb20.ira.uka.de (8.12.3/8.12.3/Submit) id g5EKWwk2016168;
	Fri, 14 Jun 2002 22:32:58 +0200 (CEST)
Message-Id: <200206142032.g5EKWwk2016168@i30nb20.ira.uka.de>
Date: Fri, 14 Jun 2002 22:32:58 +0200 (CEST)
From: Espen Skoglund <esk@ira.uka.de>
Reply-To: esk@ira.uka.de
To: FreeBSD-gnats-submit@freebsd.org
Subject: Bootloader assuming 8KB buffer when only 4KB is allocated
X-Send-Pr-Version: 3.2

>Number:         39415
>Category:       ia64
>Synopsis:       Bootloader assuming 8KB buffer when only 4KB is allocated
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-ia64
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Jun 17 06:10:01 PDT 2002
>Closed-Date:    Thu Oct 24 00:55:49 PDT 2002
>Last-Modified:  Thu Oct 24 00:55:49 PDT 2002
>Originator:     Espen Skoglund
>Release:        FreeBSD 5.0-CURRENT ia64
>Organization:
Karlsruhe University
>Environment:


>Description:

The AllocatePages() call in sys/boot/efi/libefi/elf_freebsd.c only
allocate one 4KB page.  The bi_load() in sys/boot/efi/libefi/bootinfo.c,
however, assumes that 8KB has been allocated when stashing the EFI memory
map behind the bootinfo.  This could lead to "interesting" behaviour
in certain (albeit probably unlikely) scenarios.

>How-To-Repeat:


>Fix:

Make sure that 8KB are allocated instead of only 4KB.

--- elf_freebsd.c.orig	Fri Jun 14 22:21:42 2002
+++ elf_freebsd.c	Fri Jun 14 22:22:13 2002
@@ -151,7 +151,7 @@
 	hdr = (Elf_Ehdr *)&(md->md_data);
 
 	status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData,
-	    EFI_SIZE_TO_PAGES(sizeof(struct bootinfo)), (void*)&bi);
+				   8192/4096, (void*)&bi);
 	if (EFI_ERROR(status)) {
 		printf("unable to create bootinfo block (status=0x%lx)\n",
 		    (long)status);
>Release-Note:
>Audit-Trail:

From: Marcel Moolenaar <marcel@xcllnt.net>
To: Espen Skoglund <esk@ira.uka.de>
Cc: FreeBSD-gnats-submit@FreeBSD.ORG
Subject: Re: ia64/39415: Bootloader assuming 8KB buffer when only 4KB is allocated
Date: Tue, 18 Jun 2002 21:10:23 -0700

 On Fri, Jun 14, 2002 at 10:32:58PM +0200, Espen Skoglund wrote:
 > 
 > >Description:
 > 
 > The AllocatePages() call in sys/boot/efi/libefi/elf_freebsd.c only
 > allocate one 4KB page.  The bi_load() in sys/boot/efi/libefi/bootinfo.c,
 > however, assumes that 8KB has been allocated when stashing the EFI memory
 > map behind the bootinfo.  This could lead to "interesting" behaviour
 > in certain (albeit probably unlikely) scenarios.
 
 Espen,
 
 It looks to me that rounding to a multiple of the EFI page size is
 more natural for an EFI application. I would probably fix bootinfo.c
 instead of elf_freebsd.c. A second reason for fixing bootinfo.c is
 that elf_freebsd.c works with arbitrary large bootinfo blocks, while
 bootinfo.c only works if the bootinfo block is smaller than 8KB.
 
 A second order fix would be to allocate enough; not just for the
 bootinfo blocks, but also for the memory map...
 
 Thoughts?
 
 -- 
  Marcel Moolenaar	  USPA: A-39004		 marcel@xcllnt.net

From: Espen Skoglund <esk@ira.uka.de>
To: Marcel Moolenaar <marcel@xcllnt.net>
Cc: Espen Skoglund <esk@ira.uka.de>, FreeBSD-gnats-submit@FreeBSD.ORG
Subject: Re: ia64/39415: Bootloader assuming 8KB buffer when only 4KB is allocated
Date: Wed, 19 Jun 2002 21:29:23 +0200

 [Marcel Moolenaar]
 > It looks to me that rounding to a multiple of the EFI page size is
 > more natural for an EFI application. I would probably fix bootinfo.c
 > instead of elf_freebsd.c. A second reason for fixing bootinfo.c is
 > that elf_freebsd.c works with arbitrary large bootinfo blocks, while
 > bootinfo.c only works if the bootinfo block is smaller than 8KB.
 
 > A second order fix would be to allocate enough; not just for the
 > bootinfo blocks, but also for the memory map...
 
 > Thoughts?
 
 You're right.  It makes more sense to fix it properly.  Here's a
 better fix.  It gets the size of the memmap and uses it for
 determining the allocation size.  The size of the allocated memory
 behind the bootinfo is then passed on to bootinfo.c (the size of
 memmap itself is not passed since it may increase due to an
 AllocatePages() call).
 
 	eSk
 
 
 ================================================================
 --- elf_freebsd.c.orig	Wed Jun 19 21:14:43 2002
 +++ elf_freebsd.c	Wed Jun 19 21:16:04 2002
 @@ -143,15 +143,22 @@
  	struct ia64_pte		pte;
  	struct bootinfo		*bi;
  	u_int64_t		psr;
 -	UINTN			mapkey;
 +	UINTN			mapkey, size, dummy1;
 +	UINT32			dummy2;
  	EFI_STATUS		status;
  
  	if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
  		return(EFTYPE);			/* XXX actually EFUCKUP */
  	hdr = (Elf_Ehdr *)&(md->md_data);
  
 +	/* Get size of EFI memory map */
 +	size = 0;
 +	BS->GetMemoryMap(&size, (EFI_MEMORY_DESCRIPTOR *)&dummy1,
 +			 &mapkey, &dummy1, &dummy2);
 +
 +	size = EFI_SIZE_TO_PAGES(sizeof(struct bootinfo) + size);
  	status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData,
 -	    EFI_SIZE_TO_PAGES(sizeof(struct bootinfo)), (void*)&bi);
 +				   size, (void*)&bi);
  	if (EFI_ERROR(status)) {
  		printf("unable to create bootinfo block (status=0x%lx)\n",
  		    (long)status);
 @@ -159,7 +166,8 @@
  	}
  
  	bzero(bi, sizeof(struct bootinfo));
 -	bi_load(bi, fp, &mapkey);
 +	bi_load(bi, fp, &mapkey,
 +		(size << EFI_PAGE_SHIFT) - sizeof(struct bootinfo));
  
  	printf("Entering %s at 0x%lx...\n", fp->f_name, hdr->e_entry);
  
 --- bootinfo.c.orig	Wed Jun 19 21:14:50 2002
 +++ bootinfo.c	Wed Jun 19 21:15:46 2002
 @@ -242,7 +242,8 @@
   * - Module metadata are formatted and placed in kernel space.
   */
  int
 -bi_load(struct bootinfo *bi, struct preloaded_file *fp, UINTN *mapkey)
 +bi_load(struct bootinfo *bi, struct preloaded_file *fp, UINTN *mapkey,
 +	UINTN alloced_size)
  {
      char			*rootdevname;
      struct efi_devdesc		*rootdev;
 @@ -331,7 +332,7 @@
  
      /* read memory map and stash it after bootinfo */
      bi->bi_memmap = (u_int64_t)(bi + 1);
 -    bi->bi_memmap_size = 8192 - sizeof(struct bootinfo);
 +    bi->bi_memmap_size = alloced_size;
      status = BS->GetMemoryMap(&bi->bi_memmap_size,
  			      (EFI_MEMORY_DESCRIPTOR *)bi->bi_memmap,
  			      &key,
State-Changed-From-To: open->closed 
State-Changed-By: marcel 
State-Changed-When: Thu Oct 24 00:52:17 PDT 2002 
State-Changed-Why:  
Fixed. Patch applied with modifications. An additional problem was 
that optaining the size of the memory map before doing an additional 
allocation could cause the previously obtained size to be too small 
to actually hold the memory map after the allocation. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=39415 
>Unformatted:
