blob: f9b0ef591cc89a88e78a6cb6279892abc5d09e54 [file] [log] [blame]
AKASHI Takahiro473d9b32020-11-17 09:27:55 +09001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * EFI Capsule
4 *
5 * Copyright (c) 2018 Linaro Limited
6 * Author: AKASHI Takahiro
7 */
8
Heinrich Schuchardte3087a12021-07-10 11:03:27 +02009#define LOG_CATEGORY LOGC_EFI
10
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090011#include <common.h>
12#include <efi_loader.h>
13#include <efi_variable.h>
14#include <fs.h>
15#include <malloc.h>
AKASHI Takahiro45b819542020-11-17 09:27:56 +090016#include <mapmem.h>
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090017#include <sort.h>
18
Ilias Apalodimas27e059c2021-07-17 17:26:44 +030019#include <asm/sections.h>
Sughosh Ganu586bb982020-12-30 19:27:09 +053020#include <crypto/pkcs7.h>
21#include <crypto/pkcs7_parser.h>
22#include <linux/err.h>
23
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090024const efi_guid_t efi_guid_capsule_report = EFI_CAPSULE_REPORT_GUID;
AKASHI Takahiro0d963782020-11-30 18:12:11 +090025static const efi_guid_t efi_guid_firmware_management_capsule_id =
26 EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID;
27const efi_guid_t efi_guid_firmware_management_protocol =
28 EFI_FIRMWARE_MANAGEMENT_PROTOCOL_GUID;
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090029
AKASHI Takahiro45b819542020-11-17 09:27:56 +090030#ifdef CONFIG_EFI_CAPSULE_ON_DISK
31/* for file system access */
32static struct efi_file_handle *bootdev_root;
33#endif
34
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090035/**
36 * get_last_capsule - get the last capsule index
37 *
38 * Retrieve the index of the capsule invoked last time from "CapsuleLast"
39 * variable.
40 *
41 * Return:
42 * * > 0 - the last capsule index invoked
43 * * 0xffff - on error, or no capsule invoked yet
44 */
45static __maybe_unused unsigned int get_last_capsule(void)
46{
47 u16 value16[11]; /* "CapsuleXXXX": non-null-terminated */
Heinrich Schuchardt812f6e02021-02-09 20:20:34 +010048 char value[5];
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090049 efi_uintn_t size;
50 unsigned long index = 0xffff;
51 efi_status_t ret;
Heinrich Schuchardt812f6e02021-02-09 20:20:34 +010052 int i;
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090053
54 size = sizeof(value16);
55 ret = efi_get_variable_int(L"CapsuleLast", &efi_guid_capsule_report,
56 NULL, &size, value16, NULL);
Heinrich Schuchardt812f6e02021-02-09 20:20:34 +010057 if (ret != EFI_SUCCESS || size != 22 ||
58 u16_strncmp(value16, L"Capsule", 7))
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090059 goto err;
Heinrich Schuchardt812f6e02021-02-09 20:20:34 +010060 for (i = 0; i < 4; ++i) {
61 u16 c = value16[i + 7];
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090062
Heinrich Schuchardt812f6e02021-02-09 20:20:34 +010063 if (!c || c > 0x7f)
64 goto err;
65 value[i] = c;
66 }
67 value[4] = 0;
68 if (strict_strtoul(value, 16, &index))
69 index = 0xffff;
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090070err:
71 return index;
72}
73
74/**
75 * set_capsule_result - set a result variable
76 * @capsule: Capsule
77 * @return_status: Return status
78 *
79 * Create and set a result variable, "CapsuleXXXX", for the capsule,
80 * @capsule.
81 */
82static __maybe_unused
83void set_capsule_result(int index, struct efi_capsule_header *capsule,
84 efi_status_t return_status)
85{
86 u16 variable_name16[12];
87 struct efi_capsule_result_variable_header result;
88 struct efi_time time;
89 efi_status_t ret;
90
Ilias Apalodimas21575292020-12-31 12:26:46 +020091 efi_create_indexed_name(variable_name16, sizeof(variable_name16),
92 "Capsule", index);
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090093 result.variable_total_size = sizeof(result);
94 result.capsule_guid = capsule->capsule_guid;
95 ret = EFI_CALL((*efi_runtime_services.get_time)(&time, NULL));
96 if (ret == EFI_SUCCESS)
97 memcpy(&result.capsule_processed, &time, sizeof(time));
98 else
99 memset(&result.capsule_processed, 0, sizeof(time));
100 result.capsule_status = return_status;
Heinrich Schuchardt24adaa72021-07-10 11:10:26 +0200101 ret = efi_set_variable_int(variable_name16, &efi_guid_capsule_report,
102 EFI_VARIABLE_NON_VOLATILE |
103 EFI_VARIABLE_BOOTSERVICE_ACCESS |
104 EFI_VARIABLE_RUNTIME_ACCESS,
105 sizeof(result), &result, false);
Heinrich Schuchardtb1fae8c2021-07-10 11:14:13 +0200106 if (ret != EFI_SUCCESS) {
Heinrich Schuchardte3087a12021-07-10 11:03:27 +0200107 log_err("Setting %ls failed\n", variable_name16);
Heinrich Schuchardtb1fae8c2021-07-10 11:14:13 +0200108 return;
109 }
110
111 /* Variable CapsuleLast must not include terminating 0x0000 */
112 ret = efi_set_variable_int(L"CapsuleLast", &efi_guid_capsule_report,
113 EFI_VARIABLE_READ_ONLY |
114 EFI_VARIABLE_NON_VOLATILE |
115 EFI_VARIABLE_BOOTSERVICE_ACCESS |
116 EFI_VARIABLE_RUNTIME_ACCESS,
117 22, variable_name16, false);
118 if (ret != EFI_SUCCESS)
119 log_err("Setting %ls failed\n", L"CapsuleLast");
AKASHI Takahiro473d9b32020-11-17 09:27:55 +0900120}
121
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900122#ifdef CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT
123/**
124 * efi_fmp_find - search for Firmware Management Protocol drivers
125 * @image_type: Image type guid
126 * @instance: Instance number
127 * @handles: Handles of FMP drivers
128 * @no_handles: Number of handles
129 *
130 * Search for Firmware Management Protocol drivers, matching the image
131 * type, @image_type and the machine instance, @instance, from the list,
132 * @handles.
133 *
134 * Return:
135 * * Protocol instance - on success
136 * * NULL - on failure
137 */
138static struct efi_firmware_management_protocol *
139efi_fmp_find(efi_guid_t *image_type, u64 instance, efi_handle_t *handles,
140 efi_uintn_t no_handles)
141{
142 efi_handle_t *handle;
143 struct efi_firmware_management_protocol *fmp;
144 struct efi_firmware_image_descriptor *image_info, *desc;
145 efi_uintn_t info_size, descriptor_size;
146 u32 descriptor_version;
147 u8 descriptor_count;
148 u32 package_version;
149 u16 *package_version_name;
150 bool found = false;
151 int i, j;
152 efi_status_t ret;
153
154 for (i = 0, handle = handles; i < no_handles; i++, handle++) {
155 ret = EFI_CALL(efi_handle_protocol(
156 *handle,
157 &efi_guid_firmware_management_protocol,
158 (void **)&fmp));
159 if (ret != EFI_SUCCESS)
160 continue;
161
162 /* get device's image info */
163 info_size = 0;
164 image_info = NULL;
165 descriptor_version = 0;
166 descriptor_count = 0;
167 descriptor_size = 0;
168 package_version = 0;
169 package_version_name = NULL;
170 ret = EFI_CALL(fmp->get_image_info(fmp, &info_size,
171 image_info,
172 &descriptor_version,
173 &descriptor_count,
174 &descriptor_size,
175 &package_version,
176 &package_version_name));
177 if (ret != EFI_BUFFER_TOO_SMALL)
178 goto skip;
179
180 image_info = malloc(info_size);
181 if (!image_info)
182 goto skip;
183
184 ret = EFI_CALL(fmp->get_image_info(fmp, &info_size,
185 image_info,
186 &descriptor_version,
187 &descriptor_count,
188 &descriptor_size,
189 &package_version,
190 &package_version_name));
191 if (ret != EFI_SUCCESS ||
192 descriptor_version != EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION)
193 goto skip;
194
195 /* matching */
196 for (j = 0, desc = image_info; j < descriptor_count;
197 j++, desc = (void *)desc + descriptor_size) {
198 log_debug("+++ desc[%d] index: %d, name: %ls\n",
199 j, desc->image_index, desc->image_id_name);
200 if (!guidcmp(&desc->image_type_id, image_type) &&
201 (!instance ||
202 !desc->hardware_instance ||
203 desc->hardware_instance == instance))
204 found = true;
205 }
206
207skip:
208 efi_free_pool(package_version_name);
209 free(image_info);
210 EFI_CALL(efi_close_protocol(
211 (efi_handle_t)fmp,
212 &efi_guid_firmware_management_protocol,
213 NULL, NULL));
214 if (found)
215 return fmp;
216 }
217
218 return NULL;
219}
220
Sughosh Ganu586bb982020-12-30 19:27:09 +0530221#if defined(CONFIG_EFI_CAPSULE_AUTHENTICATE)
222
223const efi_guid_t efi_guid_capsule_root_cert_guid =
224 EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID;
225
Ilias Apalodimas27e059c2021-07-17 17:26:44 +0300226static int efi_get_public_key_data(void **pkey, efi_uintn_t *pkey_len)
227{
228 const void *blob = __efi_capsule_sig_begin;
229 const int len = __efi_capsule_sig_end - __efi_capsule_sig_begin;
230
231 *pkey = (void *)blob;
232 *pkey_len = len;
233
234 return 0;
235}
236
Sughosh Ganu586bb982020-12-30 19:27:09 +0530237efi_status_t efi_capsule_authenticate(const void *capsule, efi_uintn_t capsule_size,
238 void **image, efi_uintn_t *image_size)
239{
240 u8 *buf;
241 int ret;
Ilias Apalodimas27e059c2021-07-17 17:26:44 +0300242 void *stored_pkey, *pkey;
Sughosh Ganu586bb982020-12-30 19:27:09 +0530243 efi_uintn_t pkey_len;
244 uint64_t monotonic_count;
245 struct efi_signature_store *truststore;
246 struct pkcs7_message *capsule_sig;
247 struct efi_image_regions *regs;
248 struct efi_firmware_image_authentication *auth_hdr;
249 efi_status_t status;
250
251 status = EFI_SECURITY_VIOLATION;
252 capsule_sig = NULL;
253 truststore = NULL;
254 regs = NULL;
255
256 /* Sanity checks */
257 if (capsule == NULL || capsule_size == 0)
258 goto out;
259
260 auth_hdr = (struct efi_firmware_image_authentication *)capsule;
261 if (capsule_size < sizeof(*auth_hdr))
262 goto out;
263
264 if (auth_hdr->auth_info.hdr.dwLength <=
265 offsetof(struct win_certificate_uefi_guid, cert_data))
266 goto out;
267
268 if (guidcmp(&auth_hdr->auth_info.cert_type, &efi_guid_cert_type_pkcs7))
269 goto out;
270
271 *image = (uint8_t *)capsule + sizeof(auth_hdr->monotonic_count) +
272 auth_hdr->auth_info.hdr.dwLength;
273 *image_size = capsule_size - auth_hdr->auth_info.hdr.dwLength -
274 sizeof(auth_hdr->monotonic_count);
275 memcpy(&monotonic_count, &auth_hdr->monotonic_count,
276 sizeof(monotonic_count));
277
278 /* data to be digested */
279 regs = calloc(sizeof(*regs) + sizeof(struct image_region) * 2, 1);
280 if (!regs)
281 goto out;
282
283 regs->max = 2;
284 efi_image_region_add(regs, (uint8_t *)*image,
285 (uint8_t *)*image + *image_size, 1);
286
287 efi_image_region_add(regs, (uint8_t *)&monotonic_count,
288 (uint8_t *)&monotonic_count + sizeof(monotonic_count),
289 1);
290
291 capsule_sig = efi_parse_pkcs7_header(auth_hdr->auth_info.cert_data,
292 auth_hdr->auth_info.hdr.dwLength
293 - sizeof(auth_hdr->auth_info),
294 &buf);
295 if (IS_ERR(capsule_sig)) {
296 debug("Parsing variable's pkcs7 header failed\n");
297 capsule_sig = NULL;
298 goto out;
299 }
300
Ilias Apalodimas27e059c2021-07-17 17:26:44 +0300301 ret = efi_get_public_key_data(&stored_pkey, &pkey_len);
Sughosh Ganu586bb982020-12-30 19:27:09 +0530302 if (ret < 0)
303 goto out;
304
305 pkey = malloc(pkey_len);
306 if (!pkey)
307 goto out;
308
Ilias Apalodimas27e059c2021-07-17 17:26:44 +0300309 memcpy(pkey, stored_pkey, pkey_len);
Sughosh Ganu586bb982020-12-30 19:27:09 +0530310 truststore = efi_build_signature_store(pkey, pkey_len);
311 if (!truststore)
312 goto out;
313
314 /* verify signature */
315 if (efi_signature_verify(regs, capsule_sig, truststore, NULL)) {
316 debug("Verified\n");
317 } else {
318 debug("Verifying variable's signature failed\n");
319 goto out;
320 }
321
322 status = EFI_SUCCESS;
323
324out:
325 efi_sigstore_free(truststore);
326 pkcs7_free_message(capsule_sig);
327 free(regs);
328
329 return status;
330}
331#else
332efi_status_t efi_capsule_authenticate(const void *capsule, efi_uintn_t capsule_size,
333 void **image, efi_uintn_t *image_size)
334{
335 return EFI_UNSUPPORTED;
336}
337#endif /* CONFIG_EFI_CAPSULE_AUTHENTICATE */
338
339
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900340/**
341 * efi_capsule_update_firmware - update firmware from capsule
342 * @capsule_data: Capsule
343 *
344 * Update firmware, using a capsule, @capsule_data. Loading any FMP
345 * drivers embedded in a capsule is not supported.
346 *
347 * Return: status code
348 */
349static efi_status_t efi_capsule_update_firmware(
350 struct efi_capsule_header *capsule_data)
351{
352 struct efi_firmware_management_capsule_header *capsule;
353 struct efi_firmware_management_capsule_image_header *image;
354 size_t capsule_size;
355 void *image_binary, *vendor_code;
356 efi_handle_t *handles;
357 efi_uintn_t no_handles;
358 int item;
359 struct efi_firmware_management_protocol *fmp;
360 u16 *abort_reason;
361 efi_status_t ret = EFI_SUCCESS;
362
363 /* sanity check */
364 if (capsule_data->header_size < sizeof(*capsule) ||
365 capsule_data->header_size >= capsule_data->capsule_image_size)
366 return EFI_INVALID_PARAMETER;
367
368 capsule = (void *)capsule_data + capsule_data->header_size;
369 capsule_size = capsule_data->capsule_image_size
370 - capsule_data->header_size;
371
372 if (capsule->version != 0x00000001)
373 return EFI_UNSUPPORTED;
374
375 handles = NULL;
376 ret = EFI_CALL(efi_locate_handle_buffer(
377 BY_PROTOCOL,
378 &efi_guid_firmware_management_protocol,
379 NULL, &no_handles, (efi_handle_t **)&handles));
380 if (ret != EFI_SUCCESS)
381 return EFI_UNSUPPORTED;
382
383 /* Payload */
384 for (item = capsule->embedded_driver_count;
385 item < capsule->embedded_driver_count
386 + capsule->payload_item_count; item++) {
387 /* sanity check */
388 if ((capsule->item_offset_list[item] + sizeof(*image)
389 >= capsule_size)) {
Heinrich Schuchardte3087a12021-07-10 11:03:27 +0200390 log_err("Capsule does not have enough data\n");
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900391 ret = EFI_INVALID_PARAMETER;
392 goto out;
393 }
394
395 image = (void *)capsule + capsule->item_offset_list[item];
396
397 if (image->version != 0x00000003) {
398 ret = EFI_UNSUPPORTED;
399 goto out;
400 }
401
402 /* find a device for update firmware */
403 /* TODO: should we pass index as well, or nothing but type? */
404 fmp = efi_fmp_find(&image->update_image_type_id,
405 image->update_hardware_instance,
406 handles, no_handles);
407 if (!fmp) {
Heinrich Schuchardte3087a12021-07-10 11:03:27 +0200408 log_err("FMP driver not found for firmware type %pUl, hardware instance %lld\n",
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900409 &image->update_image_type_id,
410 image->update_hardware_instance);
411 ret = EFI_UNSUPPORTED;
412 goto out;
413 }
414
415 /* do update */
416 image_binary = (void *)image + sizeof(*image);
417 vendor_code = image_binary + image->update_image_size;
418
419 abort_reason = NULL;
420 ret = EFI_CALL(fmp->set_image(fmp, image->update_image_index,
421 image_binary,
422 image->update_image_size,
423 vendor_code, NULL,
424 &abort_reason));
425 if (ret != EFI_SUCCESS) {
Heinrich Schuchardte3087a12021-07-10 11:03:27 +0200426 log_err("Firmware update failed: %ls\n",
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900427 abort_reason);
428 efi_free_pool(abort_reason);
429 goto out;
430 }
431 }
432
433out:
434 efi_free_pool(handles);
435
436 return ret;
437}
438#else
439static efi_status_t efi_capsule_update_firmware(
440 struct efi_capsule_header *capsule_data)
441{
442 return EFI_UNSUPPORTED;
443}
444#endif /* CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT */
445
AKASHI Takahiro473d9b32020-11-17 09:27:55 +0900446/**
447 * efi_update_capsule() - process information from operating system
448 * @capsule_header_array: Array of virtual address pointers
449 * @capsule_count: Number of pointers in capsule_header_array
450 * @scatter_gather_list: Array of physical address pointers
451 *
452 * This function implements the UpdateCapsule() runtime service.
453 *
454 * See the Unified Extensible Firmware Interface (UEFI) specification for
455 * details.
456 *
457 * Return: status code
458 */
459efi_status_t EFIAPI efi_update_capsule(
460 struct efi_capsule_header **capsule_header_array,
461 efi_uintn_t capsule_count,
462 u64 scatter_gather_list)
463{
464 struct efi_capsule_header *capsule;
465 unsigned int i;
466 efi_status_t ret;
467
Simon Glass83698b22021-02-07 14:27:02 -0700468 EFI_ENTRY("%p, %zu, %llu\n", capsule_header_array, capsule_count,
AKASHI Takahiro473d9b32020-11-17 09:27:55 +0900469 scatter_gather_list);
470
471 if (!capsule_count) {
472 ret = EFI_INVALID_PARAMETER;
473 goto out;
474 }
475
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900476 ret = EFI_SUCCESS;
AKASHI Takahiro473d9b32020-11-17 09:27:55 +0900477 for (i = 0, capsule = *capsule_header_array; i < capsule_count;
478 i++, capsule = *(++capsule_header_array)) {
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900479 /* sanity check */
480 if (capsule->header_size < sizeof(*capsule) ||
481 capsule->capsule_image_size < sizeof(*capsule)) {
Heinrich Schuchardte3087a12021-07-10 11:03:27 +0200482 log_err("Capsule does not have enough data\n");
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900483 continue;
484 }
485
486 log_debug("Capsule[%d] (guid:%pUl)\n",
487 i, &capsule->capsule_guid);
488 if (!guidcmp(&capsule->capsule_guid,
489 &efi_guid_firmware_management_capsule_id)) {
490 ret = efi_capsule_update_firmware(capsule);
491 } else {
Heinrich Schuchardte3087a12021-07-10 11:03:27 +0200492 log_err("Unsupported capsule type: %pUl\n",
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900493 &capsule->capsule_guid);
494 ret = EFI_UNSUPPORTED;
495 }
496
497 if (ret != EFI_SUCCESS)
498 goto out;
AKASHI Takahiro473d9b32020-11-17 09:27:55 +0900499 }
Jose Marinhoebb61ee2021-03-02 17:26:38 +0000500
501 if (IS_ENABLED(CONFIG_EFI_ESRT)) {
502 /* Rebuild the ESRT to reflect any updated FW images. */
503 ret = efi_esrt_populate();
504 if (ret != EFI_SUCCESS)
Heinrich Schuchardte3087a12021-07-10 11:03:27 +0200505 log_warning("ESRT update failed\n");
Jose Marinhoebb61ee2021-03-02 17:26:38 +0000506 }
Jose Marinhoaf886ce2021-04-19 14:54:33 +0100507out:
Jose Marinhoebb61ee2021-03-02 17:26:38 +0000508
AKASHI Takahiro473d9b32020-11-17 09:27:55 +0900509 return EFI_EXIT(ret);
510}
511
512/**
513 * efi_query_capsule_caps() - check if capsule is supported
514 * @capsule_header_array: Array of virtual pointers
515 * @capsule_count: Number of pointers in capsule_header_array
516 * @maximum_capsule_size: Maximum capsule size
517 * @reset_type: Type of reset needed for capsule update
518 *
519 * This function implements the QueryCapsuleCapabilities() runtime service.
520 *
521 * See the Unified Extensible Firmware Interface (UEFI) specification for
522 * details.
523 *
524 * Return: status code
525 */
526efi_status_t EFIAPI efi_query_capsule_caps(
527 struct efi_capsule_header **capsule_header_array,
528 efi_uintn_t capsule_count,
529 u64 *maximum_capsule_size,
530 u32 *reset_type)
531{
532 struct efi_capsule_header *capsule __attribute__((unused));
533 unsigned int i;
534 efi_status_t ret;
535
Simon Glass83698b22021-02-07 14:27:02 -0700536 EFI_ENTRY("%p, %zu, %p, %p\n", capsule_header_array, capsule_count,
AKASHI Takahiro473d9b32020-11-17 09:27:55 +0900537 maximum_capsule_size, reset_type);
538
539 if (!maximum_capsule_size) {
540 ret = EFI_INVALID_PARAMETER;
541 goto out;
542 }
543
544 *maximum_capsule_size = U64_MAX;
545 *reset_type = EFI_RESET_COLD;
546
547 ret = EFI_SUCCESS;
548 for (i = 0, capsule = *capsule_header_array; i < capsule_count;
549 i++, capsule = *(++capsule_header_array)) {
550 /* TODO */
551 }
552out:
553 return EFI_EXIT(ret);
554}
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900555
556#ifdef CONFIG_EFI_CAPSULE_ON_DISK
557/**
558 * get_dp_device - retrieve a device path from boot variable
559 * @boot_var: Boot variable name
560 * @device_dp Device path
561 *
562 * Retrieve a device patch from boot variable, @boot_var.
563 *
564 * Return: status code
565 */
566static efi_status_t get_dp_device(u16 *boot_var,
567 struct efi_device_path **device_dp)
568{
569 void *buf = NULL;
570 efi_uintn_t size;
571 struct efi_load_option lo;
572 struct efi_device_path *file_dp;
573 efi_status_t ret;
574
575 size = 0;
576 ret = efi_get_variable_int(boot_var, &efi_global_variable_guid,
577 NULL, &size, NULL, NULL);
578 if (ret == EFI_BUFFER_TOO_SMALL) {
579 buf = malloc(size);
580 if (!buf)
581 return EFI_OUT_OF_RESOURCES;
582 ret = efi_get_variable_int(boot_var, &efi_global_variable_guid,
583 NULL, &size, buf, NULL);
584 }
585 if (ret != EFI_SUCCESS)
586 return ret;
587
588 efi_deserialize_load_option(&lo, buf, &size);
589
590 if (lo.attributes & LOAD_OPTION_ACTIVE) {
591 efi_dp_split_file_path(lo.file_path, device_dp, &file_dp);
592 efi_free_pool(file_dp);
593
594 ret = EFI_SUCCESS;
595 } else {
596 ret = EFI_NOT_FOUND;
597 }
598
599 free(buf);
600
601 return ret;
602}
603
604/**
605 * device_is_present_and_system_part - check if a device exists
606 * @dp Device path
607 *
608 * Check if a device pointed to by the device path, @dp, exists and is
609 * located in UEFI system partition.
610 *
611 * Return: true - yes, false - no
612 */
613static bool device_is_present_and_system_part(struct efi_device_path *dp)
614{
615 efi_handle_t handle;
616
617 handle = efi_dp_find_obj(dp, NULL);
618 if (!handle)
619 return false;
620
621 return efi_disk_is_system_part(handle);
622}
623
624/**
625 * find_boot_device - identify the boot device
626 *
627 * Identify the boot device from boot-related variables as UEFI
628 * specification describes and put its handle into bootdev_root.
629 *
630 * Return: status code
631 */
632static efi_status_t find_boot_device(void)
633{
634 char boot_var[9];
635 u16 boot_var16[9], *p, bootnext, *boot_order = NULL;
636 efi_uintn_t size;
637 int i, num;
638 struct efi_simple_file_system_protocol *volume;
639 struct efi_device_path *boot_dev = NULL;
640 efi_status_t ret;
641
642 /* find active boot device in BootNext */
643 bootnext = 0;
644 size = sizeof(bootnext);
645 ret = efi_get_variable_int(L"BootNext",
646 (efi_guid_t *)&efi_global_variable_guid,
647 NULL, &size, &bootnext, NULL);
648 if (ret == EFI_SUCCESS || ret == EFI_BUFFER_TOO_SMALL) {
649 /* BootNext does exist here */
650 if (ret == EFI_BUFFER_TOO_SMALL || size != sizeof(u16)) {
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900651 log_err("BootNext must be 16-bit integer\n");
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900652 goto skip;
653 }
654 sprintf((char *)boot_var, "Boot%04X", bootnext);
655 p = boot_var16;
656 utf8_utf16_strcpy(&p, boot_var);
657
658 ret = get_dp_device(boot_var16, &boot_dev);
659 if (ret == EFI_SUCCESS) {
660 if (device_is_present_and_system_part(boot_dev)) {
Masami Hiramatsu10165752021-07-12 18:05:17 +0900661 goto found;
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900662 } else {
663 efi_free_pool(boot_dev);
664 boot_dev = NULL;
665 }
666 }
667 }
668
669skip:
670 /* find active boot device in BootOrder */
671 size = 0;
672 ret = efi_get_variable_int(L"BootOrder", &efi_global_variable_guid,
673 NULL, &size, NULL, NULL);
674 if (ret == EFI_BUFFER_TOO_SMALL) {
675 boot_order = malloc(size);
676 if (!boot_order) {
677 ret = EFI_OUT_OF_RESOURCES;
678 goto out;
679 }
680
681 ret = efi_get_variable_int(L"BootOrder",
682 &efi_global_variable_guid,
683 NULL, &size, boot_order, NULL);
684 }
685 if (ret != EFI_SUCCESS)
686 goto out;
687
688 /* check in higher order */
689 num = size / sizeof(u16);
690 for (i = 0; i < num; i++) {
691 sprintf((char *)boot_var, "Boot%04X", boot_order[i]);
692 p = boot_var16;
693 utf8_utf16_strcpy(&p, boot_var);
694 ret = get_dp_device(boot_var16, &boot_dev);
695 if (ret != EFI_SUCCESS)
696 continue;
697
698 if (device_is_present_and_system_part(boot_dev))
699 break;
700
701 efi_free_pool(boot_dev);
702 boot_dev = NULL;
703 }
Masami Hiramatsu10165752021-07-12 18:05:17 +0900704found:
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900705 if (boot_dev) {
Masami Hiramatsud9763bb2021-07-14 14:19:13 +0900706 log_debug("Boot device %pD\n", boot_dev);
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900707
708 volume = efi_fs_from_path(boot_dev);
709 if (!volume)
710 ret = EFI_DEVICE_ERROR;
711 else
712 ret = EFI_CALL(volume->open_volume(volume,
713 &bootdev_root));
714 efi_free_pool(boot_dev);
715 } else {
716 ret = EFI_NOT_FOUND;
717 }
AKASHI Takahirofa390e62021-04-20 10:03:16 +0900718out:
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900719 free(boot_order);
720
721 return ret;
722}
723
724/**
725 * efi_capsule_scan_dir - traverse a capsule directory in boot device
726 * @files: Array of file names
727 * @num: Number of elements in @files
728 *
729 * Traverse a capsule directory in boot device.
730 * Called by initialization code, and returns an array of capsule file
731 * names in @files.
732 *
733 * Return: status code
734 */
735static efi_status_t efi_capsule_scan_dir(u16 ***files, unsigned int *num)
736{
737 struct efi_file_handle *dirh;
738 struct efi_file_info *dirent;
739 efi_uintn_t dirent_size, tmp_size;
740 unsigned int count;
741 u16 **tmp_files;
742 efi_status_t ret;
743
744 ret = find_boot_device();
745 if (ret == EFI_NOT_FOUND) {
Heinrich Schuchardte3087a12021-07-10 11:03:27 +0200746 log_debug("Boot device is not set\n");
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900747 *num = 0;
748 return EFI_SUCCESS;
749 } else if (ret != EFI_SUCCESS) {
750 return EFI_DEVICE_ERROR;
751 }
752
753 /* count capsule files */
754 ret = EFI_CALL((*bootdev_root->open)(bootdev_root, &dirh,
755 EFI_CAPSULE_DIR,
756 EFI_FILE_MODE_READ, 0));
757 if (ret != EFI_SUCCESS) {
758 *num = 0;
759 return EFI_SUCCESS;
760 }
761
762 dirent_size = 256;
763 dirent = malloc(dirent_size);
764 if (!dirent)
765 return EFI_OUT_OF_RESOURCES;
766
767 count = 0;
768 while (1) {
769 tmp_size = dirent_size;
770 ret = EFI_CALL((*dirh->read)(dirh, &tmp_size, dirent));
771 if (ret == EFI_BUFFER_TOO_SMALL) {
Heinrich Schuchardtaa27e5d2021-04-11 06:53:04 +0200772 struct efi_file_info *old_dirent = dirent;
773
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900774 dirent = realloc(dirent, tmp_size);
775 if (!dirent) {
Heinrich Schuchardtaa27e5d2021-04-11 06:53:04 +0200776 dirent = old_dirent;
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900777 ret = EFI_OUT_OF_RESOURCES;
778 goto err;
779 }
780 dirent_size = tmp_size;
781 ret = EFI_CALL((*dirh->read)(dirh, &tmp_size, dirent));
782 }
783 if (ret != EFI_SUCCESS)
784 goto err;
785 if (!tmp_size)
786 break;
787
Heinrich Schuchardt76b708a2021-02-09 17:45:33 +0100788 if (!(dirent->attribute & EFI_FILE_DIRECTORY))
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900789 count++;
790 }
791
792 ret = EFI_CALL((*dirh->setpos)(dirh, 0));
793 if (ret != EFI_SUCCESS)
794 goto err;
795
796 /* make a list */
AKASHI Takahiroc8fc12f2021-01-22 10:43:27 +0900797 tmp_files = malloc(count * sizeof(*tmp_files));
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900798 if (!tmp_files) {
799 ret = EFI_OUT_OF_RESOURCES;
800 goto err;
801 }
802
803 count = 0;
804 while (1) {
805 tmp_size = dirent_size;
806 ret = EFI_CALL((*dirh->read)(dirh, &tmp_size, dirent));
807 if (ret != EFI_SUCCESS)
808 goto err;
809 if (!tmp_size)
810 break;
811
812 if (!(dirent->attribute & EFI_FILE_DIRECTORY) &&
813 u16_strcmp(dirent->file_name, L".") &&
814 u16_strcmp(dirent->file_name, L".."))
815 tmp_files[count++] = u16_strdup(dirent->file_name);
816 }
817 /* ignore an error */
818 EFI_CALL((*dirh->close)(dirh));
819
820 /* in ascii order */
821 /* FIXME: u16 version of strcasecmp */
822 qsort(tmp_files, count, sizeof(*tmp_files),
823 (int (*)(const void *, const void *))strcasecmp);
824 *files = tmp_files;
825 *num = count;
826 ret = EFI_SUCCESS;
827err:
828 free(dirent);
829
830 return ret;
831}
832
833/**
834 * efi_capsule_read_file - read in a capsule file
835 * @filename: File name
836 * @capsule: Pointer to buffer for capsule
837 *
838 * Read a capsule file and put its content in @capsule.
839 *
840 * Return: status code
841 */
842static efi_status_t efi_capsule_read_file(const u16 *filename,
843 struct efi_capsule_header **capsule)
844{
845 struct efi_file_handle *dirh, *fh;
846 struct efi_file_info *file_info = NULL;
847 struct efi_capsule_header *buf = NULL;
848 efi_uintn_t size;
849 efi_status_t ret;
850
851 ret = EFI_CALL((*bootdev_root->open)(bootdev_root, &dirh,
852 EFI_CAPSULE_DIR,
853 EFI_FILE_MODE_READ, 0));
854 if (ret != EFI_SUCCESS)
855 return ret;
856 ret = EFI_CALL((*dirh->open)(dirh, &fh, (u16 *)filename,
857 EFI_FILE_MODE_READ, 0));
858 /* ignore an error */
859 EFI_CALL((*dirh->close)(dirh));
860 if (ret != EFI_SUCCESS)
861 return ret;
862
863 /* file size */
864 size = 0;
865 ret = EFI_CALL((*fh->getinfo)(fh, &efi_file_info_guid,
866 &size, file_info));
867 if (ret == EFI_BUFFER_TOO_SMALL) {
868 file_info = malloc(size);
869 if (!file_info) {
870 ret = EFI_OUT_OF_RESOURCES;
871 goto err;
872 }
873 ret = EFI_CALL((*fh->getinfo)(fh, &efi_file_info_guid,
874 &size, file_info));
875 }
876 if (ret != EFI_SUCCESS)
877 goto err;
878 size = file_info->file_size;
879 free(file_info);
880 buf = malloc(size);
881 if (!buf) {
882 ret = EFI_OUT_OF_RESOURCES;
883 goto err;
884 }
885
886 /* fetch data */
887 ret = EFI_CALL((*fh->read)(fh, &size, buf));
888 if (ret == EFI_SUCCESS) {
889 if (size >= buf->capsule_image_size) {
890 *capsule = buf;
891 } else {
892 free(buf);
893 ret = EFI_INVALID_PARAMETER;
894 }
895 } else {
896 free(buf);
897 }
898err:
899 EFI_CALL((*fh->close)(fh));
900
901 return ret;
902}
903
904/**
905 * efi_capsule_delete_file - delete a capsule file
906 * @filename: File name
907 *
908 * Delete a capsule file from capsule directory.
909 *
910 * Return: status code
911 */
912static efi_status_t efi_capsule_delete_file(const u16 *filename)
913{
914 struct efi_file_handle *dirh, *fh;
915 efi_status_t ret;
916
917 ret = EFI_CALL((*bootdev_root->open)(bootdev_root, &dirh,
918 EFI_CAPSULE_DIR,
919 EFI_FILE_MODE_READ, 0));
920 if (ret != EFI_SUCCESS)
921 return ret;
922 ret = EFI_CALL((*dirh->open)(dirh, &fh, (u16 *)filename,
923 EFI_FILE_MODE_READ, 0));
924 /* ignore an error */
925 EFI_CALL((*dirh->close)(dirh));
926
Heinrich Schuchardte5c22812021-06-02 19:28:22 +0200927 if (ret == EFI_SUCCESS)
928 ret = EFI_CALL((*fh->delete)(fh));
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900929
930 return ret;
931}
932
933/**
934 * efi_capsule_scan_done - reset a scan help function
935 *
936 * Reset a scan help function
937 */
938static void efi_capsule_scan_done(void)
939{
940 EFI_CALL((*bootdev_root->close)(bootdev_root));
941 bootdev_root = NULL;
942}
943
944/**
Ilias Apalodimasfac773e2021-06-22 17:38:53 +0300945 * efi_load_capsule_drivers - initialize capsule drivers
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900946 *
Ilias Apalodimasfac773e2021-06-22 17:38:53 +0300947 * Generic FMP drivers backed by DFU
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900948 *
949 * Return: status code
950 */
Ilias Apalodimasfac773e2021-06-22 17:38:53 +0300951efi_status_t __weak efi_load_capsule_drivers(void)
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900952{
AKASHI Takahirof4818e62020-11-30 18:12:12 +0900953 __maybe_unused efi_handle_t handle;
954 efi_status_t ret = EFI_SUCCESS;
955
956 if (IS_ENABLED(CONFIG_EFI_CAPSULE_FIRMWARE_FIT)) {
957 handle = NULL;
958 ret = EFI_CALL(efi_install_multiple_protocol_interfaces(
959 &handle, &efi_guid_firmware_management_protocol,
960 &efi_fmp_fit, NULL));
961 }
962
AKASHI Takahiro7ff3f3c2020-11-17 09:28:00 +0900963 if (IS_ENABLED(CONFIG_EFI_CAPSULE_FIRMWARE_RAW)) {
964 handle = NULL;
965 ret = EFI_CALL(efi_install_multiple_protocol_interfaces(
Masami Hiramatsuf5388522021-06-22 17:38:51 +0300966 &handle,
AKASHI Takahiro7ff3f3c2020-11-17 09:28:00 +0900967 &efi_guid_firmware_management_protocol,
968 &efi_fmp_raw, NULL));
969 }
970
AKASHI Takahirof4818e62020-11-30 18:12:12 +0900971 return ret;
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900972}
973
974/**
Ilias Apalodimasa38d0cb2021-06-29 07:55:51 +0300975 * check_run_capsules - Check whether capsule update should run
976 *
977 * The spec says OsIndications must be set in order to run the capsule update
978 * on-disk. Since U-Boot doesn't support runtime SetVariable, allow capsules to
979 * run explicitly if CONFIG_EFI_IGNORE_OSINDICATIONS is selected
980 */
981static bool check_run_capsules(void)
982{
983 u64 os_indications;
984 efi_uintn_t size;
985 efi_status_t ret;
986
987 if (IS_ENABLED(CONFIG_EFI_IGNORE_OSINDICATIONS))
988 return true;
989
990 size = sizeof(os_indications);
991 ret = efi_get_variable_int(L"OsIndications", &efi_global_variable_guid,
992 NULL, &size, &os_indications, NULL);
993 if (ret == EFI_SUCCESS &&
994 (os_indications
995 & EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED))
996 return true;
997
998 return false;
999}
1000
1001/**
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001002 * efi_launch_capsule - launch capsules
1003 *
1004 * Launch all the capsules in system at boot time.
1005 * Called by efi init code
1006 *
1007 * Return: status codde
1008 */
1009efi_status_t efi_launch_capsules(void)
1010{
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001011 struct efi_capsule_header *capsule = NULL;
1012 u16 **files;
1013 unsigned int nfiles, index, i;
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001014 efi_status_t ret;
1015
Ilias Apalodimasa38d0cb2021-06-29 07:55:51 +03001016 if (!check_run_capsules())
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001017 return EFI_SUCCESS;
1018
1019 index = get_last_capsule();
1020
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001021 /*
1022 * Find capsules on disk.
1023 * All the capsules are collected at the beginning because
1024 * capsule files will be removed instantly.
1025 */
1026 nfiles = 0;
1027 files = NULL;
1028 ret = efi_capsule_scan_dir(&files, &nfiles);
1029 if (ret != EFI_SUCCESS)
1030 return ret;
1031 if (!nfiles)
1032 return EFI_SUCCESS;
1033
1034 /* Launch capsules */
1035 for (i = 0, ++index; i < nfiles; i++, index++) {
Heinrich Schuchardte3087a12021-07-10 11:03:27 +02001036 log_debug("Applying %ls\n", files[i]);
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001037 if (index > 0xffff)
1038 index = 0;
1039 ret = efi_capsule_read_file(files[i], &capsule);
1040 if (ret == EFI_SUCCESS) {
1041 ret = EFI_CALL(efi_update_capsule(&capsule, 1, 0));
1042 if (ret != EFI_SUCCESS)
Heinrich Schuchardte3087a12021-07-10 11:03:27 +02001043 log_err("Applying capsule %ls failed\n",
AKASHI Takahiro0d963782020-11-30 18:12:11 +09001044 files[i]);
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001045
1046 free(capsule);
1047 } else {
Heinrich Schuchardte3087a12021-07-10 11:03:27 +02001048 log_err("Reading capsule %ls failed\n", files[i]);
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001049 }
1050 /* create CapsuleXXXX */
1051 set_capsule_result(index, capsule, ret);
1052
1053 /* delete a capsule either in case of success or failure */
1054 ret = efi_capsule_delete_file(files[i]);
1055 if (ret != EFI_SUCCESS)
Heinrich Schuchardte3087a12021-07-10 11:03:27 +02001056 log_err("Deleting capsule %ls failed\n",
AKASHI Takahiro0d963782020-11-30 18:12:11 +09001057 files[i]);
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001058 }
1059 efi_capsule_scan_done();
1060
1061 for (i = 0; i < nfiles; i++)
1062 free(files[i]);
1063 free(files);
1064
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001065 return ret;
1066}
1067#endif /* CONFIG_EFI_CAPSULE_ON_DISK */