iPXE
Macros | Functions
efi_image.c File Reference
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <ipxe/efi/efi.h>
#include <ipxe/efi/efi_snp.h>
#include <ipxe/efi/efi_download.h>
#include <ipxe/efi/efi_file.h>
#include <ipxe/efi/efi_path.h>
#include <ipxe/efi/efi_strings.h>
#include <ipxe/efi/efi_wrap.h>
#include <ipxe/efi/efi_pxe.h>
#include <ipxe/efi/efi_driver.h>
#include <ipxe/efi/efi_image.h>
#include <ipxe/efi/efi_shim.h>
#include <ipxe/efi/efi_fdt.h>
#include <ipxe/image.h>
#include <ipxe/init.h>
#include <ipxe/features.h>
#include <ipxe/uri.h>
#include <ipxe/console.h>

Go to the source code of this file.

Macros

#define EINFO_EEFI_LOAD
 
#define EINFO_EEFI_LOAD_PROHIBITED
 
#define EEFI_LOAD_PROHIBITED   __einfo_error ( EINFO_EEFI_LOAD_PROHIBITED )
 
#define EEFI_LOAD(efirc)
 
#define EINFO_EEFI_START
 
#define EEFI_START(efirc)   EPLATFORM ( EINFO_EEFI_START, efirc )
 

Functions

 FILE_LICENCE (GPL2_OR_LATER)
 
 FILE_SECBOOT (PERMITTED)
 
 FEATURE (FEATURE_IMAGE, "EFI", DHCP_EB_FEATURE_EFI, 1)
 
static EFI_DEVICE_PATH_PROTOCOLefi_image_path (struct image *image, EFI_DEVICE_PATH_PROTOCOL *parent)
 Create device path for image. More...
 
static wchar_tefi_image_cmdline (struct image *image)
 Create command line for image. More...
 
__weak int efi_fdt_install (const char *cmdline __unused)
 Install EFI Flattened Device Tree table (when no FDT support is present) More...
 
__weak int efi_fdt_uninstall (void)
 Uninstall EFI Flattened Device Tree table (when no FDT support is present) More...
 
static int efi_image_exec (struct image *image)
 Execute EFI image. More...
 
static int efi_image_probe (struct image *image)
 Probe EFI image. More...
 
static int efi_pe_image_probe (struct image *image)
 Probe EFI PE image. More...
 
struct image_type efi_image_type [] __image_type (PROBE_NORMAL)
 EFI image types. More...
 

Macro Definition Documentation

◆ EINFO_EEFI_LOAD

#define EINFO_EEFI_LOAD
Value:
"Could not load image" )
#define EINFO_EPLATFORM
Platform-generated base error.
Definition: errno.h:692
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:181

Definition at line 48 of file efi_image.c.

◆ EINFO_EEFI_LOAD_PROHIBITED

#define EINFO_EEFI_LOAD_PROHIBITED
Value:
"Image prohibited by security policy" )
#define __einfo_platformify(einfo_base, platform, desc)
Declare platform-generated error.
Definition: errno.h:194
#define EINFO_EEFI_LOAD
Definition: efi_image.c:48
#define EFI_SECURITY_VIOLATION
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:141

Definition at line 51 of file efi_image.c.

◆ EEFI_LOAD_PROHIBITED

#define EEFI_LOAD_PROHIBITED   __einfo_error ( EINFO_EEFI_LOAD_PROHIBITED )

Definition at line 54 of file efi_image.c.

◆ EEFI_LOAD

#define EEFI_LOAD (   efirc)
Value:
#define EINFO_EEFI_LOAD
Definition: efi_image.c:48
#define EPLATFORM(einfo_base, platform,...)
Generate an error based on an external platform error code.
Definition: errno.h:249
#define EEFI_LOAD_PROHIBITED
Definition: efi_image.c:54

Definition at line 56 of file efi_image.c.

◆ EINFO_EEFI_START

#define EINFO_EEFI_START
Value:
"Could not start image" )
#define EINFO_EPLATFORM
Platform-generated base error.
Definition: errno.h:692
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:181

Definition at line 58 of file efi_image.c.

◆ EEFI_START

#define EEFI_START (   efirc)    EPLATFORM ( EINFO_EEFI_START, efirc )

