Browse Source

[efi] Wrap any images loaded by our wrapped image

Propagate our modified EFI system table to any images loaded by the
image that we wrap, thereby allowing us to observe boot services calls
made by all subsequent EFI images.

Also show details of intercepted ExitBootServices() calls.  When
wrapping is used, exiting boot services will almost certainly fail,
but this at least allows us to see when it happens.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 10 years ago
parent
commit
0cc2f42f46

+ 1
- 1
src/image/efi_image.c View File

227
 	efi_snp_release();
227
 	efi_snp_release();
228
 
228
 
229
 	/* Wrap calls made by the loaded image (for debugging) */
229
 	/* Wrap calls made by the loaded image (for debugging) */
230
-	efi_wrap ( handle, loaded.image );
230
+	efi_wrap ( handle );
231
 
231
 
232
 	/* Start the image */
232
 	/* Start the image */
233
 	if ( ( efirc = bs->StartImage ( handle, NULL, NULL ) ) != 0 ) {
233
 	if ( ( efirc = bs->StartImage ( handle, NULL, NULL ) ) != 0 ) {

+ 1
- 2
src/include/ipxe/efi/efi_wrap.h View File

9
 FILE_LICENCE ( GPL2_OR_LATER );
9
 FILE_LICENCE ( GPL2_OR_LATER );
10
 
10
 
11
 #include <ipxe/efi/efi.h>
11
 #include <ipxe/efi/efi.h>
12
-#include <ipxe/efi/Protocol/LoadedImage.h>
13
 
12
 
14
-extern void efi_wrap ( EFI_HANDLE handle, EFI_LOADED_IMAGE_PROTOCOL *loaded );
13
+extern void efi_wrap ( EFI_HANDLE handle );
15
 
14
 
16
 #endif /* _IPXE_EFI_WRAP_H */
15
 #endif /* _IPXE_EFI_WRAP_H */

+ 1
- 0
src/include/ipxe/errfile.h View File

306
 #define ERRFILE_xenbus		      ( ERRFILE_OTHER | 0x00430000 )
306
 #define ERRFILE_xenbus		      ( ERRFILE_OTHER | 0x00430000 )
307
 #define ERRFILE_xengrant	      ( ERRFILE_OTHER | 0x00440000 )
307
 #define ERRFILE_xengrant	      ( ERRFILE_OTHER | 0x00440000 )
308
 #define ERRFILE_efi_utils	      ( ERRFILE_OTHER | 0x00450000 )
308
 #define ERRFILE_efi_utils	      ( ERRFILE_OTHER | 0x00450000 )
309
+#define ERRFILE_efi_wrap	      ( ERRFILE_OTHER | 0x00460000 )
309
 
310
 
310
 /** @} */
311
 /** @} */
311
 
312
 

+ 67
- 21
src/interface/efi/efi_wrap.c View File

28
 
28
 
29
 #include <string.h>
29
 #include <string.h>
30
 #include <stdio.h>
30
 #include <stdio.h>
31
+#include <errno.h>
31
 #include <ipxe/efi/efi.h>
32
 #include <ipxe/efi/efi.h>
32
 #include <ipxe/efi/Protocol/LoadedImage.h>
33
 #include <ipxe/efi/Protocol/LoadedImage.h>
33
 #include <ipxe/efi/efi_wrap.h>
34
 #include <ipxe/efi/efi_wrap.h>
135
 	return efirc;
136
 	return efirc;
136
 }
137
 }
137
 
138
 
