iPXE
Macros | Functions
efi_image.c File Reference
#include <errno.h>
#include <stdlib.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/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...
 
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 45 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:45
#define EFI_SECURITY_VIOLATION
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:140

Definition at line 48 of file efi_image.c.

◆ EEFI_LOAD_PROHIBITED

#define EEFI_LOAD_PROHIBITED   __einfo_error ( EINFO_EEFI_LOAD_PROHIBITED )

Definition at line 51 of file efi_image.c.

◆ EEFI_LOAD

#define EEFI_LOAD (   efirc)
Value:
#define EINFO_EEFI_LOAD
Definition: efi_image.c:45
#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:51

Definition at line 53 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 55 of file efi_image.c.

◆ EEFI_START

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

Definition at line 58 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 70 of file efi_image.c.

70  {
72  FILEPATH_DEVICE_PATH *filepath;
74  size_t name_len;
75  size_t prefix_len;
76  size_t filepath_len;
77  size_t len;
78 
79  /* Calculate device path lengths */
80  prefix_len = efi_path_len ( parent );
81  name_len = strlen ( image->name );
82  filepath_len = ( SIZE_OF_FILEPATH_DEVICE_PATH +
83  ( name_len + 1 /* NUL */ ) * sizeof ( wchar_t ) );
84  len = ( prefix_len + filepath_len + sizeof ( *end ) );
85 
86  /* Allocate device path */
87  path = zalloc ( len );
88  if ( ! path )
89  return NULL;
90 
91  /* Construct device path */
92  memcpy ( path, parent, prefix_len );
93  filepath = ( ( ( void * ) path ) + prefix_len );
94  filepath->Header.Type = MEDIA_DEVICE_PATH;
95  filepath->Header.SubType = MEDIA_FILEPATH_DP;
96  filepath->Header.Length[0] = ( filepath_len & 0xff );
97  filepath->Header.Length[1] = ( filepath_len >> 8 );
98  efi_snprintf ( filepath->PathName, ( name_len + 1 /* NUL */ ),
99  "%s", image->name );
100  end = ( ( ( void * ) filepath ) + filepath_len );
102 
103  return path;
104 }
size_t efi_path_len(EFI_DEVICE_PATH_PROTOCOL *path)
Find length of device path (excluding terminator)
Definition: efi_path.c:144
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:45
CHAR16 PathName[1]
A NULL-terminated Path string including directory and file names.
Definition: DevicePath.h:1086
EFI_DEVICE_PATH_PROTOCOL Header
Definition: DevicePath.h:1082
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
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:1089
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
#define MEDIA_DEVICE_PATH
Definition: DevicePath.h:991
UINT8 Length[2]
Specific Device Path data.
Definition: DevicePath.h:58
uint32_t len
Length.
Definition: ena.h:14
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:34
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define MEDIA_FILEPATH_DP
File Path Media Device Path SubType.
Definition: DevicePath.h:1080

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

112  {
113  wchar_t *cmdline;
114 
115  /* Allocate and construct command line */
116  if ( efi_asprintf ( &cmdline, "%s%s%s", image->name,
117  ( image->cmdline ? " " : "" ),
118  ( image->cmdline ? image->cmdline : "" ) ) < 0 ) {
119  return NULL;
120  }
121 
122  return cmdline;
123 }
An executable image.
Definition: image.h:24
char * cmdline
Command line to pass to image.
Definition: image.h:39
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:34
#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_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 131 of file efi_image.c.

