mirror of
https://github.com/ipxe/ipxe
synced 2025-12-28 18:42:53 +03:00
[image] Use memmap_describe() to check loadable image segments
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -33,7 +33,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ipxe/uaccess.h>
|
||||
#include <ipxe/io.h>
|
||||
#include <ipxe/memmap.h>
|
||||
#include <ipxe/errortab.h>
|
||||
#include <ipxe/segment.h>
|
||||
|
||||
@@ -59,38 +59,45 @@ struct errortab segment_errors[] __errortab = {
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int prep_segment ( void *segment, size_t filesz, size_t memsz ) {
|
||||
struct memory_map memmap;
|
||||
struct memmap_region region;
|
||||
physaddr_t start = virt_to_phys ( segment );
|
||||
physaddr_t mid = ( start + filesz );
|
||||
physaddr_t end = ( start + memsz );
|
||||
unsigned int i;
|
||||
physaddr_t last;
|
||||
|
||||
DBG ( "Preparing segment [%lx,%lx,%lx)\n", start, mid, end );
|
||||
DBGC ( ®ion, "SEGMENT [%#08lx,%#08lx,%#08lx)\n", start, mid, end );
|
||||
|
||||
/* Sanity check */
|
||||
/* Check for malformed lengths */
|
||||
if ( filesz > memsz ) {
|
||||
DBG ( "Insane segment [%lx,%lx,%lx)\n", start, mid, end );
|
||||
DBGC ( ®ion, "SEGMENT [%#08lx,%#08lx,%#08lx) is "
|
||||
"malformed\n", start, mid, end );
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Get a fresh memory map. This allows us to automatically
|
||||
* avoid treading on any regions that Etherboot is currently
|
||||
* editing out of the memory map.
|
||||
*/
|
||||
get_memmap ( &memmap );
|
||||
/* Zero-length segments do not need a memory region */
|
||||
if ( memsz == 0 )
|
||||
return 0;
|
||||
last = ( end - 1 );
|
||||
|
||||
/* Look for a suitable memory region */
|
||||
for ( i = 0 ; i < memmap.count ; i++ ) {
|
||||
if ( ( start >= memmap.regions[i].start ) &&
|
||||
( end <= memmap.regions[i].end ) ) {
|
||||
/* Found valid region: zero bss and return */
|
||||
memset ( ( segment + filesz ), 0, ( memsz - filesz ) );
|
||||
return 0;
|
||||
}
|
||||
/* Check for address space overflow */
|
||||
if ( last < start ) {
|
||||
DBGC ( ®ion, "SEGMENT [%#08lx,%#08lx,%#08lx) wraps "
|
||||
"around\n", start, mid, end );
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* No suitable memory region found */
|
||||
DBG ( "Segment [%lx,%lx,%lx) does not fit into available memory\n",
|
||||
start, mid, end );
|
||||
return -ERANGE_SEGMENT;
|
||||
/* Describe region containing this segment */
|
||||
memmap_describe ( start, 1, ®ion );
|
||||
memmap_dump ( ®ion );
|
||||
|
||||
/* Fail unless region is usable and sufficiently large */
|
||||
if ( ( ! memmap_is_usable ( ®ion ) ) || ( region.last < last ) ) {
|
||||
DBGC ( ®ion, "SEGMENT [%#08lx,%#08lx,%#08lx) does not fit "
|
||||
"into available memory\n", start, mid, end );
|
||||
return -ERANGE_SEGMENT;
|
||||
}
|
||||
|
||||
/* Found valid region: zero bss and return */
|
||||
memset ( ( segment + filesz ), 0, ( memsz - filesz ) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user