139
+/**
140
+ * Wrap LocateDevicePath()
141
+ *
142
+ */
143
+static EFI_STATUS EFIAPI
144
+efi_locate_device_path_wrapper ( EFI_GUID *protocol,
145
+				 EFI_DEVICE_PATH_PROTOCOL **device_path,
146
+				 EFI_HANDLE *device ) {
147
+	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
148
+	void *retaddr = __builtin_return_address ( 0 );
149
+	EFI_STATUS efirc;
150
+
151
+	DBGC ( colour, "LocateDevicePath ( %s, %s, ... ) ",
152
+	       efi_guid_ntoa ( protocol ), efi_devpath_text ( *device_path ) );
153
+	efirc = bs->LocateDevicePath ( protocol, device_path, device );
154
+	DBGC ( colour, "= %s ( %p, ",
155
+	       efi_status ( efirc ), efi_devpath_text ( *device_path ) );
156
+	DBGC ( colour, "%p %s ) -> %p\n",
157
+	       *device, efi_handle_name ( *device ), retaddr );
158
+	return efirc;
159
+}
160
+
138
 /**
161
 /**
139
  * Wrap LoadImage()
162
  * Wrap LoadImage()
140
  *
163
  *
161
 		       efi_handle_name ( *image_handle ) );
184
 		       efi_handle_name ( *image_handle ) );
162
 	}
185
 	}
163
 	DBGC ( colour, ") -> %p\n", retaddr );
186
 	DBGC ( colour, ") -> %p\n", retaddr );
187
+
188
+	/* Wrap the new image */
189
+	if ( efirc == 0 )
190
+		efi_wrap ( *image_handle );
191
+
164
 	return efirc;
192
 	return efirc;
165
 }
193
 }
166
 
194
 
167
 /**
195
 /**
168
- * Wrap LocateDevicePath()
196
+ * Wrap ExitBootServices()
169
  *
197
  *
170
  */
198
  */
171
 static EFI_STATUS EFIAPI
199
 static EFI_STATUS EFIAPI
172
-efi_locate_device_path_wrapper ( EFI_GUID *protocol,
173
-				 EFI_DEVICE_PATH_PROTOCOL **device_path,
174
-				 EFI_HANDLE *device ) {
200
+efi_exit_boot_services_wrapper ( EFI_HANDLE image_handle, UINTN map_key ) {
175
 	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
201
 	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
176
 	void *retaddr = __builtin_return_address ( 0 );
202
 	void *retaddr = __builtin_return_address ( 0 );
177
 	EFI_STATUS efirc;
203
 	EFI_STATUS efirc;
178
 
204
 
179
-	DBGC ( colour, "LocateDevicePath ( %s, %s, ... ) ",
180
-	       efi_guid_ntoa ( protocol ), efi_devpath_text ( *device_path ) );
181
-	efirc = bs->LocateDevicePath ( protocol, device_path, device );
182
-	DBGC ( colour, "= %s ( %p, ",
183
-	       efi_status ( efirc ), efi_devpath_text ( *device_path ) );
184
-	DBGC ( colour, "%p %s ) -> %p\n",
185
-	       *device, efi_handle_name ( *device ), retaddr );
205
+	DBGC ( colour, "ExitBootServices ( %p %s, %#llx ) ",
206
+	       image_handle, efi_handle_name ( image_handle ),
207
+	       ( ( unsigned long long ) map_key ) );
208
+	efirc = bs->ExitBootServices ( image_handle, map_key );
209
+	DBGC ( colour, "= %s -> %p\n", efi_status ( efirc ), retaddr );
186
 	return efirc;
210
 	return efirc;
187
 }
211
 }
188
 
212
 
234
  * Wrap the calls made by a loaded image
258
  * Wrap the calls made by a loaded image
235
  *
259
  *
236
  * @v handle		Image handle
260
  * @v handle		Image handle
237
- * @v loaded		Loaded image protocol
238
  */
261
  */