131  {
133  struct efi_snp_device *snpdev;
135  union {
137  void *interface;
138  } loaded;
139  struct image *shim;
140  struct image *exec;
143  wchar_t *cmdline;
144  unsigned int toggle;
145  EFI_STATUS efirc;
146  int rc;
147 
148  /* Find an appropriate device handle to use */
149  snpdev = last_opened_snpdev();
150  if ( ! snpdev ) {
151  DBGC ( image, "EFIIMAGE %s could not identify SNP device\n",
152  image->name );
153  rc = -ENODEV;
154  goto err_no_snpdev;
155  }
156 
157  /* Use shim instead of directly executing image if applicable */
158  shim = ( efi_can_load ( image ) ?
159  NULL : find_image_tag ( &efi_shim ) );
160  exec = ( shim ? shim : image );
161  if ( shim ) {
162  DBGC ( image, "EFIIMAGE %s executing via %s\n",
163  image->name, shim->name );
164  }
165 
166  /* Re-register as a hidden image to allow for access via file I/O */
167  toggle = ( ~image->flags & IMAGE_HIDDEN );
169  if ( ( rc = register_image ( image ) ) != 0 )
170  goto err_register_image;
171 
172  /* Install file I/O protocols */
173  if ( ( rc = efi_file_install ( snpdev->handle ) ) != 0 ) {
174  DBGC ( image, "EFIIMAGE %s could not install file protocol: "
175  "%s\n", image->name, strerror ( rc ) );
176  goto err_file_install;
177  }
178 
179  /* Install PXE base code protocol */
180  if ( ( rc = efi_pxe_install ( snpdev->handle, snpdev->netdev ) ) != 0 ){
181  DBGC ( image, "EFIIMAGE %s could not install PXE protocol: "
182  "%s\n", image->name, strerror ( rc ) );
183  goto err_pxe_install;
184  }
185 
186  /* Install iPXE download protocol */
187  if ( ( rc = efi_download_install ( snpdev->handle ) ) != 0 ) {
188  DBGC ( image, "EFIIMAGE %s could not install iPXE download "
189  "protocol: %s\n", image->name, strerror ( rc ) );
190  goto err_download_install;
191  }
192 
193  /* Create device path for image */
194  path = efi_image_path ( exec, snpdev->path );
195  if ( ! path ) {
196  DBGC ( image, "EFIIMAGE %s could not create device path\n",
197  image->name );
198  rc = -ENOMEM;
199  goto err_image_path;
200  }
201 
202  /* Create command line for image */
204  if ( ! cmdline ) {
205  DBGC ( image, "EFIIMAGE %s could not create command line\n",
206  image->name );
207  rc = -ENOMEM;
208  goto err_cmdline;
209  }
210 
211  /* Install shim special handling if applicable */
212  if ( shim &&
213  ( ( rc = efi_shim_install ( shim, snpdev->handle,
214  &cmdline ) ) != 0 ) ){
215  DBGC ( image, "EFIIMAGE %s could not install shim handling: "
216  "%s\n", image->name, strerror ( rc ) );
217  goto err_shim_install;
218  }
219 
220  /* Attempt loading image */
221  handle = NULL;
222  if ( ( efirc = bs->LoadImage ( FALSE, efi_image_handle, path,
223  user_to_virt ( exec->data, 0 ),
224  exec->len, &handle ) ) != 0 ) {
225  /* Not an EFI image */
226  rc = -EEFI_LOAD ( efirc );
227  DBGC ( image, "EFIIMAGE %s could not load: %s\n",
228  image->name, strerror ( rc ) );
229  if ( efirc == EFI_SECURITY_VIOLATION ) {
230  goto err_load_image_security_violation;
231  } else {
232  goto err_load_image;
233  }
234  }
235 
236  /* Get the loaded image protocol for the newly loaded image */
238  &loaded.interface, efi_image_handle,
240  if ( efirc ) {
241  /* Should never happen */
242  rc = -EEFI ( efirc );
243  goto err_open_protocol;
244  }
245 
246  /* Some EFI 1.10 implementations seem not to fill in DeviceHandle */
247  if ( loaded.image->DeviceHandle == NULL ) {
248  DBGC ( image, "EFIIMAGE %s filling in missing DeviceHandle\n",
249  image->name );
250  loaded.image->DeviceHandle = snpdev->handle;
251  }
252 
253  /* Sanity checks */
254  assert ( loaded.image->ParentHandle == efi_image_handle );
255  assert ( loaded.image->DeviceHandle == snpdev->handle );
256  assert ( loaded.image->LoadOptionsSize == 0 );
257  assert ( loaded.image->LoadOptions == NULL );
258 
259  /* Record image code type */
260  type = loaded.image->ImageCodeType;
261 
262  /* Set command line */
263  loaded.image->LoadOptions = cmdline;
264  loaded.image->LoadOptionsSize =
265  ( ( wcslen ( cmdline ) + 1 /* NUL */ ) * sizeof ( wchar_t ) );
266 
267  /* Release network devices for use via SNP */
268  efi_snp_release();
269 
270  /* Wrap calls made by the loaded image (for debugging) */
271  efi_wrap ( handle );
272 
273  /* Reset console since image will probably use it */
274  console_reset();
275 
276  /* Start the image */
277  if ( ( efirc = bs->StartImage ( handle, NULL, NULL ) ) != 0 ) {
278  rc = -EEFI_START ( efirc );
279  DBGC ( image, "EFIIMAGE %s could not start (or returned with "
280  "error): %s\n", image->name, strerror ( rc ) );
281  goto err_start_image;
282  }
283 
284  /* If image was a driver, connect it up to anything available */
285  if ( type == EfiBootServicesCode ) {
286  DBGC ( image, "EFIIMAGE %s connecting drivers\n", image->name );
288  }
289 
290  /* Success */
291  rc = 0;
292 
293  err_start_image:
294  efi_snp_claim();
295  err_open_protocol:
296  /* If there was no error, then the image must have been
297  * started and returned successfully. It either unloaded
298  * itself, or it intended to remain loaded (e.g. it was a
299  * driver). We therefore do not unload successful images.
300  *
301  * If there was an error, attempt to unload the image. This
302  * may not work. In particular, there is no way to tell
303  * whether an error returned from StartImage() was due to
304  * being unable to start the image (in which case we probably
305  * should call UnloadImage()), or due to the image itself
306  * returning an error (in which case we probably should not
307  * call UnloadImage()). We therefore ignore any failures from
308  * the UnloadImage() call itself.
309  */
310  err_load_image_security_violation:
311  if ( rc != 0 )
312  bs->UnloadImage ( handle );
313  err_load_image:
314  if ( shim )
316  err_shim_install:
317  free ( cmdline );
318  err_cmdline:
319  free ( path );
320  err_image_path:
321  efi_download_uninstall ( snpdev->handle );
322  err_download_install:
323  efi_pxe_uninstall ( snpdev->handle );
324  err_pxe_install:
325  efi_file_uninstall ( snpdev->handle );
326  err_file_install:
328  err_register_image:
329  image->flags ^= toggle;
330  err_no_snpdev:
331  return rc;
332 }
unsigned int flags
Flags.
Definition: image.h:36
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2081
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
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition: efi.h:171
userptr_t data
Raw file image.
Definition: image.h:41
EFI_IMAGE_LOAD LoadImage
Definition: UefiSpec.h:1964
int efi_shim_install(struct image *shim, EFI_HANDLE handle, wchar_t **cmdline)
Install UEFI shim special handling.
Definition: efi_shim.c:353
#define EEFI_START(efirc)
Definition: efi_image.c:58
#define DBGC(...)
Definition: compiler.h:505
EFI_GUID efi_loaded_image_protocol_guid
Loaded image protocol GUID.
Definition: efi_guid.c:243
void efi_file_uninstall(EFI_HANDLE handle)
Uninstall EFI simple file system protocol.
Definition: efi_file.c:1216
EFI_IMAGE_UNLOAD UnloadImage
Definition: UefiSpec.h:1967
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:45
static void efi_snp_claim(void)
Claim network devices for use by iPXE.
Definition: efi_snp.h:91
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:41
int efi_file_install(EFI_HANDLE handle)
Install EFI simple file system protocol.
Definition: efi_file.c:1113
struct image * find_image_tag(struct image_tag *tag)
Find image by tag.
Definition: image.c:338
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:2133
#define ENOMEM
Not enough space.
Definition: errno.h:534
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:1674
void efi_driver_reconnect_all(void)
Reconnect original EFI drivers to all possible devices.
Definition: efi_driver.c:624
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:53
An object interface.
Definition: interface.h:124
void efi_wrap(EFI_HANDLE handle)
Wrap the calls made by a loaded image.
Definition: efi_wrap.c:1248
#define EFI_OPEN_PROTOCOL_GET_PROTOCOL
Definition: UefiSpec.h:1344
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:1590
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:267
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:1917
EFI_HANDLE efi_image_handle
Image handle passed to entry point.
Definition: efi_init.c:34
size_t len
Length of raw file image.
Definition: image.h:43
#define IMAGE_HIDDEN
Image will be hidden from enumeration.
Definition: image.h:73
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
static void console_reset(void)
Reset console.
Definition: console.h:214
EFI_IMAGE_START StartImage
Definition: UefiSpec.h:1965
#define EFI_SECURITY_VIOLATION
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:140
static wchar_t * efi_image_cmdline(struct image *image)
Create command line for image.
Definition: efi_image.c:112
void unregister_image(struct image *image)
Unregister executable image.
Definition: image.c:303
uint32_t type
Operating system type.
Definition: ena.h:12
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:70
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:31
void efi_shim_uninstall(void)
Uninstall UEFI shim special handling.
Definition: efi_shim.c:387
void * user_to_virt(userptr_t userptr, off_t offset)
Convert user pointer to virtual address.
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
EFI_OPEN_PROTOCOL OpenProtocol
Definition: UefiSpec.h:1986
uint32_t cmdline
Definition: multiboot.h:16
EFI_DEVICE_PATH_PROTOCOL * path
The device path.
Definition: efi_snp.h:78
uint16_t handle
Handle.
Definition: smbios.h:16
char * name
Name.
Definition: image.h:34
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
Definition: efi.h:59