Definition at line 61 of file efi_image.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER  )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED  )

◆ FEATURE()

FEATURE ( FEATURE_IMAGE  ,
"EFI"  ,
DHCP_EB_FEATURE_EFI  ,
 
)

◆ efi_image_path()

static EFI_DEVICE_PATH_PROTOCOL* efi_image_path ( struct image image,
EFI_DEVICE_PATH_PROTOCOL parent 
)
static

Create device path for image.

Parameters
imageEFI image
parentParent device path
Return values
pathDevice path, or NULL on failure

The caller must eventually free() the device path.

Definition at line 73 of file efi_image.c.

73  {
75  FILEPATH_DEVICE_PATH *filepath;
77  size_t name_len;
78  size_t prefix_len;
79  size_t filepath_len;
80  size_t len;
81 
82  /* Calculate device path lengths */
83  prefix_len = efi_path_len ( parent );
84  name_len = strlen ( image->name );
85  filepath_len = ( SIZE_OF_FILEPATH_DEVICE_PATH +
86  ( name_len + 1 /* NUL */ ) * sizeof ( wchar_t ) );
87  len = ( prefix_len + filepath_len + sizeof ( *end ) );
88 
89  /* Allocate device path */
90  path = zalloc ( len );
91  if ( ! path )
92  return NULL;
93 
94  /* Construct device path */
95  memcpy ( path, parent, prefix_len );
96  filepath = ( ( ( void * ) path ) + prefix_len );
97  filepath->Header.Type = MEDIA_DEVICE_PATH;
98  filepath->Header.SubType = MEDIA_FILEPATH_DP;
99  filepath->Header.Length[0] = ( filepath_len & 0xff );
100  filepath->Header.Length[1] = ( filepath_len >> 8 );
101  efi_snprintf ( filepath->PathName, ( name_len + 1 /* NUL */ ),
102  "%s", image->name );
103  end = ( ( ( void * ) filepath ) + filepath_len );
105 
106  return path;
107 }
size_t efi_path_len(EFI_DEVICE_PATH_PROTOCOL *path)
Find length of device path (excluding terminator)
Definition: efi_path.c:174
An executable image.
Definition: image.h:24
This protocol can be used on any device handle to obtain generic path/location information concerning...
Definition: DevicePath.h:46
CHAR16 PathName[1]
A NULL-terminated Path string including directory and file names.
Definition: DevicePath.h:1107
EFI_DEVICE_PATH_PROTOCOL Header
Definition: DevicePath.h:1103
static void efi_path_terminate(EFI_DEVICE_PATH_PROTOCOL *end)
Terminate device path.
Definition: efi_path.h:31
void * memcpy(void *dest, const void *src, size_t len) __nonnull
ring len
Length.
Definition: dwmac.h:231
int efi_snprintf(wchar_t *wbuf, size_t wsize, const char *fmt,...)
Write a formatted string to a buffer.
Definition: efi_strings.c:107
#define SIZE_OF_FILEPATH_DEVICE_PATH
Definition: DevicePath.h:1110
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:662
size_t strlen(const char *src)
Get length of string.
Definition: string.c:244
#define MEDIA_DEVICE_PATH
Definition: DevicePath.h:1012
UINT8 Length[2]
Specific Device Path data.
Definition: DevicePath.h:59
UINT8 SubType
Varies by Type 0xFF End Entire Device Path, or 0x01 End This Instance of a Device Path and start a ne...
Definition: DevicePath.h:54
uint32_t end
Ending offset.
Definition: netvsc.h:18
UINT8 Type
0x01 Hardware Device Path.
Definition: DevicePath.h:47
char * name
Name.
Definition: image.h:38
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
#define MEDIA_FILEPATH_DP
File Path Media Device Path SubType.
Definition: DevicePath.h:1101

References efi_path_len(), efi_path_terminate(), efi_snprintf(), end, FILEPATH_DEVICE_PATH::Header, len, EFI_DEVICE_PATH_PROTOCOL::Length, MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP, memcpy(), image::name, NULL, FILEPATH_DEVICE_PATH::PathName, SIZE_OF_FILEPATH_DEVICE_PATH, strlen(), EFI_DEVICE_PATH_PROTOCOL::SubType, EFI_DEVICE_PATH_PROTOCOL::Type, and zalloc().

