From: Michael Brown Date: Thu, 15 May 2025 22:02:06 +0000 (+0100) Subject: [image] Use memmap_describe() to check loadable image segments X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=25ab8f462978ee45abdf6b3a9bc0eee9872014ec;p=thirdparty%2Fipxe.git [image] Use memmap_describe() to check loadable image segments Signed-off-by: Michael Brown --- diff --git a/src/image/segment.c b/src/image/segment.c index 52272170a..848831ace 100644 --- a/src/image/segment.c +++ b/src/image/segment.c @@ -33,7 +33,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include #include #include -#include +#include #include #include @@ -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; + } + + /* 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; } - /* No suitable memory region found */ - DBG ( "Segment [%lx,%lx,%lx) 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; }