References assert(), EFI_SYSTEM_TABLE::BootServices, cmdline, console_reset(), image::data, DBGC, EEFI, EEFI_LOAD, EEFI_START, efi_can_load(), efi_download_install(), efi_download_uninstall(), efi_driver_reconnect_all(), efi_file_install(), efi_file_uninstall(), efi_image_cmdline(), efi_image_handle, efi_image_path(), efi_loaded_image_protocol_guid, EFI_OPEN_PROTOCOL_GET_PROTOCOL, efi_pxe_install(), efi_pxe_uninstall(), EFI_SECURITY_VIOLATION, efi_shim_install(), efi_shim_uninstall(), efi_snp_claim(), efi_snp_release(), efi_systab, efi_wrap(), EfiBootServicesCode, ENODEV, ENOMEM, FALSE, find_image_tag(), image::flags, free, handle, efi_snp_device::handle, IMAGE_HIDDEN, last_opened_snpdev(), image::len, EFI_BOOT_SERVICES::LoadImage, image::name, efi_snp_device::netdev, NULL, EFI_BOOT_SERVICES::OpenProtocol, efi_snp_device::path, rc, register_image(), shim(), EFI_BOOT_SERVICES::StartImage, strerror(), type, EFI_BOOT_SERVICES::UnloadImage, unregister_image(), user_to_virt(), 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 340 of file efi_image.c.