Referenced by efi_image_exec().

◆ efi_image_cmdline()

static wchar_t* efi_image_cmdline ( struct image image)
static

Create command line for image.

Parameters
imageEFI image
Return values
cmdlineCommand line, or NULL on failure

Definition at line 115 of file efi_image.c.

115  {
116  wchar_t *cmdline;
117 
118  /* Allocate and construct command line */
119  if ( efi_asprintf ( &cmdline, "%s%s%s", image->name,
120  ( image->cmdline ? " " : "" ),
121  ( image->cmdline ? image->cmdline : "" ) ) < 0 ) {
122  return NULL;
123  }
124 
125  return cmdline;
126 }
An executable image.
Definition: image.h:24
char * cmdline
Command line to pass to image.
Definition: image.h:43
int efi_asprintf(wchar_t **wstrp, const char *fmt,...)
Write a formatted string to newly allocated memory.
Definition: efi_strings.c:189
uint32_t cmdline
Definition: multiboot.h:16
char * name
Name.
Definition: image.h:38
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322

References cmdline, image::cmdline, efi_asprintf(), image::name, and NULL.

Referenced by efi_image_exec().

◆ efi_fdt_install()

__weak int efi_fdt_install ( const char *cmdline  __unused)

Install EFI Flattened Device Tree table (when no FDT support is present)

Parameters
cmdlineCommand line, or NULL
Return values
rcReturn status code

Definition at line 134 of file efi_image.c.

134  {
135  return 0;
136 }

Referenced by efi_image_exec().

◆ efi_fdt_uninstall()

__weak int efi_fdt_uninstall ( void  )

Uninstall EFI Flattened Device Tree table (when no FDT support is present)

Return values
rcReturn status code

Definition at line 143 of file efi_image.c.

143  {
144  return 0;
145 }

Referenced by efi_image_exec().

◆ efi_image_exec()

static int efi_image_exec ( struct image image)
static

Execute EFI image.

Parameters
imageEFI image
Return values
rcReturn status code

Definition at line 153 of file efi_image.c.

