blob: d8141176dfd7735bbc5cd1305cc789a69b6f38a8 [file] [log] [blame]
AKASHI Takahiro2bc27ca2020-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 Schuchardt3e491192021-07-10 11:03:27 +02009#define LOG_CATEGORY LOGC_EFI
10
AKASHI Takahiro2bc27ca2020-11-17 09:27:55 +090011#include <common.h>
12#include <efi_loader.h>
13#include <efi_variable.h>
AKASHI Takahiro7a6fb282021-10-07 15:23:32 +090014#include <env.h>
15#include <fdtdec.h>
AKASHI Takahiro2bc27ca2020-11-17 09:27:55 +090016#include <fs.h>
17#include <malloc.h>
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +090018#include <mapmem.h>
AKASHI Takahiro2bc27ca2020-11-17 09:27:55 +090019#include <sort.h>
AKASHI Takahiro7a6fb282021-10-07 15:23:32 +090020#include <asm/global_data.h>
AKASHI Takahiro2bc27ca2020-11-17 09:27:55 +090021
Sughosh Ganu04be98b2020-12-30 19:27:09 +053022#include <crypto/pkcs7.h>
23#include <crypto/pkcs7_parser.h>
24#include <linux/err.h>
25
AKASHI Takahiro7a6fb282021-10-07 15:23:32 +090026DECLARE_GLOBAL_DATA_PTR;
27
AKASHI Takahiro2bc27ca2020-11-17 09:27:55 +090028const efi_guid_t efi_guid_capsule_report = EFI_CAPSULE_REPORT_GUID;
AKASHI Takahiro8d990262020-11-30 18:12:11 +090029static const efi_guid_t efi_guid_firmware_management_capsule_id =
30 EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID;
31const efi_guid_t efi_guid_firmware_management_protocol =
32 EFI_FIRMWARE_MANAGEMENT_PROTOCOL_GUID;
AKASHI Takahiro2bc27ca2020-11-17 09:27:55 +090033
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +090034#ifdef CONFIG_EFI_CAPSULE_ON_DISK
35/* for file system access */
36static struct efi_file_handle *bootdev_root;
37#endif
38
AKASHI Takahiro2bc27ca2020-11-17 09:27:55 +090039/**
40 * get_last_capsule - get the last capsule index
41 *
42 * Retrieve the index of the capsule invoked last time from "CapsuleLast"
43 * variable.
44 *
45 * Return:
46 * * > 0 - the last capsule index invoked
47 * * 0xffff - on error, or no capsule invoked yet
48 */
49static __maybe_unused unsigned int get_last_capsule(void)
50{
51 u16 value16[11]; /* "CapsuleXXXX": non-null-terminated */
Heinrich Schuchardt15bbcaf2021-02-09 20:20:34 +010052 char value[5];
AKASHI Takahiro2bc27ca2020-11-17 09:27:55 +090053 efi_uintn_t size;
54 unsigned long index = 0xffff;
55 efi_status_t ret;
Heinrich Schuchardt15bbcaf2021-02-09 20:20:34 +010056 int i;
AKASHI Takahiro2bc27ca2020-11-17 09:27:55 +090057
58 size = sizeof(value16);
Simon Glass156ccbc2022-01-23 12:55:12 -070059 ret = efi_get_variable_int(u"CapsuleLast", &efi_guid_capsule_report,
AKASHI Takahiro2bc27ca2020-11-17 09:27:55 +090060 NULL, &size, value16, NULL);
Heinrich Schuchardt15bbcaf2021-02-09 20:20:34 +010061 if (ret != EFI_SUCCESS || size != 22 ||
Simon Glass156ccbc2022-01-23 12:55:12 -070062 u16_strncmp(value16, u"Capsule", 7))
AKASHI Takahiro2bc27ca2020-11-17 09:27:55 +090063 goto err;
Heinrich Schuchardt15bbcaf2021-02-09 20:20:34 +010064 for (i = 0; i < 4; ++i) {
65 u16 c = value16[i + 7];
AKASHI Takahiro2bc27ca2020-11-17 09:27:55 +090066
Heinrich Schuchardt15bbcaf2021-02-09 20:20:34 +010067 if (!c || c > 0x7f)
68 goto err;
69 value[i] = c;
70 }
71 value[4] = 0;
72 if (strict_strtoul(value, 16, &index))
73 index = 0xffff;
AKASHI Takahiro2bc27ca2020-11-17 09:27:55 +090074err:
75 return index;
76}
77
78/**
79 * set_capsule_result - set a result variable
80 * @capsule: Capsule
81 * @return_status: Return status
82 *
83 * Create and set a result variable, "CapsuleXXXX", for the capsule,
84 * @capsule.
85 */
86static __maybe_unused
87void set_capsule_result(int index, struct efi_capsule_header *capsule,
88 efi_status_t return_status)
89{
90 u16 variable_name16[12];
91 struct efi_capsule_result_variable_header result;
92 struct efi_time time;
93 efi_status_t ret;
94
Ilias Apalodimasfe179d72020-12-31 12:26:46 +020095 efi_create_indexed_name(variable_name16, sizeof(variable_name16),
96 "Capsule", index);
AKASHI Takahiro2bc27ca2020-11-17 09:27:55 +090097 result.variable_total_size = sizeof(result);
98 result.capsule_guid = capsule->capsule_guid;
99 ret = EFI_CALL((*efi_runtime_services.get_time)(&time, NULL));
100 if (ret == EFI_SUCCESS)
101 memcpy(&result.capsule_processed, &time, sizeof(time));
102 else
103 memset(&result.capsule_processed, 0, sizeof(time));
104 result.capsule_status = return_status;
Heinrich Schuchardtd7eedd92021-07-10 11:10:26 +0200105 ret = efi_set_variable_int(variable_name16, &efi_guid_capsule_report,
106 EFI_VARIABLE_NON_VOLATILE |
107 EFI_VARIABLE_BOOTSERVICE_ACCESS |
108 EFI_VARIABLE_RUNTIME_ACCESS,
109 sizeof(result), &result, false);
Heinrich Schuchardt70bad542021-07-10 11:14:13 +0200110 if (ret != EFI_SUCCESS) {
Heinrich Schuchardt3e491192021-07-10 11:03:27 +0200111 log_err("Setting %ls failed\n", variable_name16);
Heinrich Schuchardt70bad542021-07-10 11:14:13 +0200112 return;
113 }
114
115 /* Variable CapsuleLast must not include terminating 0x0000 */
Simon Glass156ccbc2022-01-23 12:55:12 -0700116 ret = efi_set_variable_int(u"CapsuleLast", &efi_guid_capsule_report,
Heinrich Schuchardt70bad542021-07-10 11:14:13 +0200117 EFI_VARIABLE_READ_ONLY |
118 EFI_VARIABLE_NON_VOLATILE |
119 EFI_VARIABLE_BOOTSERVICE_ACCESS |
120 EFI_VARIABLE_RUNTIME_ACCESS,
121 22, variable_name16, false);
122 if (ret != EFI_SUCCESS)
Simon Glass156ccbc2022-01-23 12:55:12 -0700123 log_err("Setting %ls failed\n", u"CapsuleLast");
AKASHI Takahiro2bc27ca2020-11-17 09:27:55 +0900124}
125
AKASHI Takahiro8d990262020-11-30 18:12:11 +0900126#ifdef CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT
127/**
128 * efi_fmp_find - search for Firmware Management Protocol drivers
129 * @image_type: Image type guid
130 * @instance: Instance number
131 * @handles: Handles of FMP drivers
132 * @no_handles: Number of handles
133 *
134 * Search for Firmware Management Protocol drivers, matching the image
135 * type, @image_type and the machine instance, @instance, from the list,
136 * @handles.
137 *
138 * Return:
139 * * Protocol instance - on success
140 * * NULL - on failure
141 */
142static struct efi_firmware_management_protocol *
143efi_fmp_find(efi_guid_t *image_type, u64 instance, efi_handle_t *handles,
144 efi_uintn_t no_handles)
145{
146 efi_handle_t *handle;
147 struct efi_firmware_management_protocol *fmp;
148 struct efi_firmware_image_descriptor *image_info, *desc;
149 efi_uintn_t info_size, descriptor_size;
150 u32 descriptor_version;
151 u8 descriptor_count;
152 u32 package_version;
153 u16 *package_version_name;
154 bool found = false;
155 int i, j;
156 efi_status_t ret;
157
158 for (i = 0, handle = handles; i < no_handles; i++, handle++) {
159 ret = EFI_CALL(efi_handle_protocol(
160 *handle,
161 &efi_guid_firmware_management_protocol,
162 (void **)&fmp));
163 if (ret != EFI_SUCCESS)
164 continue;
165
166 /* get device's image info */
167 info_size = 0;
168 image_info = NULL;
169 descriptor_version = 0;
170 descriptor_count = 0;
171 descriptor_size = 0;
172 package_version = 0;
173 package_version_name = NULL;
174 ret = EFI_CALL(fmp->get_image_info(fmp, &info_size,
175 image_info,
176 &descriptor_version,
177 &descriptor_count,
178 &descriptor_size,
179 &package_version,
180 &package_version_name));
181 if (ret != EFI_BUFFER_TOO_SMALL)
182 goto skip;
183
184 image_info = malloc(info_size);
185 if (!image_info)
186 goto skip;
187
188 ret = EFI_CALL(fmp->get_image_info(fmp, &info_size,
189 image_info,
190 &descriptor_version,
191 &descriptor_count,
192 &descriptor_size,
193 &package_version,
194 &package_version_name));
195 if (ret != EFI_SUCCESS ||
196 descriptor_version != EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION)
197 goto skip;
198
199 /* matching */
200 for (j = 0, desc = image_info; j < descriptor_count;
201 j++, desc = (void *)desc + descriptor_size) {
202 log_debug("+++ desc[%d] index: %d, name: %ls\n",
203 j, desc->image_index, desc->image_id_name);
204 if (!guidcmp(&desc->image_type_id, image_type) &&
205 (!instance ||
206 !desc->hardware_instance ||
207 desc->hardware_instance == instance))
208 found = true;
209 }
210
211skip:
212 efi_free_pool(package_version_name);
213 free(image_info);
214 EFI_CALL(efi_close_protocol(
215 (efi_handle_t)fmp,
216 &efi_guid_firmware_management_protocol,
217 NULL, NULL));
218 if (found)
219 return fmp;
220 }
221
222 return NULL;
223}
224
AKASHI Takahiroc2cc60c2021-07-20 14:52:05 +0900225/**
226 * efi_remove_auth_hdr - remove authentication data from image
227 * @image: Pointer to pointer to Image
228 * @image_size: Pointer to Image size
229 *
230 * Remove the authentication data from image if possible.
231 * Update @image and @image_size.
232 *
233 * Return: status code
234 */
235static efi_status_t efi_remove_auth_hdr(void **image, efi_uintn_t *image_size)
236{
237 struct efi_firmware_image_authentication *auth_hdr;
238 efi_status_t ret = EFI_INVALID_PARAMETER;
239
240 auth_hdr = (struct efi_firmware_image_authentication *)*image;
241 if (*image_size < sizeof(*auth_hdr))
242 goto out;
243
244 if (auth_hdr->auth_info.hdr.dwLength <=
245 offsetof(struct win_certificate_uefi_guid, cert_data))
246 goto out;
247
248 *image = (uint8_t *)*image + sizeof(auth_hdr->monotonic_count) +
249 auth_hdr->auth_info.hdr.dwLength;
250 *image_size = *image_size - auth_hdr->auth_info.hdr.dwLength -
251 sizeof(auth_hdr->monotonic_count);
252
253 ret = EFI_SUCCESS;
254out:
255 return ret;
256}
257
Sughosh Ganu04be98b2020-12-30 19:27:09 +0530258#if defined(CONFIG_EFI_CAPSULE_AUTHENTICATE)
AKASHI Takahiro50b05eb2021-11-02 09:55:01 +0900259int efi_get_public_key_data(void **pkey, efi_uintn_t *pkey_len)
AKASHI Takahiro7a6fb282021-10-07 15:23:32 +0900260{
261 const void *fdt_blob = gd->fdt_blob;
262 const void *blob;
263 const char *cnode_name = "capsule-key";
264 const char *snode_name = "signature";
265 int sig_node;
266 int len;
267
268 sig_node = fdt_subnode_offset(fdt_blob, 0, snode_name);
269 if (sig_node < 0) {
270 log_err("Unable to get signature node offset\n");
271
272 return -FDT_ERR_NOTFOUND;
273 }
274
275 blob = fdt_getprop(fdt_blob, sig_node, cnode_name, &len);
276
277 if (!blob || len < 0) {
278 log_err("Unable to get capsule-key value\n");
279 *pkey = NULL;
280 *pkey_len = 0;
281
282 return -FDT_ERR_NOTFOUND;
283 }
284
285 *pkey = (void *)blob;
286 *pkey_len = len;
287
288 return 0;
289}
Sughosh Ganu04be98b2020-12-30 19:27:09 +0530290
Sughosh Ganu04be98b2020-12-30 19:27:09 +0530291efi_status_t efi_capsule_authenticate(const void *capsule, efi_uintn_t capsule_size,
292 void **image, efi_uintn_t *image_size)
293{
294 u8 *buf;
295 int ret;
Simon Glass47a25e82021-08-02 08:44:31 -0600296 void *fdt_pkey, *pkey;
Sughosh Ganu04be98b2020-12-30 19:27:09 +0530297 efi_uintn_t pkey_len;
298 uint64_t monotonic_count;
299 struct efi_signature_store *truststore;
300 struct pkcs7_message *capsule_sig;
301 struct efi_image_regions *regs;
302 struct efi_firmware_image_authentication *auth_hdr;
303 efi_status_t status;
304
305 status = EFI_SECURITY_VIOLATION;
306 capsule_sig = NULL;
307 truststore = NULL;
308 regs = NULL;
309
310 /* Sanity checks */
311 if (capsule == NULL || capsule_size == 0)
312 goto out;
313
AKASHI Takahiroc2cc60c2021-07-20 14:52:05 +0900314 *image = (uint8_t *)capsule;
315 *image_size = capsule_size;
316 if (efi_remove_auth_hdr(image, image_size) != EFI_SUCCESS)
317 goto out;
318
Sughosh Ganu04be98b2020-12-30 19:27:09 +0530319 auth_hdr = (struct efi_firmware_image_authentication *)capsule;
Sughosh Ganu04be98b2020-12-30 19:27:09 +0530320 if (guidcmp(&auth_hdr->auth_info.cert_type, &efi_guid_cert_type_pkcs7))
321 goto out;
322
Sughosh Ganu04be98b2020-12-30 19:27:09 +0530323 memcpy(&monotonic_count, &auth_hdr->monotonic_count,
324 sizeof(monotonic_count));
325
326 /* data to be digested */
327 regs = calloc(sizeof(*regs) + sizeof(struct image_region) * 2, 1);
328 if (!regs)
329 goto out;
330
331 regs->max = 2;
332 efi_image_region_add(regs, (uint8_t *)*image,
333 (uint8_t *)*image + *image_size, 1);
334
335 efi_image_region_add(regs, (uint8_t *)&monotonic_count,
336 (uint8_t *)&monotonic_count + sizeof(monotonic_count),
337 1);
338
339 capsule_sig = efi_parse_pkcs7_header(auth_hdr->auth_info.cert_data,
340 auth_hdr->auth_info.hdr.dwLength
341 - sizeof(auth_hdr->auth_info),
342 &buf);
343 if (IS_ERR(capsule_sig)) {
344 debug("Parsing variable's pkcs7 header failed\n");
345 capsule_sig = NULL;
346 goto out;
347 }
348
Simon Glass47a25e82021-08-02 08:44:31 -0600349 ret = efi_get_public_key_data(&fdt_pkey, &pkey_len);
Sughosh Ganu04be98b2020-12-30 19:27:09 +0530350 if (ret < 0)
351 goto out;
352
353 pkey = malloc(pkey_len);
354 if (!pkey)
355 goto out;
356
Simon Glass47a25e82021-08-02 08:44:31 -0600357 memcpy(pkey, fdt_pkey, pkey_len);
Sughosh Ganu04be98b2020-12-30 19:27:09 +0530358 truststore = efi_build_signature_store(pkey, pkey_len);
359 if (!truststore)
360 goto out;
361
362 /* verify signature */
363 if (efi_signature_verify(regs, capsule_sig, truststore, NULL)) {
364 debug("Verified\n");
365 } else {
366 debug("Verifying variable's signature failed\n");
367 goto out;
368 }
369
370 status = EFI_SUCCESS;
371
372out:
373 efi_sigstore_free(truststore);
374 pkcs7_free_message(capsule_sig);
375 free(regs);
376
377 return status;
378}
379#else
380efi_status_t efi_capsule_authenticate(const void *capsule, efi_uintn_t capsule_size,
381 void **image, efi_uintn_t *image_size)
382{
383 return EFI_UNSUPPORTED;
384}
385#endif /* CONFIG_EFI_CAPSULE_AUTHENTICATE */
386
387
AKASHI Takahiro8d990262020-11-30 18:12:11 +0900388/**
389 * efi_capsule_update_firmware - update firmware from capsule
390 * @capsule_data: Capsule
391 *
392 * Update firmware, using a capsule, @capsule_data. Loading any FMP
393 * drivers embedded in a capsule is not supported.
394 *
395 * Return: status code
396 */
397static efi_status_t efi_capsule_update_firmware(
398 struct efi_capsule_header *capsule_data)
399{
400 struct efi_firmware_management_capsule_header *capsule;
401 struct efi_firmware_management_capsule_image_header *image;
AKASHI Takahiroc2cc60c2021-07-20 14:52:05 +0900402 size_t capsule_size, image_binary_size;
AKASHI Takahiro8d990262020-11-30 18:12:11 +0900403 void *image_binary, *vendor_code;
404 efi_handle_t *handles;
405 efi_uintn_t no_handles;
406 int item;
407 struct efi_firmware_management_protocol *fmp;
408 u16 *abort_reason;
409 efi_status_t ret = EFI_SUCCESS;
410
411 /* sanity check */
412 if (capsule_data->header_size < sizeof(*capsule) ||
413 capsule_data->header_size >= capsule_data->capsule_image_size)
414 return EFI_INVALID_PARAMETER;
415
416 capsule = (void *)capsule_data + capsule_data->header_size;
417 capsule_size = capsule_data->capsule_image_size
418 - capsule_data->header_size;
419
420 if (capsule->version != 0x00000001)
421 return EFI_UNSUPPORTED;
422
423 handles = NULL;
424 ret = EFI_CALL(efi_locate_handle_buffer(
425 BY_PROTOCOL,
426 &efi_guid_firmware_management_protocol,
427 NULL, &no_handles, (efi_handle_t **)&handles));
428 if (ret != EFI_SUCCESS)
429 return EFI_UNSUPPORTED;
430
431 /* Payload */
432 for (item = capsule->embedded_driver_count;
433 item < capsule->embedded_driver_count
434 + capsule->payload_item_count; item++) {
435 /* sanity check */
436 if ((capsule->item_offset_list[item] + sizeof(*image)
437 >= capsule_size)) {
Heinrich Schuchardt3e491192021-07-10 11:03:27 +0200438 log_err("Capsule does not have enough data\n");
AKASHI Takahiro8d990262020-11-30 18:12:11 +0900439 ret = EFI_INVALID_PARAMETER;
440 goto out;
441 }
442
443 image = (void *)capsule + capsule->item_offset_list[item];
444
445 if (image->version != 0x00000003) {
446 ret = EFI_UNSUPPORTED;
447 goto out;
448 }
449
450 /* find a device for update firmware */
451 /* TODO: should we pass index as well, or nothing but type? */
452 fmp = efi_fmp_find(&image->update_image_type_id,
453 image->update_hardware_instance,
454 handles, no_handles);
455 if (!fmp) {
Heinrich Schuchardtce00a742022-01-16 14:15:31 +0100456 log_err("FMP driver not found for firmware type %pUs, hardware instance %lld\n",
AKASHI Takahiro8d990262020-11-30 18:12:11 +0900457 &image->update_image_type_id,
458 image->update_hardware_instance);
459 ret = EFI_UNSUPPORTED;
460 goto out;
461 }
462
463 /* do update */
AKASHI Takahiroc2cc60c2021-07-20 14:52:05 +0900464 if (IS_ENABLED(CONFIG_EFI_CAPSULE_AUTHENTICATE) &&
465 !(image->image_capsule_support &
466 CAPSULE_SUPPORT_AUTHENTICATION)) {
467 /* no signature */
468 ret = EFI_SECURITY_VIOLATION;
469 goto out;
470 }
471
AKASHI Takahiro8d990262020-11-30 18:12:11 +0900472 image_binary = (void *)image + sizeof(*image);
AKASHI Takahiroc2cc60c2021-07-20 14:52:05 +0900473 image_binary_size = image->update_image_size;
474 vendor_code = image_binary + image_binary_size;
475 if (!IS_ENABLED(CONFIG_EFI_CAPSULE_AUTHENTICATE) &&
476 (image->image_capsule_support &
477 CAPSULE_SUPPORT_AUTHENTICATION)) {
478 ret = efi_remove_auth_hdr(&image_binary,
479 &image_binary_size);
480 if (ret != EFI_SUCCESS)
481 goto out;
482 }
AKASHI Takahiro8d990262020-11-30 18:12:11 +0900483
484 abort_reason = NULL;
485 ret = EFI_CALL(fmp->set_image(fmp, image->update_image_index,
486 image_binary,
AKASHI Takahiroc2cc60c2021-07-20 14:52:05 +0900487 image_binary_size,
AKASHI Takahiro8d990262020-11-30 18:12:11 +0900488 vendor_code, NULL,
489 &abort_reason));
490 if (ret != EFI_SUCCESS) {
Heinrich Schuchardt3e491192021-07-10 11:03:27 +0200491 log_err("Firmware update failed: %ls\n",
AKASHI Takahiro8d990262020-11-30 18:12:11 +0900492 abort_reason);
493 efi_free_pool(abort_reason);
494 goto out;
495 }
496 }
497
498out:
499 efi_free_pool(handles);
500
501 return ret;
502}
503#else
504static efi_status_t efi_capsule_update_firmware(
505 struct efi_capsule_header *capsule_data)
506{
507 return EFI_UNSUPPORTED;
508}
509#endif /* CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT */
510
AKASHI Takahiro2bc27ca2020-11-17 09:27:55 +0900511/**
512 * efi_update_capsule() - process information from operating system
513 * @capsule_header_array: Array of virtual address pointers
514 * @capsule_count: Number of pointers in capsule_header_array
515 * @scatter_gather_list: Array of physical address pointers
516 *
517 * This function implements the UpdateCapsule() runtime service.
518 *
519 * See the Unified Extensible Firmware Interface (UEFI) specification for
520 * details.
521 *
522 * Return: status code
523 */
524efi_status_t EFIAPI efi_update_capsule(
525 struct efi_capsule_header **capsule_header_array,
526 efi_uintn_t capsule_count,
527 u64 scatter_gather_list)
528{
529 struct efi_capsule_header *capsule;
530 unsigned int i;
531 efi_status_t ret;
532
Simon Glassdf7d89a2021-02-07 14:27:02 -0700533 EFI_ENTRY("%p, %zu, %llu\n", capsule_header_array, capsule_count,
AKASHI Takahiro2bc27ca2020-11-17 09:27:55 +0900534 scatter_gather_list);
535
536 if (!capsule_count) {
537 ret = EFI_INVALID_PARAMETER;
538 goto out;
539 }
540
AKASHI Takahiro8d990262020-11-30 18:12:11 +0900541 ret = EFI_SUCCESS;
AKASHI Takahiro2bc27ca2020-11-17 09:27:55 +0900542 for (i = 0, capsule = *capsule_header_array; i < capsule_count;
543 i++, capsule = *(++capsule_header_array)) {
AKASHI Takahiro8d990262020-11-30 18:12:11 +0900544 /* sanity check */
545 if (capsule->header_size < sizeof(*capsule) ||
546 capsule->capsule_image_size < sizeof(*capsule)) {
Heinrich Schuchardt3e491192021-07-10 11:03:27 +0200547 log_err("Capsule does not have enough data\n");
AKASHI Takahiro8d990262020-11-30 18:12:11 +0900548 continue;
549 }
550
Heinrich Schuchardtce00a742022-01-16 14:15:31 +0100551 log_debug("Capsule[%d] (guid:%pUs)\n",
AKASHI Takahiro8d990262020-11-30 18:12:11 +0900552 i, &capsule->capsule_guid);
553 if (!guidcmp(&capsule->capsule_guid,
554 &efi_guid_firmware_management_capsule_id)) {
555 ret = efi_capsule_update_firmware(capsule);
556 } else {
Heinrich Schuchardtce00a742022-01-16 14:15:31 +0100557 log_err("Unsupported capsule type: %pUs\n",
AKASHI Takahiro8d990262020-11-30 18:12:11 +0900558 &capsule->capsule_guid);
559 ret = EFI_UNSUPPORTED;
560 }
561
562 if (ret != EFI_SUCCESS)
563 goto out;
AKASHI Takahiro2bc27ca2020-11-17 09:27:55 +0900564 }
Jose Marinho64a8aae2021-03-02 17:26:38 +0000565
566 if (IS_ENABLED(CONFIG_EFI_ESRT)) {
567 /* Rebuild the ESRT to reflect any updated FW images. */
568 ret = efi_esrt_populate();
569 if (ret != EFI_SUCCESS)
Heinrich Schuchardt3e491192021-07-10 11:03:27 +0200570 log_warning("ESRT update failed\n");
Jose Marinho64a8aae2021-03-02 17:26:38 +0000571 }
Jose Marinho3627cf42021-04-19 14:54:33 +0100572out:
Jose Marinho64a8aae2021-03-02 17:26:38 +0000573
AKASHI Takahiro2bc27ca2020-11-17 09:27:55 +0900574 return EFI_EXIT(ret);
575}
576
577/**
578 * efi_query_capsule_caps() - check if capsule is supported
579 * @capsule_header_array: Array of virtual pointers
580 * @capsule_count: Number of pointers in capsule_header_array
581 * @maximum_capsule_size: Maximum capsule size
582 * @reset_type: Type of reset needed for capsule update
583 *
584 * This function implements the QueryCapsuleCapabilities() runtime service.
585 *
586 * See the Unified Extensible Firmware Interface (UEFI) specification for
587 * details.
588 *
589 * Return: status code
590 */
591efi_status_t EFIAPI efi_query_capsule_caps(
592 struct efi_capsule_header **capsule_header_array,
593 efi_uintn_t capsule_count,
594 u64 *maximum_capsule_size,
595 u32 *reset_type)
596{
597 struct efi_capsule_header *capsule __attribute__((unused));
598 unsigned int i;
599 efi_status_t ret;
600
Simon Glassdf7d89a2021-02-07 14:27:02 -0700601 EFI_ENTRY("%p, %zu, %p, %p\n", capsule_header_array, capsule_count,
AKASHI Takahiro2bc27ca2020-11-17 09:27:55 +0900602 maximum_capsule_size, reset_type);
603
604 if (!maximum_capsule_size) {
605 ret = EFI_INVALID_PARAMETER;
606 goto out;
607 }
608
609 *maximum_capsule_size = U64_MAX;
610 *reset_type = EFI_RESET_COLD;
611
612 ret = EFI_SUCCESS;
613 for (i = 0, capsule = *capsule_header_array; i < capsule_count;
614 i++, capsule = *(++capsule_header_array)) {
615 /* TODO */
616 }
617out:
618 return EFI_EXIT(ret);
619}
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +0900620
621#ifdef CONFIG_EFI_CAPSULE_ON_DISK
622/**
623 * get_dp_device - retrieve a device path from boot variable
624 * @boot_var: Boot variable name
625 * @device_dp Device path
626 *
627 * Retrieve a device patch from boot variable, @boot_var.
628 *
629 * Return: status code
630 */
631static efi_status_t get_dp_device(u16 *boot_var,
632 struct efi_device_path **device_dp)
633{
634 void *buf = NULL;
635 efi_uintn_t size;
636 struct efi_load_option lo;
637 struct efi_device_path *file_dp;
638 efi_status_t ret;
639
640 size = 0;
641 ret = efi_get_variable_int(boot_var, &efi_global_variable_guid,
642 NULL, &size, NULL, NULL);
643 if (ret == EFI_BUFFER_TOO_SMALL) {
644 buf = malloc(size);
645 if (!buf)
646 return EFI_OUT_OF_RESOURCES;
647 ret = efi_get_variable_int(boot_var, &efi_global_variable_guid,
648 NULL, &size, buf, NULL);
649 }
650 if (ret != EFI_SUCCESS)
651 return ret;
652
653 efi_deserialize_load_option(&lo, buf, &size);
654
655 if (lo.attributes & LOAD_OPTION_ACTIVE) {
656 efi_dp_split_file_path(lo.file_path, device_dp, &file_dp);
657 efi_free_pool(file_dp);
658
659 ret = EFI_SUCCESS;
660 } else {
661 ret = EFI_NOT_FOUND;
662 }
663
664 free(buf);
665
666 return ret;
667}
668
669/**
670 * device_is_present_and_system_part - check if a device exists
671 * @dp Device path
672 *
673 * Check if a device pointed to by the device path, @dp, exists and is
674 * located in UEFI system partition.
675 *
676 * Return: true - yes, false - no
677 */
678static bool device_is_present_and_system_part(struct efi_device_path *dp)
679{
680 efi_handle_t handle;
681
682 handle = efi_dp_find_obj(dp, NULL);
683 if (!handle)
684 return false;
685
686 return efi_disk_is_system_part(handle);
687}
688
689/**
690 * find_boot_device - identify the boot device
691 *
692 * Identify the boot device from boot-related variables as UEFI
693 * specification describes and put its handle into bootdev_root.
694 *
695 * Return: status code
696 */
697static efi_status_t find_boot_device(void)
698{
699 char boot_var[9];
700 u16 boot_var16[9], *p, bootnext, *boot_order = NULL;
701 efi_uintn_t size;
702 int i, num;
703 struct efi_simple_file_system_protocol *volume;
704 struct efi_device_path *boot_dev = NULL;
705 efi_status_t ret;
706
707 /* find active boot device in BootNext */
708 bootnext = 0;
709 size = sizeof(bootnext);
Simon Glass156ccbc2022-01-23 12:55:12 -0700710 ret = efi_get_variable_int(u"BootNext",
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +0900711 (efi_guid_t *)&efi_global_variable_guid,
712 NULL, &size, &bootnext, NULL);
713 if (ret == EFI_SUCCESS || ret == EFI_BUFFER_TOO_SMALL) {
714 /* BootNext does exist here */
715 if (ret == EFI_BUFFER_TOO_SMALL || size != sizeof(u16)) {
AKASHI Takahiro8d990262020-11-30 18:12:11 +0900716 log_err("BootNext must be 16-bit integer\n");
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +0900717 goto skip;
718 }
719 sprintf((char *)boot_var, "Boot%04X", bootnext);
720 p = boot_var16;
721 utf8_utf16_strcpy(&p, boot_var);
722
723 ret = get_dp_device(boot_var16, &boot_dev);
724 if (ret == EFI_SUCCESS) {
725 if (device_is_present_and_system_part(boot_dev)) {
Masami Hiramatsub0b14492021-07-12 18:05:17 +0900726 goto found;
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +0900727 } else {
728 efi_free_pool(boot_dev);
729 boot_dev = NULL;
730 }
731 }
732 }
733
734skip:
735 /* find active boot device in BootOrder */
736 size = 0;
Simon Glass156ccbc2022-01-23 12:55:12 -0700737 ret = efi_get_variable_int(u"BootOrder", &efi_global_variable_guid,
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +0900738 NULL, &size, NULL, NULL);
739 if (ret == EFI_BUFFER_TOO_SMALL) {
740 boot_order = malloc(size);
741 if (!boot_order) {
742 ret = EFI_OUT_OF_RESOURCES;
743 goto out;
744 }
745
Simon Glass156ccbc2022-01-23 12:55:12 -0700746 ret = efi_get_variable_int(u"BootOrder",
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +0900747 &efi_global_variable_guid,
748 NULL, &size, boot_order, NULL);
749 }
750 if (ret != EFI_SUCCESS)
751 goto out;
752
753 /* check in higher order */
754 num = size / sizeof(u16);
755 for (i = 0; i < num; i++) {
756 sprintf((char *)boot_var, "Boot%04X", boot_order[i]);
757 p = boot_var16;
758 utf8_utf16_strcpy(&p, boot_var);
759 ret = get_dp_device(boot_var16, &boot_dev);
760 if (ret != EFI_SUCCESS)
761 continue;
762
763 if (device_is_present_and_system_part(boot_dev))
764 break;
765
766 efi_free_pool(boot_dev);
767 boot_dev = NULL;
768 }
Masami Hiramatsub0b14492021-07-12 18:05:17 +0900769found:
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +0900770 if (boot_dev) {
Masami Hiramatsu484d7d82021-07-14 14:19:13 +0900771 log_debug("Boot device %pD\n", boot_dev);
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +0900772
773 volume = efi_fs_from_path(boot_dev);
774 if (!volume)
775 ret = EFI_DEVICE_ERROR;
776 else
777 ret = EFI_CALL(volume->open_volume(volume,
778 &bootdev_root));
779 efi_free_pool(boot_dev);
780 } else {
781 ret = EFI_NOT_FOUND;
782 }
AKASHI Takahiro2c1a6842021-04-20 10:03:16 +0900783out:
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +0900784 free(boot_order);
785
786 return ret;
787}
788
789/**
790 * efi_capsule_scan_dir - traverse a capsule directory in boot device
791 * @files: Array of file names
792 * @num: Number of elements in @files
793 *
794 * Traverse a capsule directory in boot device.
795 * Called by initialization code, and returns an array of capsule file
796 * names in @files.
797 *
798 * Return: status code
799 */
800static efi_status_t efi_capsule_scan_dir(u16 ***files, unsigned int *num)
801{
802 struct efi_file_handle *dirh;
803 struct efi_file_info *dirent;
804 efi_uintn_t dirent_size, tmp_size;
805 unsigned int count;
806 u16 **tmp_files;
807 efi_status_t ret;
808
809 ret = find_boot_device();
810 if (ret == EFI_NOT_FOUND) {
Heinrich Schuchardt3e491192021-07-10 11:03:27 +0200811 log_debug("Boot device is not set\n");
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +0900812 *num = 0;
813 return EFI_SUCCESS;
814 } else if (ret != EFI_SUCCESS) {
815 return EFI_DEVICE_ERROR;
816 }
817
818 /* count capsule files */
819 ret = EFI_CALL((*bootdev_root->open)(bootdev_root, &dirh,
820 EFI_CAPSULE_DIR,
821 EFI_FILE_MODE_READ, 0));
822 if (ret != EFI_SUCCESS) {
823 *num = 0;
824 return EFI_SUCCESS;
825 }
826
827 dirent_size = 256;
828 dirent = malloc(dirent_size);
829 if (!dirent)
830 return EFI_OUT_OF_RESOURCES;
831
832 count = 0;
833 while (1) {
834 tmp_size = dirent_size;
835 ret = EFI_CALL((*dirh->read)(dirh, &tmp_size, dirent));
836 if (ret == EFI_BUFFER_TOO_SMALL) {
Heinrich Schuchardte8287b02021-04-11 06:53:04 +0200837 struct efi_file_info *old_dirent = dirent;
838
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +0900839 dirent = realloc(dirent, tmp_size);
840 if (!dirent) {
Heinrich Schuchardte8287b02021-04-11 06:53:04 +0200841 dirent = old_dirent;
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +0900842 ret = EFI_OUT_OF_RESOURCES;
843 goto err;
844 }
845 dirent_size = tmp_size;
846 ret = EFI_CALL((*dirh->read)(dirh, &tmp_size, dirent));
847 }
848 if (ret != EFI_SUCCESS)
849 goto err;
850 if (!tmp_size)
851 break;
852
Heinrich Schuchardt841f7a42021-02-09 17:45:33 +0100853 if (!(dirent->attribute & EFI_FILE_DIRECTORY))
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +0900854 count++;
855 }
856
857 ret = EFI_CALL((*dirh->setpos)(dirh, 0));
858 if (ret != EFI_SUCCESS)
859 goto err;
860
861 /* make a list */
AKASHI Takahiro8f1844c2021-01-22 10:43:27 +0900862 tmp_files = malloc(count * sizeof(*tmp_files));
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +0900863 if (!tmp_files) {
864 ret = EFI_OUT_OF_RESOURCES;
865 goto err;
866 }
867
868 count = 0;
869 while (1) {
870 tmp_size = dirent_size;
871 ret = EFI_CALL((*dirh->read)(dirh, &tmp_size, dirent));
872 if (ret != EFI_SUCCESS)
873 goto err;
874 if (!tmp_size)
875 break;
876
877 if (!(dirent->attribute & EFI_FILE_DIRECTORY) &&
Simon Glass156ccbc2022-01-23 12:55:12 -0700878 u16_strcmp(dirent->file_name, u".") &&
879 u16_strcmp(dirent->file_name, u".."))
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +0900880 tmp_files[count++] = u16_strdup(dirent->file_name);
881 }
882 /* ignore an error */
883 EFI_CALL((*dirh->close)(dirh));
884
885 /* in ascii order */
886 /* FIXME: u16 version of strcasecmp */
887 qsort(tmp_files, count, sizeof(*tmp_files),
888 (int (*)(const void *, const void *))strcasecmp);
889 *files = tmp_files;
890 *num = count;
891 ret = EFI_SUCCESS;
892err:
893 free(dirent);
894
895 return ret;
896}
897
898/**
899 * efi_capsule_read_file - read in a capsule file
900 * @filename: File name
901 * @capsule: Pointer to buffer for capsule
902 *
903 * Read a capsule file and put its content in @capsule.
904 *
905 * Return: status code
906 */
907static efi_status_t efi_capsule_read_file(const u16 *filename,
908 struct efi_capsule_header **capsule)
909{
910 struct efi_file_handle *dirh, *fh;
911 struct efi_file_info *file_info = NULL;
912 struct efi_capsule_header *buf = NULL;
913 efi_uintn_t size;
914 efi_status_t ret;
915
916 ret = EFI_CALL((*bootdev_root->open)(bootdev_root, &dirh,
917 EFI_CAPSULE_DIR,
918 EFI_FILE_MODE_READ, 0));
919 if (ret != EFI_SUCCESS)
920 return ret;
921 ret = EFI_CALL((*dirh->open)(dirh, &fh, (u16 *)filename,
922 EFI_FILE_MODE_READ, 0));
923 /* ignore an error */
924 EFI_CALL((*dirh->close)(dirh));
925 if (ret != EFI_SUCCESS)
926 return ret;
927
928 /* file size */
929 size = 0;
930 ret = EFI_CALL((*fh->getinfo)(fh, &efi_file_info_guid,
931 &size, file_info));
932 if (ret == EFI_BUFFER_TOO_SMALL) {
933 file_info = malloc(size);
934 if (!file_info) {
935 ret = EFI_OUT_OF_RESOURCES;
936 goto err;
937 }
938 ret = EFI_CALL((*fh->getinfo)(fh, &efi_file_info_guid,
939 &size, file_info));
940 }
941 if (ret != EFI_SUCCESS)
942 goto err;
943 size = file_info->file_size;
944 free(file_info);
945 buf = malloc(size);
946 if (!buf) {
947 ret = EFI_OUT_OF_RESOURCES;
948 goto err;
949 }
950
951 /* fetch data */
952 ret = EFI_CALL((*fh->read)(fh, &size, buf));
953 if (ret == EFI_SUCCESS) {
954 if (size >= buf->capsule_image_size) {
955 *capsule = buf;
956 } else {
957 free(buf);
958 ret = EFI_INVALID_PARAMETER;
959 }
960 } else {
961 free(buf);
962 }
963err:
964 EFI_CALL((*fh->close)(fh));
965
966 return ret;
967}
968
969/**
970 * efi_capsule_delete_file - delete a capsule file
971 * @filename: File name
972 *
973 * Delete a capsule file from capsule directory.
974 *
975 * Return: status code
976 */
977static efi_status_t efi_capsule_delete_file(const u16 *filename)
978{
979 struct efi_file_handle *dirh, *fh;
980 efi_status_t ret;
981
982 ret = EFI_CALL((*bootdev_root->open)(bootdev_root, &dirh,
983 EFI_CAPSULE_DIR,
984 EFI_FILE_MODE_READ, 0));
985 if (ret != EFI_SUCCESS)
986 return ret;
987 ret = EFI_CALL((*dirh->open)(dirh, &fh, (u16 *)filename,
988 EFI_FILE_MODE_READ, 0));
989 /* ignore an error */
990 EFI_CALL((*dirh->close)(dirh));
991
Heinrich Schuchardte27b0ff2021-06-02 19:28:22 +0200992 if (ret == EFI_SUCCESS)
993 ret = EFI_CALL((*fh->delete)(fh));
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +0900994
995 return ret;
996}
997
998/**
999 * efi_capsule_scan_done - reset a scan help function
1000 *
1001 * Reset a scan help function
1002 */
1003static void efi_capsule_scan_done(void)
1004{
1005 EFI_CALL((*bootdev_root->close)(bootdev_root));
1006 bootdev_root = NULL;
1007}
1008
1009/**
Ilias Apalodimas6e0184b2021-06-22 17:38:53 +03001010 * efi_load_capsule_drivers - initialize capsule drivers
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +09001011 *
Ilias Apalodimas6e0184b2021-06-22 17:38:53 +03001012 * Generic FMP drivers backed by DFU
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +09001013 *
1014 * Return: status code
1015 */
Ilias Apalodimas6e0184b2021-06-22 17:38:53 +03001016efi_status_t __weak efi_load_capsule_drivers(void)
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +09001017{
AKASHI Takahirof27c2012020-11-30 18:12:12 +09001018 __maybe_unused efi_handle_t handle;
1019 efi_status_t ret = EFI_SUCCESS;
1020
1021 if (IS_ENABLED(CONFIG_EFI_CAPSULE_FIRMWARE_FIT)) {
1022 handle = NULL;
1023 ret = EFI_CALL(efi_install_multiple_protocol_interfaces(
1024 &handle, &efi_guid_firmware_management_protocol,
1025 &efi_fmp_fit, NULL));
1026 }
1027
AKASHI Takahirobb7e71d2020-11-17 09:28:00 +09001028 if (IS_ENABLED(CONFIG_EFI_CAPSULE_FIRMWARE_RAW)) {
1029 handle = NULL;
1030 ret = EFI_CALL(efi_install_multiple_protocol_interfaces(
Masami Hiramatsu3ef77222021-06-22 17:38:51 +03001031 &handle,
AKASHI Takahirobb7e71d2020-11-17 09:28:00 +09001032 &efi_guid_firmware_management_protocol,
1033 &efi_fmp_raw, NULL));
1034 }
1035
AKASHI Takahirof27c2012020-11-30 18:12:12 +09001036 return ret;
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +09001037}
1038
1039/**
Heinrich Schuchardt9d1564d2021-11-20 11:53:12 +01001040 * check_run_capsules() - check whether capsule update should run
Ilias Apalodimas0fa50202021-06-29 07:55:51 +03001041 *
1042 * The spec says OsIndications must be set in order to run the capsule update
1043 * on-disk. Since U-Boot doesn't support runtime SetVariable, allow capsules to
1044 * run explicitly if CONFIG_EFI_IGNORE_OSINDICATIONS is selected
Heinrich Schuchardt9d1564d2021-11-20 11:53:12 +01001045 *
1046 * Return: EFI_SUCCESS if update to run, EFI_NOT_FOUND otherwise
Ilias Apalodimas0fa50202021-06-29 07:55:51 +03001047 */
Heinrich Schuchardt9d1564d2021-11-20 11:53:12 +01001048static efi_status_t check_run_capsules(void)
Ilias Apalodimas0fa50202021-06-29 07:55:51 +03001049{
1050 u64 os_indications;
1051 efi_uintn_t size;
Heinrich Schuchardt9d1564d2021-11-20 11:53:12 +01001052 efi_status_t r;
Ilias Apalodimas0fa50202021-06-29 07:55:51 +03001053
1054 size = sizeof(os_indications);
Simon Glass156ccbc2022-01-23 12:55:12 -07001055 r = efi_get_variable_int(u"OsIndications", &efi_global_variable_guid,
Heinrich Schuchardt9d1564d2021-11-20 11:53:12 +01001056 NULL, &size, &os_indications, NULL);
1057 if (r != EFI_SUCCESS || size != sizeof(os_indications))
1058 return EFI_NOT_FOUND;
Ilias Apalodimas0fa50202021-06-29 07:55:51 +03001059
Heinrich Schuchardt9d1564d2021-11-20 11:53:12 +01001060 if (os_indications &
1061 EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED) {
1062 os_indications &=
1063 ~EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED;
Simon Glass156ccbc2022-01-23 12:55:12 -07001064 r = efi_set_variable_int(u"OsIndications",
Heinrich Schuchardt9d1564d2021-11-20 11:53:12 +01001065 &efi_global_variable_guid,
1066 EFI_VARIABLE_NON_VOLATILE |
1067 EFI_VARIABLE_BOOTSERVICE_ACCESS |
1068 EFI_VARIABLE_RUNTIME_ACCESS,
1069 sizeof(os_indications),
1070 &os_indications, false);
1071 if (r != EFI_SUCCESS)
1072 log_err("Setting %ls failed\n", L"OsIndications");
1073 return EFI_SUCCESS;
1074 } else if (IS_ENABLED(CONFIG_EFI_IGNORE_OSINDICATIONS)) {
1075 return EFI_SUCCESS;
1076 } else {
1077 return EFI_NOT_FOUND;
1078 }
Ilias Apalodimas0fa50202021-06-29 07:55:51 +03001079}
1080
1081/**
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +09001082 * efi_launch_capsule - launch capsules
1083 *
1084 * Launch all the capsules in system at boot time.
1085 * Called by efi init code
1086 *
1087 * Return: status codde
1088 */
1089efi_status_t efi_launch_capsules(void)
1090{
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +09001091 struct efi_capsule_header *capsule = NULL;
1092 u16 **files;
1093 unsigned int nfiles, index, i;
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +09001094 efi_status_t ret;
1095
Heinrich Schuchardt9d1564d2021-11-20 11:53:12 +01001096 if (check_run_capsules() != EFI_SUCCESS)
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +09001097 return EFI_SUCCESS;
1098
1099 index = get_last_capsule();
1100
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +09001101 /*
1102 * Find capsules on disk.
1103 * All the capsules are collected at the beginning because
1104 * capsule files will be removed instantly.
1105 */
1106 nfiles = 0;
1107 files = NULL;
1108 ret = efi_capsule_scan_dir(&files, &nfiles);
1109 if (ret != EFI_SUCCESS)
1110 return ret;
1111 if (!nfiles)
1112 return EFI_SUCCESS;
1113
1114 /* Launch capsules */
1115 for (i = 0, ++index; i < nfiles; i++, index++) {
Heinrich Schuchardt3e491192021-07-10 11:03:27 +02001116 log_debug("Applying %ls\n", files[i]);
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +09001117 if (index > 0xffff)
1118 index = 0;
1119 ret = efi_capsule_read_file(files[i], &capsule);
1120 if (ret == EFI_SUCCESS) {
Masami Hiramatsua6aafce2022-02-16 15:15:42 +09001121 ret = efi_capsule_update_firmware(capsule);
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +09001122 if (ret != EFI_SUCCESS)
Heinrich Schuchardt3e491192021-07-10 11:03:27 +02001123 log_err("Applying capsule %ls failed\n",
AKASHI Takahiro8d990262020-11-30 18:12:11 +09001124 files[i]);
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +09001125
Masami Hiramatsu5d49b322021-11-12 22:05:15 +09001126 /* create CapsuleXXXX */
1127 set_capsule_result(index, capsule, ret);
1128
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +09001129 free(capsule);
1130 } else {
Heinrich Schuchardt3e491192021-07-10 11:03:27 +02001131 log_err("Reading capsule %ls failed\n", files[i]);
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +09001132 }
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +09001133 /* delete a capsule either in case of success or failure */
1134 ret = efi_capsule_delete_file(files[i]);
1135 if (ret != EFI_SUCCESS)
Heinrich Schuchardt3e491192021-07-10 11:03:27 +02001136 log_err("Deleting capsule %ls failed\n",
AKASHI Takahiro8d990262020-11-30 18:12:11 +09001137 files[i]);
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +09001138 }
1139 efi_capsule_scan_done();
1140
1141 for (i = 0; i < nfiles; i++)
1142 free(files[i]);
1143 free(files);
1144
AKASHI Takahiroc74cd8b2020-11-17 09:27:56 +09001145 return ret;
1146}
1147#endif /* CONFIG_EFI_CAPSULE_ON_DISK */