340  {
342  static EFI_DEVICE_PATH_PROTOCOL empty_path = {
345  .Length[0] = sizeof ( empty_path ),
346  };
348  EFI_STATUS efirc;
349  int rc;
350 
351  /* Attempt loading image */
352  handle = NULL;
353  if ( ( efirc = bs->LoadImage ( FALSE, efi_image_handle, &empty_path,
354  user_to_virt ( image->data, 0 ),
355  image->len, &handle ) ) != 0 ) {
356  /* Not an EFI image */
357  rc = -EEFI_LOAD ( efirc );
358  DBGC ( image, "EFIIMAGE %s could not load: %s\n",
359  image->name, strerror ( rc ) );
360  if ( efirc == EFI_SECURITY_VIOLATION ) {
361  goto err_load_image_security_violation;
362  } else {
363  goto err_load_image;
364  }
365  }
366 
367  /* Unload the image. We can't leave it loaded, because we
368  * have no "unload" operation.
369  */
370  bs->UnloadImage ( handle );
371 
372  return 0;
373 
374  err_load_image_security_violation:
375  bs->UnloadImage ( handle );
376  err_load_image:
377  return rc;
378 }
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2081
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
userptr_t data
Raw file image.
Definition: image.h:41
#define END_DEVICE_PATH_TYPE
Definition: DevicePath.h:1371
EFI_IMAGE_LOAD LoadImage
Definition: UefiSpec.h:1964
#define DBGC(...)
Definition: compiler.h:505
EFI_IMAGE_UNLOAD UnloadImage
Definition: UefiSpec.h:1967
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:45
#define EEFI_LOAD(efirc)
Definition: efi_image.c:53
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
EFI Boot Services Table.
Definition: UefiSpec.h:1917
EFI_HANDLE efi_image_handle
Image handle passed to entry point.
Definition: efi_init.c:34
size_t len
Length of raw file image.
Definition: image.h:43
#define EFI_SECURITY_VIOLATION
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:140
#define END_ENTIRE_DEVICE_PATH_SUBTYPE
Definition: DevicePath.h:1372
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:31
void * user_to_virt(userptr_t userptr, off_t offset)
Convert user pointer to virtual address.
#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:34
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
Definition: efi.h:59