153  {
155  struct efi_snp_device *snpdev;
158  struct image *shim;
159  struct image *exec;
163  wchar_t *cmdline;
164  unsigned int toggle;
165  EFI_STATUS efirc;
166  int rc;
167 
168  /* Find an appropriate device handle to use */
169  snpdev = last_opened_snpdev();
170  if ( ! snpdev ) {
171  DBGC ( image, "EFIIMAGE %s could not identify SNP device\n",
172  image->name );
173  rc = -ENODEV;
174  goto err_no_snpdev;
175  }
176  device = snpdev->handle;
177 
178  /* Use shim instead of directly executing image if applicable */
179  shim = ( efi_can_load ( image ) ?
180  NULL : find_image_tag ( &efi_shim ) );
181  exec = ( shim ? shim : image );
182  if ( shim ) {
183  DBGC ( image, "EFIIMAGE %s executing via %s\n",
184  image->name, shim->name );
185  }
186 
187  /* Re-register as a hidden image to allow for access via file I/O */
188  toggle = ( ~image->flags & IMAGE_HIDDEN );
190  if ( ( rc = register_image ( image ) ) != 0 )
191  goto err_register_image;
192 
193  /* Install file I/O protocols */
194  if ( ( rc = efi_file_install ( device ) ) != 0 ) {
195  DBGC ( image, "EFIIMAGE %s could not install file protocol: "
196  "%s\n", image->name, strerror ( rc ) );
197  goto err_file_install;
198  }
199 
200  /* Install PXE base code protocol */
201  if ( ( rc = efi_pxe_install ( device, snpdev->netdev ) ) != 0 ){
202  DBGC ( image, "EFIIMAGE %s could not install PXE protocol: "
203  "%s\n", image->name, strerror ( rc ) );
204  goto err_pxe_install;
205  }
206 
207  /* Install iPXE download protocol */
208  if ( ( rc = efi_download_install ( device ) ) != 0 ) {
209  DBGC ( image, "EFIIMAGE %s could not install iPXE download "
210  "protocol: %s\n", image->name, strerror ( rc ) );
211  goto err_download_install;
212  }
213 
214  /* Install Flattened Device Tree table */
215  if ( ( rc = efi_fdt_install ( image->cmdline ) ) != 0 ) {
216  DBGC ( image, "EFIIMAGE %s could not install FDT: %s\n",
217  image->name, strerror ( rc ) );
218  goto err_fdt_install;
219  }
220 
221  /* Create device path for image */
222  path = efi_image_path ( exec, snpdev->path );
223  if ( ! path ) {
224  DBGC ( image, "EFIIMAGE %s could not create device path\n",
225  image->name );
226  rc = -ENOMEM;
227  goto err_image_path;
228  }
229 
230  /* Create command line for image */
232  if ( ! cmdline ) {
233  DBGC ( image, "EFIIMAGE %s could not create command line\n",
234  image->name );
235  rc = -ENOMEM;
236  goto err_cmdline;
237  }
238 
239  /* Install shim special handling if applicable */
240  if ( shim &&
241  ( ( rc = efi_shim_install ( shim, device, &cmdline ) ) != 0 ) ) {
242  DBGC ( image, "EFIIMAGE %s could not install shim handling: "
243  "%s\n", image->name, strerror ( rc ) );
244  goto err_shim_install;
245  }
246 
247  /* Attempt loading image
248  *
249  * LoadImage() does not (allegedly) modify the image content,
250  * but requires a non-const pointer to SourceBuffer. We
251  * therefore use the .rwdata field rather than .data.
252  */
253  handle = NULL;
254  if ( ( efirc = bs->LoadImage ( FALSE, efi_image_handle, path,
255  exec->rwdata, exec->len,
256  &handle ) ) != 0 ) {
257  /* Not an EFI image */
258  rc = -EEFI_LOAD ( efirc );
259  DBGC ( image, "EFIIMAGE %s could not load: %s\n",
260  image->name, strerror ( rc ) );
261  if ( efirc == EFI_SECURITY_VIOLATION ) {
262  goto err_load_image_security_violation;
263  } else {
264  goto err_load_image;
265  }
266  }
267 
268  /* Get the loaded image protocol for the newly loaded image */
270  &loaded ) ) != 0 ) {
271  /* Should never happen */
272  goto err_open_protocol;
273  }
274 
275  /* Some EFI 1.10 implementations seem not to fill in DeviceHandle */
276  if ( loaded->DeviceHandle == NULL ) {
277  DBGC ( image, "EFIIMAGE %s filling in missing DeviceHandle\n",
278  image->name );
279  loaded->DeviceHandle = device;
280  }
281 
282  /* Sanity checks */
283  assert ( loaded->ParentHandle == efi_image_handle );
284  assert ( loaded->DeviceHandle == device );
285  assert ( loaded->LoadOptionsSize == 0 );
286  assert ( loaded->LoadOptions == NULL );
287 
288  /* Record image code type */
289  type = loaded->ImageCodeType;
290 
291  /* Set command line */
292  loaded->LoadOptions = cmdline;
293  loaded->LoadOptionsSize =
294  ( ( wcslen ( cmdline ) + 1 /* NUL */ ) * sizeof ( wchar_t ) );
295 
296  /* Release network devices for use via SNP */
297  efi_snp_release();
298 
299  /* Wrap calls made by the loaded image (for debugging) */
301 
302  /* Reset console since image will probably use it */
303  console_reset();
304 
305  /* Assume that image may cause SNP device to be removed */
306  snpdev = NULL;
307 
308  /* Start the image */
309  if ( ( efirc = bs->StartImage ( handle, NULL, NULL ) ) != 0 ) {
310  rc = -EEFI_START ( efirc );
311  DBGC ( image, "EFIIMAGE %s could not start (or returned with "
312  "error): %s\n", image->name, strerror ( rc ) );
313  goto err_start_image;
314  }
315 
316  /* If image was a driver, connect it up to anything available */
317  if ( type == EfiBootServicesCode ) {
318  DBGC ( image, "EFIIMAGE %s connecting drivers\n", image->name );
320  }
321 
322  /* Success */
323  rc = 0;
324 
325  err_start_image:
326  efi_unwrap();
327  efi_snp_claim();
328  err_open_protocol:
329  /* If there was no error, then the image must have been
330  * started and returned successfully. It either unloaded
331  * itself, or it intended to remain loaded (e.g. it was a
332  * driver). We therefore do not unload successful images.
333  *
334  * If there was an error, attempt to unload the image. This
335  * may not work. In particular, there is no way to tell
336  * whether an error returned from StartImage() was due to
337  * being unable to start the image (in which case we probably
338  * should call UnloadImage()), or due to the image itself
339  * returning an error (in which case we probably should not
340  * call UnloadImage()). We therefore ignore any failures from
341  * the UnloadImage() call itself.
342  */
343  err_load_image_security_violation:
344  if ( rc != 0 )
345  bs->UnloadImage ( handle );
346  err_load_image:
347  if ( shim )
349  err_shim_install:
350  free ( cmdline );
351  err_cmdline:
352  free ( path );
353  err_image_path:
355  err_fdt_install:
357  err_download_install:
359  err_pxe_install:
361  err_file_install:
363  err_register_image:
364  image->flags ^= toggle;
365  err_no_snpdev:
366  return rc;
367 }
unsigned int flags
Flags.
Definition: image.h:40
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2099
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void efi_download_uninstall(EFI_HANDLE handle)
Uninstall iPXE download protocol.
Definition: efi_download.c:237
EFI_IMAGE_LOAD LoadImage
Definition: UefiSpec.h:1978
uint32_t type
Operating system type.
Definition: ena.h:12
int efi_shim_install(struct image *shim, EFI_HANDLE handle, wchar_t **cmdline)
Install UEFI shim special handling.
Definition: efi_shim.c:341
#define EEFI_START(efirc)
Definition: efi_image.c:61
#define DBGC(...)
Definition: compiler.h:505
EFI_GUID efi_loaded_image_protocol_guid
Loaded image protocol GUID.
Definition: efi_guid.c:273
void efi_file_uninstall(EFI_HANDLE handle)
Uninstall EFI simple file system protocol.
Definition: efi_file.c:1212
EFI_IMAGE_UNLOAD UnloadImage
Definition: UefiSpec.h:1981
An executable image.
Definition: image.h:24
This protocol can be used on any device handle to obtain generic path/location information concerning...
Definition: DevicePath.h:46
static void efi_snp_claim(void)
Claim network devices for use by iPXE.
Definition: efi_snp.h:92
uint16_t device
Device ID.
Definition: ena.h:24
EFI_HANDLE handle
EFI device handle.
Definition: efi_snp.h:37
size_t wcslen(const wchar_t *string)
Calculate length of wide-character string.
Definition: wchar.c:57
EFI_MEMORY_TYPE ImageCodeType
The memory type that the code sections were loaded as.
Definition: LoadedImage.h:72
char * cmdline
Command line to pass to image.
Definition: image.h:43
int efi_file_install(EFI_HANDLE handle)
Install EFI simple file system protocol.
Definition: efi_file.c:1116
struct image * find_image_tag(struct image_tag *tag)
Find image by tag.
Definition: image.c:393
struct net_device * netdev
The underlying iPXE network device.
Definition: efi_snp.h:33
struct efi_snp_device * last_opened_snpdev(void)
Get most recently opened SNP device.
Definition: efi_snp.c:2119
#define ENOMEM
Not enough space.
Definition: errno.h:535
A hardware device.
Definition: device.h:77
Can be used on any image handle to obtain information about the loaded image.
Definition: LoadedImage.h:46
void efi_pxe_uninstall(EFI_HANDLE handle)
Uninstall PXE base code protocol.
Definition: efi_pxe.c:1632
void efi_driver_reconnect_all(void)
Reconnect original EFI drivers to all possible devices.
Definition: efi_driver.c:659
EFI_MEMORY_TYPE
Enumeration of memory types introduced in UEFI.
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define EEFI_LOAD(efirc)
Definition: efi_image.c:56
VOID * LoadOptions
A pointer to the image's binary load options.
Definition: LoadedImage.h:65
The code portions of a loaded Boot Services Driver.
int efi_pxe_install(EFI_HANDLE handle, struct net_device *netdev)
Install PXE base code protocol.
Definition: efi_pxe.c:1549
static int efi_can_load(struct image *image)
Check if EFI image can be loaded directly.
Definition: efi_image.h:23
int register_image(struct image *image)
Register executable image.
Definition: image.c:315
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55
EFI Boot Services Table.
Definition: UefiSpec.h:1931
EFI_HANDLE efi_image_handle
Image handle passed to entry point.
Definition: efi_init.c:36
size_t len
Length of raw file image.
Definition: image.h:56
#define IMAGE_HIDDEN
Image will be hidden from enumeration.
Definition: image.h:86
An SNP device.
Definition: efi_snp.h:29
#define ENODEV
No such device.
Definition: errno.h:510
static void efi_snp_release(void)
Release network devices for use via SNP.
Definition: efi_snp.h:100
#define efi_open(handle, protocol, interface)
Open protocol for ephemeral use.
Definition: efi.h:444
__weak int efi_fdt_uninstall(void)
Uninstall EFI Flattened Device Tree table (when no FDT support is present)
Definition: efi_image.c:143
static void console_reset(void)
Reset console.
Definition: console.h:215
EFI_IMAGE_START StartImage
Definition: UefiSpec.h:1979
void efi_wrap_image(EFI_HANDLE handle)
Wrap calls made by a newly loaded image.
Definition: efi_wrap.c:1567
#define EFI_SECURITY_VIOLATION
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:141
UINT32 LoadOptionsSize
The size in bytes of LoadOptions.
Definition: LoadedImage.h:64
static wchar_t * efi_image_cmdline(struct image *image)
Create command line for image.
Definition: efi_image.c:115
void unregister_image(struct image *image)
Unregister executable image.
Definition: image.c:358
static EFI_DEVICE_PATH_PROTOCOL * efi_image_path(struct image *image, EFI_DEVICE_PATH_PROTOCOL *parent)
Create device path for image.
Definition: efi_image.c:73
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:32
void * rwdata
Writable data.
Definition: image.h:53
void efi_shim_uninstall(void)
Uninstall UEFI shim special handling.
Definition: efi_shim.c:375
int efi_download_install(EFI_HANDLE handle)
Install iPXE download protocol.
Definition: efi_download.c:212
#define FALSE
Definition: tlan.h:45
EFI_SYSTEM_TABLE * efi_systab
uint32_t cmdline
Definition: multiboot.h:16
EFI_DEVICE_PATH_PROTOCOL * path
The device path.
Definition: efi_snp.h:79
void efi_unwrap(void)
Remove boot services table wrapper.
Definition: efi_wrap.c:1543
uint16_t handle
Handle.
Definition: smbios.h:17
char * name
Name.
Definition: image.h:38
int shim(struct image *image, int require_loader, int allow_pxe, int allow_sbat)
Set shim image.
Definition: shimmgmt.c:46
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
EFI_HANDLE ParentHandle
Parent image's image handle.
Definition: LoadedImage.h:49
__weak int efi_fdt_install(const char *cmdline __unused)
Install EFI Flattened Device Tree table (when no FDT support is present)
Definition: efi_image.c:134
Definition: efi.h:62
EFI_HANDLE DeviceHandle
The device handle that the EFI Image was loaded from.
Definition: LoadedImage.h:56

