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)
 
 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:691
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 47 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:193
#define EINFO_EEFI_LOAD
Definition: efi_image.c:47
#define EFI_SECURITY_VIOLATION
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:140

Definition at line 50 of file efi_image.c.

◆ EEFI_LOAD_PROHIBITED

#define EEFI_LOAD_PROHIBITED   __einfo_error ( EINFO_EEFI_LOAD_PROHIBITED )

Definition at line 53 of file efi_image.c.

◆ EEFI_LOAD

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

Definition at line 55 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:691
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 57 of file efi_image.c.

◆ EEFI_START

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

Definition at line 60 of file efi_image.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER  )

◆ 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 72 of file efi_image.c.

72  {
74  FILEPATH_DEVICE_PATH *filepath;
76  size_t name_len;
77  size_t prefix_len;
78  size_t filepath_len;
79  size_t len;
80 
81  /* Calculate device path lengths */
82  prefix_len = efi_path_len ( parent );
83  name_len = strlen ( image->name );
84  filepath_len = ( SIZE_OF_FILEPATH_DEVICE_PATH +
85  ( name_len + 1 /* NUL */ ) * sizeof ( wchar_t ) );
86  len = ( prefix_len + filepath_len + sizeof ( *end ) );
87 
88  /* Allocate device path */
89  path = zalloc ( len );
90  if ( ! path )
91  return NULL;
92 
93  /* Construct device path */
94  memcpy ( path, parent, prefix_len );
95  filepath = ( ( ( void * ) path ) + prefix_len );
96  filepath->Header.Type = MEDIA_DEVICE_PATH;
97  filepath->Header.SubType = MEDIA_FILEPATH_DP;
98  filepath->Header.Length[0] = ( filepath_len & 0xff );
99  filepath->Header.Length[1] = ( filepath_len >> 8 );
100  efi_snprintf ( filepath->PathName, ( name_len + 1 /* NUL */ ),
101  "%s", image->name );
102  end = ( ( ( void * ) filepath ) + filepath_len );
104 
105  return path;
106 }
size_t efi_path_len(EFI_DEVICE_PATH_PROTOCOL *path)
Find length of device path (excluding terminator)
Definition: efi_path.c:173
An executable image.
Definition: image.h:23
This protocol can be used on any device handle to obtain generic path/location information concerning...
Definition: DevicePath.h:45
CHAR16 PathName[1]
A NULL-terminated Path string including directory and file names.
Definition: DevicePath.h:1106
EFI_DEVICE_PATH_PROTOCOL Header
Definition: DevicePath.h:1102
static void efi_path_terminate(EFI_DEVICE_PATH_PROTOCOL *end)
Terminate device path.
Definition: efi_path.h:30
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:106
#define SIZE_OF_FILEPATH_DEVICE_PATH
Definition: DevicePath.h:1109
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:661
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
#define MEDIA_DEVICE_PATH
Definition: DevicePath.h:1011
UINT8 Length[2]
Specific Device Path data.
Definition: DevicePath.h:58
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:53
uint32_t end
Ending offset.
Definition: netvsc.h:18
UINT8 Type
0x01 Hardware Device Path.
Definition: DevicePath.h:46
char * name
Name.
Definition: image.h:37
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define MEDIA_FILEPATH_DP
File Path Media Device Path SubType.
Definition: DevicePath.h:1100

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 114 of file efi_image.c.

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

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 133 of file efi_image.c.

133  {
134  return 0;
135 }

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 142 of file efi_image.c.

142  {
143  return 0;
144 }

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 152 of file efi_image.c.

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

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 374 of file efi_image.c.

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

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 432 of file efi_image.c.

432  {
433  const UINT16 magic = ( ( sizeof ( UINTN ) == sizeof ( uint32_t ) ) ?
436  const EFI_IMAGE_DOS_HEADER *dos;
438 
439  /* Check for existence of DOS header */
440  if ( image->len < sizeof ( *dos ) ) {
441  DBGC ( image, "EFIIMAGE %s too short for DOS header\n",
442  image->name );
443  return -ENOEXEC;
444  }
445  dos = image->data;
446  if ( dos->e_magic != EFI_IMAGE_DOS_SIGNATURE ) {
447  DBGC ( image, "EFIIMAGE %s missing MZ signature\n",
448  image->name );
449  return -ENOEXEC;
450  }
451 
452  /* Check for existence of PE header */
453  if ( ( image->len < dos->e_lfanew ) ||
454  ( ( image->len - dos->e_lfanew ) < sizeof ( *pe ) ) ) {
455  DBGC ( image, "EFIIMAGE %s too short for PE header\n",
456  image->name );
457  return -ENOEXEC;
458  }
459  pe = ( image->data + dos->e_lfanew );
460  if ( pe->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE ) {
461  DBGC ( image, "EFIIMAGE %s missing PE signature\n",
462  image->name );
463  return -ENOEXEC;
464  }
465 
466  /* Check PE header magic */
467  if ( pe->Pe32.OptionalHeader.Magic != magic ) {
468  DBGC ( image, "EFIIMAGE %s incorrect magic %04x\n",
470  return -ENOEXEC;
471  }
472 
473  return 0;
474 }
const void * data
Read-only data.
Definition: image.h:50
uint16_t magic
Magic signature.
Definition: bzimage.h:6
#define ENOEXEC
Exec format error.
Definition: errno.h:519
#define DBGC(...)
Definition: compiler.h:505
Union of PE32, PE32+, and TE headers.
Definition: PeImage.h:804
#define EFI_IMAGE_DOS_SIGNATURE
Definition: PeImage.h:49
An executable image.
Definition: image.h:23
EFI_IMAGE_NT_HEADERS32 Pe32
Definition: PeImage.h:805
#define EFI_IMAGE_NT_SIGNATURE
Definition: PeImage.h:52
unsigned short UINT16
UINT16 Magic
Standard fields.
Definition: PeImage.h:153
size_t len
Length of raw file image.
Definition: image.h:55
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:77
UINT16 e_magic
Magic number.
Definition: PeImage.h:59
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:58
#define EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
Definition: PeImage.h:144
#define EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
Definition: PeImage.h:195
char * name
Name.
Definition: image.h:37
EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: PeImage.h:246

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.