239
-void efi_wrap ( EFI_HANDLE handle, EFI_LOADED_IMAGE_PROTOCOL *loaded ) {
262
+ void efi_wrap ( EFI_HANDLE handle ) {
240
 	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
263
 	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
264
+	union {
265
+		EFI_LOADED_IMAGE_PROTOCOL *image;
266
+		void *intf;
267
+	} loaded;
268
+	EFI_STATUS efirc;
269
+	int rc;
241
 
270
 
242
 	/* Do nothing unless debugging is enabled */
271
 	/* Do nothing unless debugging is enabled */
243
 	if ( ! DBG_LOG )
272
 	if ( ! DBG_LOG )
252
 	efi_bs_wrapper.LocateHandle	= efi_locate_handle_wrapper;
281
 	efi_bs_wrapper.LocateHandle	= efi_locate_handle_wrapper;
253
 	efi_bs_wrapper.LocateDevicePath	= efi_locate_device_path_wrapper;
282
 	efi_bs_wrapper.LocateDevicePath	= efi_locate_device_path_wrapper;
254
 	efi_bs_wrapper.LoadImage	= efi_load_image_wrapper;
283
 	efi_bs_wrapper.LoadImage	= efi_load_image_wrapper;
284
+	efi_bs_wrapper.ExitBootServices	= efi_exit_boot_services_wrapper;
255
 	efi_bs_wrapper.OpenProtocol	= efi_open_protocol_wrapper;
285
 	efi_bs_wrapper.OpenProtocol	= efi_open_protocol_wrapper;
256
 	efi_bs_wrapper.LocateProtocol	= efi_locate_protocol_wrapper;
286
 	efi_bs_wrapper.LocateProtocol	= efi_locate_protocol_wrapper;
257
 
287
 
288
+	/* Open loaded image protocol */
289
+	if ( ( efirc = bs->OpenProtocol ( handle,
290
+					  &efi_loaded_image_protocol_guid,
291
+					  &loaded.intf, efi_image_handle, NULL,
292
+					  EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
293
+		rc = -EEFI ( efirc );
294
+		DBGC ( colour, "Could not get loaded image protocol for %p %s: "
295
+		       "%s\n", handle, efi_handle_name ( handle ),
296
+		       strerror ( rc ) );
297
+		return;
298
+	}
299
+
258
 	/* Provide system table wrapper to image */
300
 	/* Provide system table wrapper to image */
259
-	loaded->SystemTable = &efi_systab_wrapper;
301
+	loaded.image->SystemTable = &efi_systab_wrapper;
260
 	DBGC ( colour, "Wrapped image %p %s at base %p has protocols:\n",
302
 	DBGC ( colour, "Wrapped image %p %s at base %p has protocols:\n",
261
-	       handle, efi_handle_name ( handle ), loaded->ImageBase );
303
+	       handle, efi_handle_name ( handle ), loaded.image->ImageBase );
262
 	DBGC_EFI_PROTOCOLS ( colour, handle );
304
 	DBGC_EFI_PROTOCOLS ( colour, handle );
263
-	DBGC ( colour, "Parent image %p %s\n", loaded->ParentHandle,
264
-	       efi_handle_name ( loaded->ParentHandle ) );
265
-	DBGC ( colour, "Device %p %s ", loaded->DeviceHandle,
266
-	       efi_handle_name ( loaded->DeviceHandle ) );
267
-	DBGC ( colour, "file %p %s\n", loaded->FilePath,
268
-	       efi_devpath_text ( loaded->FilePath ) );
305
+	DBGC ( colour, "Parent image %p %s\n", loaded.image->ParentHandle,
306
+	       efi_handle_name ( loaded.image->ParentHandle ) );
307
+	DBGC ( colour, "Device %p %s ", loaded.image->DeviceHandle,
308
+	       efi_handle_name ( loaded.image->DeviceHandle ) );
309
+	DBGC ( colour, "file %p %s\n", loaded.image->FilePath,
310
+	       efi_devpath_text ( loaded.image->FilePath ) );
311
+
312
+	/* Close loaded image protocol */
313
+	bs->CloseProtocol ( handle, &efi_loaded_image_protocol_guid,
314
+			    efi_image_handle, NULL );
269
 }
315
 }

Loading…
Cancel
Save