References assert(), EFI_SYSTEM_TABLE::BootServices, cmdline, image::cmdline, console_reset(), DBGC, device, EFI_LOADED_IMAGE_PROTOCOL::DeviceHandle, EEFI_LOAD, EEFI_START, efi_can_load(), efi_download_install(), efi_download_uninstall(), efi_driver_reconnect_all(), efi_fdt_install(), efi_fdt_uninstall(), efi_file_install(), efi_file_uninstall(), efi_image_cmdline(), efi_image_handle, efi_image_path(), efi_loaded_image_protocol_guid, efi_open, efi_pxe_install(), efi_pxe_uninstall(), EFI_SECURITY_VIOLATION, efi_shim_install(), efi_shim_uninstall(), efi_snp_claim(), efi_snp_release(), efi_systab, efi_unwrap(), efi_wrap_image(), EfiBootServicesCode, ENODEV, ENOMEM, FALSE, find_image_tag(), image::flags, free, handle, efi_snp_device::handle, IMAGE_HIDDEN, EFI_LOADED_IMAGE_PROTOCOL::ImageCodeType, last_opened_snpdev(), image::len, EFI_BOOT_SERVICES::LoadImage, EFI_LOADED_IMAGE_PROTOCOL::LoadOptions, EFI_LOADED_IMAGE_PROTOCOL::LoadOptionsSize, image::name, efi_snp_device::netdev, NULL, EFI_LOADED_IMAGE_PROTOCOL::ParentHandle, efi_snp_device::path, rc, register_image(), image::rwdata, shim(), EFI_BOOT_SERVICES::StartImage, strerror(), type, EFI_BOOT_SERVICES::UnloadImage, unregister_image(), and wcslen().