References EFI_SYSTEM_TABLE::BootServices, image::data, 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, strerror(), EFI_DEVICE_PATH_PROTOCOL::Type, EFI_BOOT_SERVICES::UnloadImage, and user_to_virt().

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

393  {
394  const UINT16 magic = ( ( sizeof ( UINTN ) == sizeof ( uint32_t ) ) ?
397  union {
400  } u;
401 
402  /* Check for existence of DOS header */
403  if ( image->len < sizeof ( u.dos ) ) {
404  DBGC ( image, "EFIIMAGE %s too short for DOS header\n",
405  image->name );
406  return -ENOEXEC;
407  }
408  copy_from_user ( &u.dos, image->data, 0, sizeof ( u.dos ) );
409  if ( u.dos.e_magic != EFI_IMAGE_DOS_SIGNATURE ) {
410  DBGC ( image, "EFIIMAGE %s missing MZ signature\n",
411  image->name );
412  return -ENOEXEC;
413  }
414 
415  /* Check for existence of PE header */
416  if ( ( image->len < u.dos.e_lfanew ) ||
417  ( ( image->len - u.dos.e_lfanew ) < sizeof ( u.pe ) ) ) {
418  DBGC ( image, "EFIIMAGE %s too short for PE header\n",
419  image->name );
420  return -ENOEXEC;
421  }
422  copy_from_user ( &u.pe, image->data, u.dos.e_lfanew, sizeof ( u.pe ) );
423  if ( u.pe.Pe32.Signature != EFI_IMAGE_NT_SIGNATURE ) {
424  DBGC ( image, "EFIIMAGE %s missing PE signature\n",
425  image->name );
426  return -ENOEXEC;
427  }
428 
429  /* Check PE header magic */
430  if ( u.pe.Pe32.OptionalHeader.Magic != magic ) {
431  DBGC ( image, "EFIIMAGE %s incorrect magic %04x\n",
432  image->name, u.pe.Pe32.OptionalHeader.Magic );
433  return -ENOEXEC;
434  }
435 
436  return 0;
437 }
userptr_t data
Raw file image.
Definition: image.h:41
#define ENOEXEC
Exec format error.
Definition: errno.h:519
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
Definition: uaccess.h:337
#define DBGC(...)
Definition: compiler.h:505
Union of PE32, PE32+, and TE headers.
Definition: PeImage.h:805
uint32_t magic
Magic signature.
Definition: fdt.h:12
#define EFI_IMAGE_DOS_SIGNATURE
Definition: PeImage.h:50
An executable image.
Definition: image.h:24
#define EFI_IMAGE_NT_SIGNATURE
Definition: PeImage.h:53
unsigned short UINT16
size_t len
Length of raw file image.
Definition: image.h:43
UINT64 UINTN
Unsigned value of native width.
unsigned int uint32_t
Definition: stdint.h:12
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
union @17 u
#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:34

References copy_from_user(), image::data, DBGC, EFI_IMAGE_DOS_SIGNATURE, EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC, EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC, EFI_IMAGE_NT_SIGNATURE, ENOEXEC, image::len, magic, image::name, and u.

◆ __image_type()

struct image_type efi_image_type [] __image_type ( PROBE_NORMAL  )

EFI image types.