[nbi] Remove userptr_t from NBI image parsing

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2025-04-24 23:17:16 +01:00
parent 3cb33435f5
commit 0edbc4c082

View File

@@ -106,7 +106,7 @@ struct ebinfo {
* @ret rc Return status code * @ret rc Return status code
*/ */
static int nbi_prepare_segment ( struct image *image, size_t offset __unused, static int nbi_prepare_segment ( struct image *image, size_t offset __unused,
userptr_t dest, size_t filesz, size_t memsz ){ void *dest, size_t filesz, size_t memsz ) {
int rc; int rc;
if ( ( rc = prep_segment ( dest, filesz, memsz ) ) != 0 ) { if ( ( rc = prep_segment ( dest, filesz, memsz ) ) != 0 ) {
@@ -129,7 +129,7 @@ static int nbi_prepare_segment ( struct image *image, size_t offset __unused,
* @ret rc Return status code * @ret rc Return status code
*/ */
static int nbi_load_segment ( struct image *image, size_t offset, static int nbi_load_segment ( struct image *image, size_t offset,
userptr_t dest, size_t filesz, void *dest, size_t filesz,
size_t memsz __unused ) { size_t memsz __unused ) {
memcpy ( dest, ( image->data + offset ), filesz ); memcpy ( dest, ( image->data + offset ), filesz );
return 0; return 0;
@@ -144,16 +144,16 @@ static int nbi_load_segment ( struct image *image, size_t offset,
* @ret rc Return status code * @ret rc Return status code
*/ */
static int nbi_process_segments ( struct image *image, static int nbi_process_segments ( struct image *image,
struct imgheader *imgheader, const struct imgheader *imgheader,
int ( * process ) ( struct image *image, int ( * process ) ( struct image *image,
size_t offset, size_t offset,
userptr_t dest, void *dest,
size_t filesz, size_t filesz,
size_t memsz ) ) { size_t memsz ) ) {
struct segheader sh; const struct segheader *sh;
size_t offset = 0; size_t offset = 0;
size_t sh_off; size_t sh_off;
userptr_t dest; void *dest;
size_t filesz; size_t filesz;
size_t memsz; size_t memsz;
int rc; int rc;
@@ -170,8 +170,8 @@ static int nbi_process_segments ( struct image *image,
sh_off = NBI_LENGTH ( imgheader->length ); sh_off = NBI_LENGTH ( imgheader->length );
do { do {
/* Read segment header */ /* Read segment header */
copy_from_user ( &sh, image->data, sh_off, sizeof ( sh ) ); sh = ( image->data + sh_off );
if ( sh.length == 0 ) { if ( sh->length == 0 ) {
/* Avoid infinite loop? */ /* Avoid infinite loop? */
DBGC ( image, "NBI %p invalid segheader length 0\n", DBGC ( image, "NBI %p invalid segheader length 0\n",
image ); image );
@@ -179,15 +179,15 @@ static int nbi_process_segments ( struct image *image,
} }
/* Calculate segment load address */ /* Calculate segment load address */
switch ( NBI_LOADADDR_FLAGS ( sh.flags ) ) { switch ( NBI_LOADADDR_FLAGS ( sh->flags ) ) {
case NBI_LOADADDR_ABS: case NBI_LOADADDR_ABS:
dest = phys_to_virt ( sh.loadaddr ); dest = phys_to_virt ( sh->loadaddr );
break; break;
case NBI_LOADADDR_AFTER: case NBI_LOADADDR_AFTER:
dest = ( dest + memsz + sh.loadaddr ); dest = ( dest + memsz + sh->loadaddr );
break; break;
case NBI_LOADADDR_BEFORE: case NBI_LOADADDR_BEFORE:
dest = ( dest - sh.loadaddr ); dest = ( dest - sh->loadaddr );
break; break;
case NBI_LOADADDR_END: case NBI_LOADADDR_END:
/* Not correct according to the spec, but /* Not correct according to the spec, but
@@ -195,7 +195,7 @@ static int nbi_process_segments ( struct image *image,
* previous versions of Etherboot. * previous versions of Etherboot.
*/ */
dest = phys_to_virt ( ( extmemsize() + 1024 ) * 1024 dest = phys_to_virt ( ( extmemsize() + 1024 ) * 1024
- sh.loadaddr ); - sh->loadaddr );
break; break;
default: default:
/* Cannot be reached */ /* Cannot be reached */
@@ -203,8 +203,8 @@ static int nbi_process_segments ( struct image *image,
} }
/* Process this segment */ /* Process this segment */
filesz = sh.imglength; filesz = sh->imglength;
memsz = sh.memlength; memsz = sh->memlength;
if ( ( offset + filesz ) > image->len ) { if ( ( offset + filesz ) > image->len ) {
DBGC ( image, "NBI %p segment outside file\n", image ); DBGC ( image, "NBI %p segment outside file\n", image );
return -ENOEXEC; return -ENOEXEC;
@@ -216,13 +216,13 @@ static int nbi_process_segments ( struct image *image,
offset += filesz; offset += filesz;
/* Next segheader */ /* Next segheader */
sh_off += NBI_LENGTH ( sh.length ); sh_off += NBI_LENGTH ( sh->length );
if ( sh_off >= NBI_HEADER_LENGTH ) { if ( sh_off >= NBI_HEADER_LENGTH ) {
DBGC ( image, "NBI %p header overflow\n", image ); DBGC ( image, "NBI %p header overflow\n", image );
return -ENOEXEC; return -ENOEXEC;
} }
} while ( ! NBI_LAST_SEGHEADER ( sh.flags ) ); } while ( ! NBI_LAST_SEGHEADER ( sh->flags ) );
if ( offset != image->len ) { if ( offset != image->len ) {
DBGC ( image, "NBI %p length wrong (file %zd, metadata %zd)\n", DBGC ( image, "NBI %p length wrong (file %zd, metadata %zd)\n",
@@ -239,7 +239,8 @@ static int nbi_process_segments ( struct image *image,
* @v imgheader Image header information * @v imgheader Image header information
* @ret rc Return status code, if image returns * @ret rc Return status code, if image returns
*/ */
static int nbi_boot16 ( struct image *image, struct imgheader *imgheader ) { static int nbi_boot16 ( struct image *image,
const struct imgheader *imgheader ) {
int discard_D, discard_S, discard_b; int discard_D, discard_S, discard_b;
int32_t rc; int32_t rc;
@@ -277,7 +278,8 @@ static int nbi_boot16 ( struct image *image, struct imgheader *imgheader ) {
* @v imgheader Image header information * @v imgheader Image header information
* @ret rc Return status code, if image returns * @ret rc Return status code, if image returns
*/ */
static int nbi_boot32 ( struct image *image, struct imgheader *imgheader ) { static int nbi_boot32 ( struct image *image,
const struct imgheader *imgheader ) {
struct ebinfo loaderinfo = { struct ebinfo loaderinfo = {
product_major_version, product_minor_version, product_major_version, product_minor_version,
0 0
@@ -342,15 +344,15 @@ static int nbi_prepare_dhcp ( struct image *image ) {
* @ret rc Return status code * @ret rc Return status code
*/ */
static int nbi_exec ( struct image *image ) { static int nbi_exec ( struct image *image ) {
struct imgheader imgheader; const struct imgheader *imgheader;
int may_return; int may_return;
int rc; int rc;
/* Retrieve image header */ /* Retrieve image header */
copy_from_user ( &imgheader, image->data, 0, sizeof ( imgheader ) ); imgheader = image->data;
DBGC ( image, "NBI %p placing header at %hx:%hx\n", image, DBGC ( image, "NBI %p placing header at %hx:%hx\n", image,
imgheader.location.segment, imgheader.location.offset ); imgheader->location.segment, imgheader->location.offset );
/* NBI files can have overlaps between segments; the bss of /* NBI files can have overlaps between segments; the bss of
* one segment may overlap the initialised data of another. I * one segment may overlap the initialised data of another. I
@@ -359,10 +361,10 @@ static int nbi_exec ( struct image *image ) {
* passes: first to initialise the segments, then to copy the * passes: first to initialise the segments, then to copy the
* data. This avoids zeroing out already-copied data. * data. This avoids zeroing out already-copied data.
*/ */
if ( ( rc = nbi_process_segments ( image, &imgheader, if ( ( rc = nbi_process_segments ( image, imgheader,
nbi_prepare_segment ) ) != 0 ) nbi_prepare_segment ) ) != 0 )
return rc; return rc;
if ( ( rc = nbi_process_segments ( image, &imgheader, if ( ( rc = nbi_process_segments ( image, imgheader,
nbi_load_segment ) ) != 0 ) nbi_load_segment ) ) != 0 )
return rc; return rc;
@@ -371,15 +373,15 @@ static int nbi_exec ( struct image *image ) {
return rc; return rc;
/* Shut down now if NBI image will not return */ /* Shut down now if NBI image will not return */
may_return = NBI_PROGRAM_RETURNS ( imgheader.flags ); may_return = NBI_PROGRAM_RETURNS ( imgheader->flags );
if ( ! may_return ) if ( ! may_return )
shutdown_boot(); shutdown_boot();
/* Execute NBI image */ /* Execute NBI image */
if ( NBI_LINEAR_EXEC_ADDR ( imgheader.flags ) ) { if ( NBI_LINEAR_EXEC_ADDR ( imgheader->flags ) ) {
rc = nbi_boot32 ( image, &imgheader ); rc = nbi_boot32 ( image, imgheader );
} else { } else {
rc = nbi_boot16 ( image, &imgheader ); rc = nbi_boot16 ( image, imgheader );
} }
if ( ! may_return ) { if ( ! may_return ) {
@@ -401,17 +403,17 @@ static int nbi_exec ( struct image *image ) {
* @ret rc Return status code * @ret rc Return status code
*/ */
static int nbi_probe ( struct image *image ) { static int nbi_probe ( struct image *image ) {
struct imgheader imgheader; const struct imgheader *imgheader;
/* If we don't have enough data give up */ /* If we don't have enough data give up */
if ( image->len < NBI_HEADER_LENGTH ) { if ( image->len < NBI_HEADER_LENGTH ) {
DBGC ( image, "NBI %p too short for an NBI image\n", image ); DBGC ( image, "NBI %p too short for an NBI image\n", image );
return -ENOEXEC; return -ENOEXEC;
} }
imgheader = image->data;
/* Check image header */ /* Check image header */
copy_from_user ( &imgheader, image->data, 0, sizeof ( imgheader ) ); if ( imgheader->magic != NBI_MAGIC ) {
if ( imgheader.magic != NBI_MAGIC ) {
DBGC ( image, "NBI %p has no NBI signature\n", image ); DBGC ( image, "NBI %p has no NBI signature\n", image );
return -ENOEXEC; return -ENOEXEC;
} }