◆ efi_image_probe()

static int efi_image_probe ( struct image image)
static

Probe EFI image.

Parameters
imageEFI file
Return values
rcReturn status code

Definition at line 375 of file efi_image.c.

375  {
377  static EFI_DEVICE_PATH_PROTOCOL empty_path = {
380  .Length[0] = sizeof ( empty_path ),
381  };
383  EFI_STATUS efirc;
384  int rc;
385 
386  /* Attempt loading image
387  *
388  * LoadImage() does not (allegedly) modify the image content,
389  * but requires a non-const pointer to SourceBuffer. We
390  * therefore use the .rwdata field rather than .data.
391  */
392  handle = NULL;
393  if ( ( efirc = bs->LoadImage ( FALSE, efi_image_handle, &empty_path,
394  image->rwdata, image->len,
395  &handle ) ) != 0 ) {
396  /* Not an EFI image */
397  rc = -EEFI_LOAD ( efirc );
398  DBGC ( image, "EFIIMAGE %s could not load: %s\n",
399  image->name, strerror ( rc ) );
400  if ( efirc == EFI_SECURITY_VIOLATION ) {
401  goto err_load_image_security_violation;
402  } else {
403  goto err_load_image;
404  }
405  }
406 
407  /* Unload the image. We can't leave it loaded, because we
408  * have no "unload" operation.
409  */
410  bs->UnloadImage ( handle );
411 
412  return 0;
413 
414  err_load_image_security_violation:
415  bs->UnloadImage ( handle );
416  err_load_image:
417  return rc;
418 }
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2099
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define END_DEVICE_PATH_TYPE
Definition: DevicePath.h:1394
EFI_IMAGE_LOAD LoadImage
Definition: UefiSpec.h:1978
#define DBGC(...)
Definition: compiler.h:505
EFI_IMAGE_UNLOAD UnloadImage
Definition: UefiSpec.h:1981
An executable image.
Definition: image.h:24
This protocol can be used on any device handle to obtain generic path/location information concerning...
Definition: DevicePath.h:46
#define EEFI_LOAD(efirc)
Definition: efi_image.c:56
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
EFI Boot Services Table.
Definition: UefiSpec.h:1931
EFI_HANDLE efi_image_handle
Image handle passed to entry point.
Definition: efi_init.c:36
size_t len
Length of raw file image.
Definition: image.h:56
#define EFI_SECURITY_VIOLATION
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:141
#define END_ENTIRE_DEVICE_PATH_SUBTYPE
Definition: DevicePath.h:1395
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:32
void * rwdata
Writable data.
Definition: image.h:53
#define FALSE
Definition: tlan.h:45
UINT8 Type
0x01 Hardware Device Path.
Definition: DevicePath.h:47
EFI_SYSTEM_TABLE * efi_systab
uint16_t handle
Handle.
Definition: smbios.h:17
char * name
Name.
Definition: image.h:38
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
Definition: efi.h:62

References EFI_SYSTEM_TABLE::BootServices, DBGC, EEFI_LOAD, efi_image_handle, EFI_SECURITY_VIOLATION, efi_systab, END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, FALSE, handle, image::len, EFI_BOOT_SERVICES::LoadImage, image::name, NULL, rc, image::rwdata, strerror(), EFI_DEVICE_PATH_PROTOCOL::Type, and EFI_BOOT_SERVICES::UnloadImage.

◆ efi_pe_image_probe()

static int efi_pe_image_probe ( struct image image)
static

Probe EFI PE image.

Parameters
imageEFI file
Return values
rcReturn status code

The extremely broken UEFI Secure Boot model provides no way for us to unambiguously determine that a valid EFI executable image was rejected by LoadImage() because it failed signature verification. We must therefore use heuristics to guess whether not an image that was rejected by LoadImage() could still be loaded via a separate PE loader such as the UEFI shim.

Definition at line 433 of file efi_image.c.

433  {
434  const UINT16 magic = ( ( sizeof ( UINTN ) == sizeof ( uint32_t ) ) ?
437  const EFI_IMAGE_DOS_HEADER *dos;
439 
440  /* Check for existence of DOS header */
441  if ( image->len < sizeof ( *dos ) ) {
442  DBGC ( image, "EFIIMAGE %s too short for DOS header\n",
443  image->name );
444  return -ENOEXEC;
445  }
446  dos = image->data;
447  if ( dos->e_magic != EFI_IMAGE_DOS_SIGNATURE ) {
448  DBGC ( image, "EFIIMAGE %s missing MZ signature\n",
449  image->name );
450  return -ENOEXEC;
451  }
452 
453  /* Check for existence of PE header */
454  if ( ( image->len < dos->e_lfanew ) ||
455  ( ( image->len - dos->e_lfanew ) < sizeof ( *pe ) ) ) {
456  DBGC ( image, "EFIIMAGE %s too short for PE header\n",
457  image->name );
458  return -ENOEXEC;
459  }
460  pe = ( image->data + dos->e_lfanew );
461  if ( pe->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE ) {
462  DBGC ( image, "EFIIMAGE %s missing PE signature\n",
463  image->name );
464  return -ENOEXEC;
465  }
466 
467  /* Check PE header magic */
468  if ( pe->Pe32.OptionalHeader.Magic != magic ) {
469  DBGC ( image, "EFIIMAGE %s incorrect magic %04x\n",
471  return -ENOEXEC;
472  }
473 
474  return 0;
475 }
const void * data
Read-only data.
Definition: image.h:51
uint16_t magic
Magic signature.
Definition: bzimage.h:6
#define ENOEXEC
Exec format error.
Definition: errno.h:520
#define DBGC(...)
Definition: compiler.h:505
Union of PE32, PE32+, and TE headers.
Definition: PeImage.h:805
#define EFI_IMAGE_DOS_SIGNATURE
Definition: PeImage.h:50
An executable image.
Definition: image.h:24
EFI_IMAGE_NT_HEADERS32 Pe32
Definition: PeImage.h:806
#define EFI_IMAGE_NT_SIGNATURE
Definition: PeImage.h:53
unsigned short UINT16
UINT16 Magic
Standard fields.
Definition: PeImage.h:154
size_t len
Length of raw file image.
Definition: image.h:56
UINT64 UINTN
Unsigned value of native width.
unsigned int uint32_t
Definition: stdint.h:12
UINT32 e_lfanew
File address of new exe header.
Definition: PeImage.h:78
UINT16 e_magic
Magic number.
Definition: PeImage.h:60
PE images can start with an optional DOS header, so if an image is run under DOS it can print an erro...
Definition: PeImage.h:59
#define EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
Definition: PeImage.h:145
#define EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
Definition: PeImage.h:196
char * name
Name.
Definition: image.h:38
EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: PeImage.h:247

References image::data, DBGC, EFI_IMAGE_DOS_HEADER::e_lfanew, EFI_IMAGE_DOS_HEADER::e_magic, EFI_IMAGE_DOS_SIGNATURE, EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC, EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC, EFI_IMAGE_NT_SIGNATURE, ENOEXEC, image::len, magic, EFI_IMAGE_OPTIONAL_HEADER32::Magic, image::name, EFI_IMAGE_NT_HEADERS32::OptionalHeader, EFI_IMAGE_OPTIONAL_HEADER_UNION::Pe32, and EFI_IMAGE_NT_HEADERS32::Signature.

◆ __image_type()

struct image_type efi_image_type [] __image_type ( PROBE_NORMAL  )

EFI image types.