blob: 1163a2ee30163e2464c7289dedbf8e93274db532 [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>
AKASHI Takahirob71a0ae2021-10-07 15:23:32 +090014#include <env.h>
15#include <fdtdec.h>
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090016#include <fs.h>
Sughosh Ganu1cadae22022-10-21 18:16:03 +053017#include <fwu.h>
Masami Hiramatsu4b2f8c12022-02-16 15:16:12 +090018#include <hang.h>
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090019#include <malloc.h>
AKASHI Takahiro45b819542020-11-17 09:27:56 +090020#include <mapmem.h>
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090021#include <sort.h>
Masami Hiramatsuff744862022-03-21 22:37:56 +090022#include <sysreset.h>
AKASHI Takahirob71a0ae2021-10-07 15:23:32 +090023#include <asm/global_data.h>
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090024
Sughosh Ganu586bb982020-12-30 19:27:09 +053025#include <crypto/pkcs7.h>
26#include <crypto/pkcs7_parser.h>
27#include <linux/err.h>
28
AKASHI Takahirob71a0ae2021-10-07 15:23:32 +090029DECLARE_GLOBAL_DATA_PTR;
30
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090031const efi_guid_t efi_guid_capsule_report = EFI_CAPSULE_REPORT_GUID;
AKASHI Takahiro0d963782020-11-30 18:12:11 +090032static const efi_guid_t efi_guid_firmware_management_capsule_id =
33 EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID;
34const efi_guid_t efi_guid_firmware_management_protocol =
35 EFI_FIRMWARE_MANAGEMENT_PROTOCOL_GUID;
Sughosh Ganu1cadae22022-10-21 18:16:03 +053036const efi_guid_t fwu_guid_os_request_fw_revert =
37 FWU_OS_REQUEST_FW_REVERT_GUID;
38const efi_guid_t fwu_guid_os_request_fw_accept =
39 FWU_OS_REQUEST_FW_ACCEPT_GUID;
40
41#define FW_ACCEPT_OS (u32)0x8000
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090042
AKASHI Takahiro45b819542020-11-17 09:27:56 +090043#ifdef CONFIG_EFI_CAPSULE_ON_DISK
44/* for file system access */
45static struct efi_file_handle *bootdev_root;
46#endif
47
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090048/**
49 * get_last_capsule - get the last capsule index
50 *
51 * Retrieve the index of the capsule invoked last time from "CapsuleLast"
52 * variable.
53 *
54 * Return:
55 * * > 0 - the last capsule index invoked
56 * * 0xffff - on error, or no capsule invoked yet
57 */
58static __maybe_unused unsigned int get_last_capsule(void)
59{
60 u16 value16[11]; /* "CapsuleXXXX": non-null-terminated */
Heinrich Schuchardt812f6e02021-02-09 20:20:34 +010061 char value[5];
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090062 efi_uintn_t size;
63 unsigned long index = 0xffff;
64 efi_status_t ret;
Heinrich Schuchardt812f6e02021-02-09 20:20:34 +010065 int i;
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090066
67 size = sizeof(value16);
Simon Glass90975372022-01-23 12:55:12 -070068 ret = efi_get_variable_int(u"CapsuleLast", &efi_guid_capsule_report,
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090069 NULL, &size, value16, NULL);
Heinrich Schuchardt812f6e02021-02-09 20:20:34 +010070 if (ret != EFI_SUCCESS || size != 22 ||
Simon Glass90975372022-01-23 12:55:12 -070071 u16_strncmp(value16, u"Capsule", 7))
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090072 goto err;
Heinrich Schuchardt812f6e02021-02-09 20:20:34 +010073 for (i = 0; i < 4; ++i) {
74 u16 c = value16[i + 7];
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090075
Heinrich Schuchardt812f6e02021-02-09 20:20:34 +010076 if (!c || c > 0x7f)
77 goto err;
78 value[i] = c;
79 }
80 value[4] = 0;
81 if (strict_strtoul(value, 16, &index))
82 index = 0xffff;
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090083err:
84 return index;
85}
86
87/**
88 * set_capsule_result - set a result variable
89 * @capsule: Capsule
90 * @return_status: Return status
91 *
92 * Create and set a result variable, "CapsuleXXXX", for the capsule,
93 * @capsule.
94 */
95static __maybe_unused
96void set_capsule_result(int index, struct efi_capsule_header *capsule,
97 efi_status_t return_status)
98{
99 u16 variable_name16[12];
100 struct efi_capsule_result_variable_header result;
101 struct efi_time time;
102 efi_status_t ret;
103
Ilias Apalodimas21575292020-12-31 12:26:46 +0200104 efi_create_indexed_name(variable_name16, sizeof(variable_name16),
105 "Capsule", index);
AKASHI Takahiro473d9b32020-11-17 09:27:55 +0900106 result.variable_total_size = sizeof(result);
107 result.capsule_guid = capsule->capsule_guid;
108 ret = EFI_CALL((*efi_runtime_services.get_time)(&time, NULL));
109 if (ret == EFI_SUCCESS)
110 memcpy(&result.capsule_processed, &time, sizeof(time));
111 else
112 memset(&result.capsule_processed, 0, sizeof(time));
113 result.capsule_status = return_status;
Heinrich Schuchardt24adaa72021-07-10 11:10:26 +0200114 ret = efi_set_variable_int(variable_name16, &efi_guid_capsule_report,
115 EFI_VARIABLE_NON_VOLATILE |
116 EFI_VARIABLE_BOOTSERVICE_ACCESS |
117 EFI_VARIABLE_RUNTIME_ACCESS,
118 sizeof(result), &result, false);
Heinrich Schuchardtb1fae8c2021-07-10 11:14:13 +0200119 if (ret != EFI_SUCCESS) {
Heinrich Schuchardte3087a12021-07-10 11:03:27 +0200120 log_err("Setting %ls failed\n", variable_name16);
Heinrich Schuchardtb1fae8c2021-07-10 11:14:13 +0200121 return;
122 }
123
124 /* Variable CapsuleLast must not include terminating 0x0000 */
Simon Glass90975372022-01-23 12:55:12 -0700125 ret = efi_set_variable_int(u"CapsuleLast", &efi_guid_capsule_report,
Heinrich Schuchardtb1fae8c2021-07-10 11:14:13 +0200126 EFI_VARIABLE_READ_ONLY |
127 EFI_VARIABLE_NON_VOLATILE |
128 EFI_VARIABLE_BOOTSERVICE_ACCESS |
129 EFI_VARIABLE_RUNTIME_ACCESS,
130 22, variable_name16, false);
131 if (ret != EFI_SUCCESS)
Simon Glass90975372022-01-23 12:55:12 -0700132 log_err("Setting %ls failed\n", u"CapsuleLast");
AKASHI Takahiro473d9b32020-11-17 09:27:55 +0900133}
134
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900135#ifdef CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT
136/**
137 * efi_fmp_find - search for Firmware Management Protocol drivers
138 * @image_type: Image type guid
Sughosh Ganuf55c6b62022-04-15 11:29:36 +0530139 * @image_index: Image Index
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900140 * @instance: Instance number
141 * @handles: Handles of FMP drivers
142 * @no_handles: Number of handles
143 *
144 * Search for Firmware Management Protocol drivers, matching the image
145 * type, @image_type and the machine instance, @instance, from the list,
146 * @handles.
147 *
148 * Return:
149 * * Protocol instance - on success
150 * * NULL - on failure
151 */
152static struct efi_firmware_management_protocol *
Sughosh Ganuf55c6b62022-04-15 11:29:36 +0530153efi_fmp_find(efi_guid_t *image_type, u8 image_index, u64 instance,
154 efi_handle_t *handles, efi_uintn_t no_handles)
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900155{
156 efi_handle_t *handle;
157 struct efi_firmware_management_protocol *fmp;
158 struct efi_firmware_image_descriptor *image_info, *desc;
159 efi_uintn_t info_size, descriptor_size;
160 u32 descriptor_version;
161 u8 descriptor_count;
162 u32 package_version;
163 u16 *package_version_name;
164 bool found = false;
165 int i, j;
166 efi_status_t ret;
167
168 for (i = 0, handle = handles; i < no_handles; i++, handle++) {
Heinrich Schuchardtd8dc3cb2022-10-07 15:29:52 +0200169 struct efi_handler *fmp_handler;
170
171 ret = efi_search_protocol(
172 *handle, &efi_guid_firmware_management_protocol,
173 &fmp_handler);
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900174 if (ret != EFI_SUCCESS)
175 continue;
Heinrich Schuchardtd8dc3cb2022-10-07 15:29:52 +0200176 fmp = fmp_handler->protocol_interface;
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900177
178 /* get device's image info */
179 info_size = 0;
180 image_info = NULL;
181 descriptor_version = 0;
182 descriptor_count = 0;
183 descriptor_size = 0;
184 package_version = 0;
185 package_version_name = NULL;
186 ret = EFI_CALL(fmp->get_image_info(fmp, &info_size,
187 image_info,
188 &descriptor_version,
189 &descriptor_count,
190 &descriptor_size,
191 &package_version,
192 &package_version_name));
193 if (ret != EFI_BUFFER_TOO_SMALL)
194 goto skip;
195
196 image_info = malloc(info_size);
197 if (!image_info)
198 goto skip;
199
200 ret = EFI_CALL(fmp->get_image_info(fmp, &info_size,
201 image_info,
202 &descriptor_version,
203 &descriptor_count,
204 &descriptor_size,
205 &package_version,
206 &package_version_name));
207 if (ret != EFI_SUCCESS ||
208 descriptor_version != EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION)
209 goto skip;
210
211 /* matching */
212 for (j = 0, desc = image_info; j < descriptor_count;
213 j++, desc = (void *)desc + descriptor_size) {
214 log_debug("+++ desc[%d] index: %d, name: %ls\n",
215 j, desc->image_index, desc->image_id_name);
216 if (!guidcmp(&desc->image_type_id, image_type) &&
Sughosh Ganuf55c6b62022-04-15 11:29:36 +0530217 (desc->image_index == image_index) &&
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900218 (!instance ||
219 !desc->hardware_instance ||
220 desc->hardware_instance == instance))
221 found = true;
222 }
223
224skip:
225 efi_free_pool(package_version_name);
226 free(image_info);
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900227 if (found)
228 return fmp;
229 }
230
231 return NULL;
232}
233
AKASHI Takahiro920671c2021-07-20 14:52:05 +0900234/**
235 * efi_remove_auth_hdr - remove authentication data from image
236 * @image: Pointer to pointer to Image
237 * @image_size: Pointer to Image size
238 *
239 * Remove the authentication data from image if possible.
240 * Update @image and @image_size.
241 *
242 * Return: status code
243 */
244static efi_status_t efi_remove_auth_hdr(void **image, efi_uintn_t *image_size)
245{
246 struct efi_firmware_image_authentication *auth_hdr;
247 efi_status_t ret = EFI_INVALID_PARAMETER;
248
249 auth_hdr = (struct efi_firmware_image_authentication *)*image;
250 if (*image_size < sizeof(*auth_hdr))
251 goto out;
252
253 if (auth_hdr->auth_info.hdr.dwLength <=
254 offsetof(struct win_certificate_uefi_guid, cert_data))
255 goto out;
256
257 *image = (uint8_t *)*image + sizeof(auth_hdr->monotonic_count) +
258 auth_hdr->auth_info.hdr.dwLength;
259 *image_size = *image_size - auth_hdr->auth_info.hdr.dwLength -
260 sizeof(auth_hdr->monotonic_count);
261
262 ret = EFI_SUCCESS;
263out:
264 return ret;
265}
266
Sughosh Ganu586bb982020-12-30 19:27:09 +0530267#if defined(CONFIG_EFI_CAPSULE_AUTHENTICATE)
AKASHI Takahirof155bf52021-11-02 09:55:01 +0900268int efi_get_public_key_data(void **pkey, efi_uintn_t *pkey_len)
AKASHI Takahirob71a0ae2021-10-07 15:23:32 +0900269{
270 const void *fdt_blob = gd->fdt_blob;
271 const void *blob;
272 const char *cnode_name = "capsule-key";
273 const char *snode_name = "signature";
274 int sig_node;
275 int len;
276
277 sig_node = fdt_subnode_offset(fdt_blob, 0, snode_name);
278 if (sig_node < 0) {
279 log_err("Unable to get signature node offset\n");
280
281 return -FDT_ERR_NOTFOUND;
282 }
283
284 blob = fdt_getprop(fdt_blob, sig_node, cnode_name, &len);
285
286 if (!blob || len < 0) {
287 log_err("Unable to get capsule-key value\n");
288 *pkey = NULL;
289 *pkey_len = 0;
290
291 return -FDT_ERR_NOTFOUND;
292 }
293
294 *pkey = (void *)blob;
295 *pkey_len = len;
296
297 return 0;
298}
Sughosh Ganu586bb982020-12-30 19:27:09 +0530299
Sughosh Ganu586bb982020-12-30 19:27:09 +0530300efi_status_t efi_capsule_authenticate(const void *capsule, efi_uintn_t capsule_size,
301 void **image, efi_uintn_t *image_size)
302{
303 u8 *buf;
304 int ret;
Simon Glass1f78c122021-08-02 08:44:31 -0600305 void *fdt_pkey, *pkey;
Sughosh Ganu586bb982020-12-30 19:27:09 +0530306 efi_uintn_t pkey_len;
307 uint64_t monotonic_count;
308 struct efi_signature_store *truststore;
309 struct pkcs7_message *capsule_sig;
310 struct efi_image_regions *regs;
311 struct efi_firmware_image_authentication *auth_hdr;
312 efi_status_t status;
313
314 status = EFI_SECURITY_VIOLATION;
315 capsule_sig = NULL;
316 truststore = NULL;
317 regs = NULL;
318
319 /* Sanity checks */
320 if (capsule == NULL || capsule_size == 0)
321 goto out;
322
AKASHI Takahiro920671c2021-07-20 14:52:05 +0900323 *image = (uint8_t *)capsule;
324 *image_size = capsule_size;
325 if (efi_remove_auth_hdr(image, image_size) != EFI_SUCCESS)
Sughosh Ganu586bb982020-12-30 19:27:09 +0530326 goto out;
327
AKASHI Takahiro920671c2021-07-20 14:52:05 +0900328 auth_hdr = (struct efi_firmware_image_authentication *)capsule;
Sughosh Ganu586bb982020-12-30 19:27:09 +0530329 if (guidcmp(&auth_hdr->auth_info.cert_type, &efi_guid_cert_type_pkcs7))
330 goto out;
331
Sughosh Ganu586bb982020-12-30 19:27:09 +0530332 memcpy(&monotonic_count, &auth_hdr->monotonic_count,
333 sizeof(monotonic_count));
334
335 /* data to be digested */
336 regs = calloc(sizeof(*regs) + sizeof(struct image_region) * 2, 1);
337 if (!regs)
338 goto out;
339
340 regs->max = 2;
341 efi_image_region_add(regs, (uint8_t *)*image,
342 (uint8_t *)*image + *image_size, 1);
343
344 efi_image_region_add(regs, (uint8_t *)&monotonic_count,
345 (uint8_t *)&monotonic_count + sizeof(monotonic_count),
346 1);
347
348 capsule_sig = efi_parse_pkcs7_header(auth_hdr->auth_info.cert_data,
349 auth_hdr->auth_info.hdr.dwLength
350 - sizeof(auth_hdr->auth_info),
351 &buf);
352 if (IS_ERR(capsule_sig)) {
353 debug("Parsing variable's pkcs7 header failed\n");
354 capsule_sig = NULL;
355 goto out;
356 }
357
Simon Glass1f78c122021-08-02 08:44:31 -0600358 ret = efi_get_public_key_data(&fdt_pkey, &pkey_len);
Sughosh Ganu586bb982020-12-30 19:27:09 +0530359 if (ret < 0)
360 goto out;
361
362 pkey = malloc(pkey_len);
363 if (!pkey)
364 goto out;
365
Simon Glass1f78c122021-08-02 08:44:31 -0600366 memcpy(pkey, fdt_pkey, pkey_len);
Sughosh Ganu586bb982020-12-30 19:27:09 +0530367 truststore = efi_build_signature_store(pkey, pkey_len);
368 if (!truststore)
369 goto out;
370
371 /* verify signature */
372 if (efi_signature_verify(regs, capsule_sig, truststore, NULL)) {
373 debug("Verified\n");
374 } else {
375 debug("Verifying variable's signature failed\n");
376 goto out;
377 }
378
379 status = EFI_SUCCESS;
380
381out:
382 efi_sigstore_free(truststore);
383 pkcs7_free_message(capsule_sig);
384 free(regs);
385
386 return status;
387}
388#else
389efi_status_t efi_capsule_authenticate(const void *capsule, efi_uintn_t capsule_size,
390 void **image, efi_uintn_t *image_size)
391{
392 return EFI_UNSUPPORTED;
393}
394#endif /* CONFIG_EFI_CAPSULE_AUTHENTICATE */
395
Sughosh Ganu1cadae22022-10-21 18:16:03 +0530396static __maybe_unused bool fwu_empty_capsule(struct efi_capsule_header *capsule)
397{
398 return !guidcmp(&capsule->capsule_guid,
399 &fwu_guid_os_request_fw_revert) ||
400 !guidcmp(&capsule->capsule_guid,
401 &fwu_guid_os_request_fw_accept);
402}
403
404static __maybe_unused efi_status_t fwu_to_efi_error(int err)
405{
406 efi_status_t ret;
407
408 switch(err) {
409 case 0:
410 ret = EFI_SUCCESS;
411 break;
412 case -ERANGE:
413 case -EIO:
414 ret = EFI_DEVICE_ERROR;
415 break;
416 case -EINVAL:
417 ret = EFI_INVALID_PARAMETER;
418 break;
419 case -ENODEV:
420 ret = EFI_NOT_FOUND;
421 break;
422 default:
423 ret = EFI_OUT_OF_RESOURCES;
424 }
425
426 return ret;
427}
428
429static __maybe_unused efi_status_t fwu_empty_capsule_process(
430 struct efi_capsule_header *capsule)
431{
432 int status;
433 u32 active_idx;
434 efi_guid_t *image_guid;
435 efi_status_t ret = EFI_INVALID_PARAMETER;
436
437 if (!guidcmp(&capsule->capsule_guid,
438 &fwu_guid_os_request_fw_revert)) {
439 /*
440 * One of the previously updated image has
441 * failed the OS acceptance test. OS has
442 * requested to revert back to the earlier
443 * boot index
444 */
445 status = fwu_revert_boot_index();
446 ret = fwu_to_efi_error(status);
447 if (ret == EFI_SUCCESS)
448 log_debug("Reverted the FWU active_index. Recommend rebooting the system\n");
449 else
450 log_err("Failed to revert the FWU boot index\n");
451 } else if (!guidcmp(&capsule->capsule_guid,
452 &fwu_guid_os_request_fw_accept)) {
453 /*
454 * Image accepted by the OS. Set the acceptance
455 * status for the image.
456 */
457 image_guid = (void *)(char *)capsule +
458 capsule->header_size;
459
460 status = fwu_get_active_index(&active_idx);
461 ret = fwu_to_efi_error(status);
462 if (ret != EFI_SUCCESS) {
463 log_err("Unable to get the active_index from the FWU metadata\n");
464 return ret;
465 }
466
467 status = fwu_accept_image(image_guid, active_idx);
468 ret = fwu_to_efi_error(status);
469 if (ret != EFI_SUCCESS)
470 log_err("Unable to set the Accept bit for the image %pUs\n",
471 image_guid);
472 }
473
474 return ret;
475}
476
477static __maybe_unused void fwu_post_update_checks(
478 struct efi_capsule_header *capsule,
479 bool *fw_accept_os, bool *capsule_update)
480{
481 if (fwu_empty_capsule(capsule))
482 *capsule_update = false;
483 else
484 if (!*fw_accept_os)
485 *fw_accept_os =
486 capsule->flags & FW_ACCEPT_OS ? true : false;
487}
488
489static __maybe_unused efi_status_t fwu_post_update_process(bool fw_accept_os)
490{
491 int status;
492 uint update_index;
493 efi_status_t ret;
494
495 status = fwu_plat_get_update_index(&update_index);
496 if (status < 0) {
497 log_err("Failed to get the FWU update_index value\n");
498 return EFI_DEVICE_ERROR;
499 }
500
501 /*
502 * All the capsules have been updated successfully,
503 * update the FWU metadata.
504 */
505 log_debug("Update Complete. Now updating active_index to %u\n",
506 update_index);
507 status = fwu_set_active_index(update_index);
508 ret = fwu_to_efi_error(status);
509 if (ret != EFI_SUCCESS) {
510 log_err("Failed to update FWU metadata index values\n");
511 } else {
512 log_debug("Successfully updated the active_index\n");
513 if (fw_accept_os) {
514 status = fwu_trial_state_ctr_start();
515 if (status < 0)
516 ret = EFI_DEVICE_ERROR;
517 }
518 }
519
520 return ret;
521}
Sughosh Ganu586bb982020-12-30 19:27:09 +0530522
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900523/**
524 * efi_capsule_update_firmware - update firmware from capsule
525 * @capsule_data: Capsule
526 *
527 * Update firmware, using a capsule, @capsule_data. Loading any FMP
528 * drivers embedded in a capsule is not supported.
529 *
530 * Return: status code
531 */
532static efi_status_t efi_capsule_update_firmware(
533 struct efi_capsule_header *capsule_data)
534{
535 struct efi_firmware_management_capsule_header *capsule;
536 struct efi_firmware_management_capsule_image_header *image;
AKASHI Takahiro920671c2021-07-20 14:52:05 +0900537 size_t capsule_size, image_binary_size;
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900538 void *image_binary, *vendor_code;
539 efi_handle_t *handles;
540 efi_uintn_t no_handles;
541 int item;
542 struct efi_firmware_management_protocol *fmp;
543 u16 *abort_reason;
Sughosh Ganu1cadae22022-10-21 18:16:03 +0530544 efi_guid_t *image_type_id;
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900545 efi_status_t ret = EFI_SUCCESS;
Sughosh Ganu1cadae22022-10-21 18:16:03 +0530546 int status;
547 uint update_index;
548 bool fw_accept_os;
549
550 if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) {
551 if (fwu_empty_capsule_checks_pass() &&
552 fwu_empty_capsule(capsule_data))
553 return fwu_empty_capsule_process(capsule_data);
554
555 if (!fwu_update_checks_pass()) {
556 log_err("FWU checks failed. Cannot start update\n");
557 return EFI_INVALID_PARAMETER;
558 }
559
560
561 /* Obtain the update_index from the platform */
562 status = fwu_plat_get_update_index(&update_index);
563 if (status < 0) {
564 log_err("Failed to get the FWU update_index value\n");
565 return EFI_DEVICE_ERROR;
566 }
567
568 fw_accept_os = capsule_data->flags & FW_ACCEPT_OS ? 0x1 : 0x0;
569 }
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900570
571 /* sanity check */
572 if (capsule_data->header_size < sizeof(*capsule) ||
573 capsule_data->header_size >= capsule_data->capsule_image_size)
574 return EFI_INVALID_PARAMETER;
575
576 capsule = (void *)capsule_data + capsule_data->header_size;
577 capsule_size = capsule_data->capsule_image_size
578 - capsule_data->header_size;
579
580 if (capsule->version != 0x00000001)
581 return EFI_UNSUPPORTED;
582
583 handles = NULL;
584 ret = EFI_CALL(efi_locate_handle_buffer(
585 BY_PROTOCOL,
586 &efi_guid_firmware_management_protocol,
587 NULL, &no_handles, (efi_handle_t **)&handles));
588 if (ret != EFI_SUCCESS)
589 return EFI_UNSUPPORTED;
590
591 /* Payload */
592 for (item = capsule->embedded_driver_count;
593 item < capsule->embedded_driver_count
594 + capsule->payload_item_count; item++) {
595 /* sanity check */
596 if ((capsule->item_offset_list[item] + sizeof(*image)
597 >= capsule_size)) {
Heinrich Schuchardte3087a12021-07-10 11:03:27 +0200598 log_err("Capsule does not have enough data\n");
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900599 ret = EFI_INVALID_PARAMETER;
600 goto out;
601 }
602
603 image = (void *)capsule + capsule->item_offset_list[item];
604
605 if (image->version != 0x00000003) {
606 ret = EFI_UNSUPPORTED;
607 goto out;
608 }
609
610 /* find a device for update firmware */
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900611 fmp = efi_fmp_find(&image->update_image_type_id,
Sughosh Ganuf55c6b62022-04-15 11:29:36 +0530612 image->update_image_index,
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900613 image->update_hardware_instance,
614 handles, no_handles);
615 if (!fmp) {
Heinrich Schuchardt282249d2022-01-16 14:15:31 +0100616 log_err("FMP driver not found for firmware type %pUs, hardware instance %lld\n",
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900617 &image->update_image_type_id,
618 image->update_hardware_instance);
619 ret = EFI_UNSUPPORTED;
620 goto out;
621 }
622
623 /* do update */
AKASHI Takahiro920671c2021-07-20 14:52:05 +0900624 if (IS_ENABLED(CONFIG_EFI_CAPSULE_AUTHENTICATE) &&
625 !(image->image_capsule_support &
626 CAPSULE_SUPPORT_AUTHENTICATION)) {
627 /* no signature */
628 ret = EFI_SECURITY_VIOLATION;
629 goto out;
630 }
631
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900632 image_binary = (void *)image + sizeof(*image);
AKASHI Takahiro920671c2021-07-20 14:52:05 +0900633 image_binary_size = image->update_image_size;
634 vendor_code = image_binary + image_binary_size;
635 if (!IS_ENABLED(CONFIG_EFI_CAPSULE_AUTHENTICATE) &&
636 (image->image_capsule_support &
637 CAPSULE_SUPPORT_AUTHENTICATION)) {
638 ret = efi_remove_auth_hdr(&image_binary,
639 &image_binary_size);
640 if (ret != EFI_SUCCESS)
641 goto out;
642 }
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900643
644 abort_reason = NULL;
645 ret = EFI_CALL(fmp->set_image(fmp, image->update_image_index,
646 image_binary,
AKASHI Takahiro920671c2021-07-20 14:52:05 +0900647 image_binary_size,
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900648 vendor_code, NULL,
649 &abort_reason));
650 if (ret != EFI_SUCCESS) {
Heinrich Schuchardte3087a12021-07-10 11:03:27 +0200651 log_err("Firmware update failed: %ls\n",
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900652 abort_reason);
653 efi_free_pool(abort_reason);
654 goto out;
655 }
Sughosh Ganu1cadae22022-10-21 18:16:03 +0530656
657 if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) {
658 image_type_id = &image->update_image_type_id;
659 if (!fw_accept_os) {
660 /*
661 * The OS will not be accepting the firmware
662 * images. Set the accept bit of all the
663 * images contained in this capsule.
664 */
665 status = fwu_accept_image(image_type_id,
666 update_index);
667 } else {
668 status = fwu_clear_accept_image(image_type_id,
669 update_index);
670 }
671 ret = fwu_to_efi_error(status);
672 if (ret != EFI_SUCCESS) {
673 log_err("Unable to %s the accept bit for the image %pUs\n",
674 fw_accept_os ? "clear" : "set",
675 image_type_id);
676 goto out;
677 }
678
679 log_debug("%s the accepted bit for Image %pUs\n",
680 fw_accept_os ? "Cleared" : "Set",
681 image_type_id);
682 }
683
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900684 }
685
686out:
687 efi_free_pool(handles);
688
689 return ret;
690}
691#else
692static efi_status_t efi_capsule_update_firmware(
693 struct efi_capsule_header *capsule_data)
694{
695 return EFI_UNSUPPORTED;
696}
697#endif /* CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT */
698
AKASHI Takahiro473d9b32020-11-17 09:27:55 +0900699/**
700 * efi_update_capsule() - process information from operating system
701 * @capsule_header_array: Array of virtual address pointers
702 * @capsule_count: Number of pointers in capsule_header_array
703 * @scatter_gather_list: Array of physical address pointers
704 *
705 * This function implements the UpdateCapsule() runtime service.
706 *
707 * See the Unified Extensible Firmware Interface (UEFI) specification for
708 * details.
709 *
710 * Return: status code
711 */
712efi_status_t EFIAPI efi_update_capsule(
713 struct efi_capsule_header **capsule_header_array,
714 efi_uintn_t capsule_count,
715 u64 scatter_gather_list)
716{
717 struct efi_capsule_header *capsule;
718 unsigned int i;
719 efi_status_t ret;
720
Simon Glass83698b22021-02-07 14:27:02 -0700721 EFI_ENTRY("%p, %zu, %llu\n", capsule_header_array, capsule_count,
AKASHI Takahiro473d9b32020-11-17 09:27:55 +0900722 scatter_gather_list);
723
724 if (!capsule_count) {
725 ret = EFI_INVALID_PARAMETER;
726 goto out;
727 }
728
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900729 ret = EFI_SUCCESS;
AKASHI Takahiro473d9b32020-11-17 09:27:55 +0900730 for (i = 0, capsule = *capsule_header_array; i < capsule_count;
731 i++, capsule = *(++capsule_header_array)) {
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900732 /* sanity check */
733 if (capsule->header_size < sizeof(*capsule) ||
734 capsule->capsule_image_size < sizeof(*capsule)) {
Heinrich Schuchardte3087a12021-07-10 11:03:27 +0200735 log_err("Capsule does not have enough data\n");
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900736 continue;
737 }
738
Heinrich Schuchardt282249d2022-01-16 14:15:31 +0100739 log_debug("Capsule[%d] (guid:%pUs)\n",
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900740 i, &capsule->capsule_guid);
741 if (!guidcmp(&capsule->capsule_guid,
742 &efi_guid_firmware_management_capsule_id)) {
743 ret = efi_capsule_update_firmware(capsule);
744 } else {
Heinrich Schuchardt282249d2022-01-16 14:15:31 +0100745 log_err("Unsupported capsule type: %pUs\n",
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900746 &capsule->capsule_guid);
747 ret = EFI_UNSUPPORTED;
748 }
749
750 if (ret != EFI_SUCCESS)
751 goto out;
AKASHI Takahiro473d9b32020-11-17 09:27:55 +0900752 }
Jose Marinhoebb61ee2021-03-02 17:26:38 +0000753
754 if (IS_ENABLED(CONFIG_EFI_ESRT)) {
755 /* Rebuild the ESRT to reflect any updated FW images. */
756 ret = efi_esrt_populate();
757 if (ret != EFI_SUCCESS)
Heinrich Schuchardte3087a12021-07-10 11:03:27 +0200758 log_warning("ESRT update failed\n");
Jose Marinhoebb61ee2021-03-02 17:26:38 +0000759 }
Jose Marinhoaf886ce2021-04-19 14:54:33 +0100760out:
Jose Marinhoebb61ee2021-03-02 17:26:38 +0000761
AKASHI Takahiro473d9b32020-11-17 09:27:55 +0900762 return EFI_EXIT(ret);
763}
764
765/**
766 * efi_query_capsule_caps() - check if capsule is supported
767 * @capsule_header_array: Array of virtual pointers
768 * @capsule_count: Number of pointers in capsule_header_array
769 * @maximum_capsule_size: Maximum capsule size
770 * @reset_type: Type of reset needed for capsule update
771 *
772 * This function implements the QueryCapsuleCapabilities() runtime service.
773 *
774 * See the Unified Extensible Firmware Interface (UEFI) specification for
775 * details.
776 *
777 * Return: status code
778 */
779efi_status_t EFIAPI efi_query_capsule_caps(
780 struct efi_capsule_header **capsule_header_array,
781 efi_uintn_t capsule_count,
782 u64 *maximum_capsule_size,
783 u32 *reset_type)
784{
785 struct efi_capsule_header *capsule __attribute__((unused));
786 unsigned int i;
787 efi_status_t ret;
788
Simon Glass83698b22021-02-07 14:27:02 -0700789 EFI_ENTRY("%p, %zu, %p, %p\n", capsule_header_array, capsule_count,
AKASHI Takahiro473d9b32020-11-17 09:27:55 +0900790 maximum_capsule_size, reset_type);
791
792 if (!maximum_capsule_size) {
793 ret = EFI_INVALID_PARAMETER;
794 goto out;
795 }
796
797 *maximum_capsule_size = U64_MAX;
798 *reset_type = EFI_RESET_COLD;
799
800 ret = EFI_SUCCESS;
801 for (i = 0, capsule = *capsule_header_array; i < capsule_count;
802 i++, capsule = *(++capsule_header_array)) {
803 /* TODO */
804 }
805out:
806 return EFI_EXIT(ret);
807}
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900808
Masami Hiramatsud306caa2022-03-21 22:37:45 +0900809/**
810 * efi_load_capsule_drivers - initialize capsule drivers
811 *
812 * Generic FMP drivers backed by DFU
813 *
814 * Return: status code
815 */
816efi_status_t __weak efi_load_capsule_drivers(void)
817{
818 __maybe_unused efi_handle_t handle;
819 efi_status_t ret = EFI_SUCCESS;
820
821 if (IS_ENABLED(CONFIG_EFI_CAPSULE_FIRMWARE_FIT)) {
822 handle = NULL;
Ilias Apalodimas8ac0ebe2022-10-06 16:08:46 +0300823 ret = efi_install_multiple_protocol_interfaces(&handle,
824 &efi_guid_firmware_management_protocol,
825 &efi_fmp_fit,
826 NULL);
Masami Hiramatsud306caa2022-03-21 22:37:45 +0900827 }
828
829 if (IS_ENABLED(CONFIG_EFI_CAPSULE_FIRMWARE_RAW)) {
830 handle = NULL;
Ilias Apalodimas8ac0ebe2022-10-06 16:08:46 +0300831 ret = efi_install_multiple_protocol_interfaces(&handle,
832 &efi_guid_firmware_management_protocol,
833 &efi_fmp_raw,
834 NULL);
Masami Hiramatsud306caa2022-03-21 22:37:45 +0900835 }
836
837 return ret;
838}
839
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900840#ifdef CONFIG_EFI_CAPSULE_ON_DISK
841/**
842 * get_dp_device - retrieve a device path from boot variable
843 * @boot_var: Boot variable name
844 * @device_dp Device path
845 *
846 * Retrieve a device patch from boot variable, @boot_var.
847 *
848 * Return: status code
849 */
850static efi_status_t get_dp_device(u16 *boot_var,
851 struct efi_device_path **device_dp)
852{
853 void *buf = NULL;
854 efi_uintn_t size;
855 struct efi_load_option lo;
856 struct efi_device_path *file_dp;
857 efi_status_t ret;
858
859 size = 0;
860 ret = efi_get_variable_int(boot_var, &efi_global_variable_guid,
861 NULL, &size, NULL, NULL);
862 if (ret == EFI_BUFFER_TOO_SMALL) {
863 buf = malloc(size);
864 if (!buf)
865 return EFI_OUT_OF_RESOURCES;
866 ret = efi_get_variable_int(boot_var, &efi_global_variable_guid,
867 NULL, &size, buf, NULL);
868 }
869 if (ret != EFI_SUCCESS)
870 return ret;
871
872 efi_deserialize_load_option(&lo, buf, &size);
873
874 if (lo.attributes & LOAD_OPTION_ACTIVE) {
875 efi_dp_split_file_path(lo.file_path, device_dp, &file_dp);
876 efi_free_pool(file_dp);
877
878 ret = EFI_SUCCESS;
879 } else {
880 ret = EFI_NOT_FOUND;
881 }
882
883 free(buf);
884
885 return ret;
886}
887
888/**
889 * device_is_present_and_system_part - check if a device exists
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900890 *
891 * Check if a device pointed to by the device path, @dp, exists and is
892 * located in UEFI system partition.
893 *
Heinrich Schuchardta76fc032022-03-05 00:36:50 +0100894 * @dp device path
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900895 * Return: true - yes, false - no
896 */
897static bool device_is_present_and_system_part(struct efi_device_path *dp)
898{
899 efi_handle_t handle;
Heinrich Schuchardta76fc032022-03-05 00:36:50 +0100900 struct efi_device_path *rem;
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900901
Heinrich Schuchardta76fc032022-03-05 00:36:50 +0100902 /* Check device exists */
Heinrich Schuchardt0a04a412022-03-19 06:35:43 +0100903 handle = efi_dp_find_obj(dp, NULL, NULL);
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900904 if (!handle)
905 return false;
906
Heinrich Schuchardta76fc032022-03-05 00:36:50 +0100907 /* Check device is on system partition */
908 handle = efi_dp_find_obj(dp, &efi_system_partition_guid, &rem);
909 if (!handle)
910 return false;
911
912 return true;
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900913}
914
915/**
916 * find_boot_device - identify the boot device
917 *
918 * Identify the boot device from boot-related variables as UEFI
919 * specification describes and put its handle into bootdev_root.
920 *
921 * Return: status code
922 */
923static efi_status_t find_boot_device(void)
924{
925 char boot_var[9];
926 u16 boot_var16[9], *p, bootnext, *boot_order = NULL;
927 efi_uintn_t size;
928 int i, num;
929 struct efi_simple_file_system_protocol *volume;
930 struct efi_device_path *boot_dev = NULL;
931 efi_status_t ret;
932
933 /* find active boot device in BootNext */
934 bootnext = 0;
935 size = sizeof(bootnext);
Simon Glass90975372022-01-23 12:55:12 -0700936 ret = efi_get_variable_int(u"BootNext",
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900937 (efi_guid_t *)&efi_global_variable_guid,
938 NULL, &size, &bootnext, NULL);
939 if (ret == EFI_SUCCESS || ret == EFI_BUFFER_TOO_SMALL) {
940 /* BootNext does exist here */
941 if (ret == EFI_BUFFER_TOO_SMALL || size != sizeof(u16)) {
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900942 log_err("BootNext must be 16-bit integer\n");
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900943 goto skip;
944 }
945 sprintf((char *)boot_var, "Boot%04X", bootnext);
946 p = boot_var16;
947 utf8_utf16_strcpy(&p, boot_var);
948
949 ret = get_dp_device(boot_var16, &boot_dev);
950 if (ret == EFI_SUCCESS) {
951 if (device_is_present_and_system_part(boot_dev)) {
Masami Hiramatsu10165752021-07-12 18:05:17 +0900952 goto found;
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900953 } else {
954 efi_free_pool(boot_dev);
955 boot_dev = NULL;
956 }
957 }
958 }
959
960skip:
961 /* find active boot device in BootOrder */
962 size = 0;
Simon Glass90975372022-01-23 12:55:12 -0700963 ret = efi_get_variable_int(u"BootOrder", &efi_global_variable_guid,
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900964 NULL, &size, NULL, NULL);
965 if (ret == EFI_BUFFER_TOO_SMALL) {
966 boot_order = malloc(size);
967 if (!boot_order) {
968 ret = EFI_OUT_OF_RESOURCES;
969 goto out;
970 }
971
Simon Glass90975372022-01-23 12:55:12 -0700972 ret = efi_get_variable_int(u"BootOrder",
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900973 &efi_global_variable_guid,
974 NULL, &size, boot_order, NULL);
975 }
976 if (ret != EFI_SUCCESS)
977 goto out;
978
979 /* check in higher order */
980 num = size / sizeof(u16);
981 for (i = 0; i < num; i++) {
982 sprintf((char *)boot_var, "Boot%04X", boot_order[i]);
983 p = boot_var16;
984 utf8_utf16_strcpy(&p, boot_var);
985 ret = get_dp_device(boot_var16, &boot_dev);
986 if (ret != EFI_SUCCESS)
987 continue;
988
989 if (device_is_present_and_system_part(boot_dev))
990 break;
991
992 efi_free_pool(boot_dev);
993 boot_dev = NULL;
994 }
Masami Hiramatsu10165752021-07-12 18:05:17 +0900995found:
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900996 if (boot_dev) {
Masami Hiramatsud9763bb2021-07-14 14:19:13 +0900997 log_debug("Boot device %pD\n", boot_dev);
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900998
999 volume = efi_fs_from_path(boot_dev);
1000 if (!volume)
1001 ret = EFI_DEVICE_ERROR;
1002 else
1003 ret = EFI_CALL(volume->open_volume(volume,
1004 &bootdev_root));
1005 efi_free_pool(boot_dev);
1006 } else {
1007 ret = EFI_NOT_FOUND;
1008 }
AKASHI Takahirofa390e62021-04-20 10:03:16 +09001009out:
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001010 free(boot_order);
1011
1012 return ret;
1013}
1014
1015/**
1016 * efi_capsule_scan_dir - traverse a capsule directory in boot device
1017 * @files: Array of file names
1018 * @num: Number of elements in @files
1019 *
1020 * Traverse a capsule directory in boot device.
1021 * Called by initialization code, and returns an array of capsule file
1022 * names in @files.
1023 *
1024 * Return: status code
1025 */
1026static efi_status_t efi_capsule_scan_dir(u16 ***files, unsigned int *num)
1027{
1028 struct efi_file_handle *dirh;
1029 struct efi_file_info *dirent;
1030 efi_uintn_t dirent_size, tmp_size;
1031 unsigned int count;
1032 u16 **tmp_files;
1033 efi_status_t ret;
1034
1035 ret = find_boot_device();
1036 if (ret == EFI_NOT_FOUND) {
Heinrich Schuchardte3087a12021-07-10 11:03:27 +02001037 log_debug("Boot device is not set\n");
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001038 *num = 0;
1039 return EFI_SUCCESS;
1040 } else if (ret != EFI_SUCCESS) {
1041 return EFI_DEVICE_ERROR;
1042 }
1043
1044 /* count capsule files */
1045 ret = EFI_CALL((*bootdev_root->open)(bootdev_root, &dirh,
1046 EFI_CAPSULE_DIR,
1047 EFI_FILE_MODE_READ, 0));
1048 if (ret != EFI_SUCCESS) {
1049 *num = 0;
1050 return EFI_SUCCESS;
1051 }
1052
1053 dirent_size = 256;
1054 dirent = malloc(dirent_size);
1055 if (!dirent)
1056 return EFI_OUT_OF_RESOURCES;
1057
1058 count = 0;
1059 while (1) {
1060 tmp_size = dirent_size;
1061 ret = EFI_CALL((*dirh->read)(dirh, &tmp_size, dirent));
1062 if (ret == EFI_BUFFER_TOO_SMALL) {
Heinrich Schuchardtaa27e5d2021-04-11 06:53:04 +02001063 struct efi_file_info *old_dirent = dirent;
1064
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001065 dirent = realloc(dirent, tmp_size);
1066 if (!dirent) {
Heinrich Schuchardtaa27e5d2021-04-11 06:53:04 +02001067 dirent = old_dirent;
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001068 ret = EFI_OUT_OF_RESOURCES;
1069 goto err;
1070 }
1071 dirent_size = tmp_size;
1072 ret = EFI_CALL((*dirh->read)(dirh, &tmp_size, dirent));
1073 }
1074 if (ret != EFI_SUCCESS)
1075 goto err;
1076 if (!tmp_size)
1077 break;
1078
Heinrich Schuchardt76b708a2021-02-09 17:45:33 +01001079 if (!(dirent->attribute & EFI_FILE_DIRECTORY))
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001080 count++;
1081 }
1082
1083 ret = EFI_CALL((*dirh->setpos)(dirh, 0));
1084 if (ret != EFI_SUCCESS)
1085 goto err;
1086
1087 /* make a list */
AKASHI Takahiroc8fc12f2021-01-22 10:43:27 +09001088 tmp_files = malloc(count * sizeof(*tmp_files));
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001089 if (!tmp_files) {
1090 ret = EFI_OUT_OF_RESOURCES;
1091 goto err;
1092 }
1093
1094 count = 0;
1095 while (1) {
1096 tmp_size = dirent_size;
1097 ret = EFI_CALL((*dirh->read)(dirh, &tmp_size, dirent));
1098 if (ret != EFI_SUCCESS)
1099 goto err;
1100 if (!tmp_size)
1101 break;
1102
1103 if (!(dirent->attribute & EFI_FILE_DIRECTORY) &&
Simon Glass90975372022-01-23 12:55:12 -07001104 u16_strcmp(dirent->file_name, u".") &&
1105 u16_strcmp(dirent->file_name, u".."))
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001106 tmp_files[count++] = u16_strdup(dirent->file_name);
1107 }
1108 /* ignore an error */
1109 EFI_CALL((*dirh->close)(dirh));
1110
1111 /* in ascii order */
1112 /* FIXME: u16 version of strcasecmp */
1113 qsort(tmp_files, count, sizeof(*tmp_files),
1114 (int (*)(const void *, const void *))strcasecmp);
1115 *files = tmp_files;
1116 *num = count;
1117 ret = EFI_SUCCESS;
1118err:
1119 free(dirent);
1120
1121 return ret;
1122}
1123
1124/**
1125 * efi_capsule_read_file - read in a capsule file
1126 * @filename: File name
1127 * @capsule: Pointer to buffer for capsule
1128 *
1129 * Read a capsule file and put its content in @capsule.
1130 *
1131 * Return: status code
1132 */
1133static efi_status_t efi_capsule_read_file(const u16 *filename,
1134 struct efi_capsule_header **capsule)
1135{
1136 struct efi_file_handle *dirh, *fh;
1137 struct efi_file_info *file_info = NULL;
1138 struct efi_capsule_header *buf = NULL;
1139 efi_uintn_t size;
1140 efi_status_t ret;
1141
1142 ret = EFI_CALL((*bootdev_root->open)(bootdev_root, &dirh,
1143 EFI_CAPSULE_DIR,
1144 EFI_FILE_MODE_READ, 0));
1145 if (ret != EFI_SUCCESS)
1146 return ret;
1147 ret = EFI_CALL((*dirh->open)(dirh, &fh, (u16 *)filename,
1148 EFI_FILE_MODE_READ, 0));
1149 /* ignore an error */
1150 EFI_CALL((*dirh->close)(dirh));
1151 if (ret != EFI_SUCCESS)
1152 return ret;
1153
1154 /* file size */
1155 size = 0;
1156 ret = EFI_CALL((*fh->getinfo)(fh, &efi_file_info_guid,
1157 &size, file_info));
1158 if (ret == EFI_BUFFER_TOO_SMALL) {
1159 file_info = malloc(size);
1160 if (!file_info) {
1161 ret = EFI_OUT_OF_RESOURCES;
1162 goto err;
1163 }
1164 ret = EFI_CALL((*fh->getinfo)(fh, &efi_file_info_guid,
1165 &size, file_info));
1166 }
1167 if (ret != EFI_SUCCESS)
1168 goto err;
1169 size = file_info->file_size;
1170 free(file_info);
1171 buf = malloc(size);
1172 if (!buf) {
1173 ret = EFI_OUT_OF_RESOURCES;
1174 goto err;
1175 }
1176
1177 /* fetch data */
1178 ret = EFI_CALL((*fh->read)(fh, &size, buf));
1179 if (ret == EFI_SUCCESS) {
1180 if (size >= buf->capsule_image_size) {
1181 *capsule = buf;
1182 } else {
1183 free(buf);
1184 ret = EFI_INVALID_PARAMETER;
1185 }
1186 } else {
1187 free(buf);
1188 }
1189err:
1190 EFI_CALL((*fh->close)(fh));
1191
1192 return ret;
1193}
1194
1195/**
1196 * efi_capsule_delete_file - delete a capsule file
1197 * @filename: File name
1198 *
1199 * Delete a capsule file from capsule directory.
1200 *
1201 * Return: status code
1202 */
1203static efi_status_t efi_capsule_delete_file(const u16 *filename)
1204{
1205 struct efi_file_handle *dirh, *fh;
1206 efi_status_t ret;
1207
1208 ret = EFI_CALL((*bootdev_root->open)(bootdev_root, &dirh,
1209 EFI_CAPSULE_DIR,
1210 EFI_FILE_MODE_READ, 0));
1211 if (ret != EFI_SUCCESS)
1212 return ret;
1213 ret = EFI_CALL((*dirh->open)(dirh, &fh, (u16 *)filename,
1214 EFI_FILE_MODE_READ, 0));
1215 /* ignore an error */
1216 EFI_CALL((*dirh->close)(dirh));
1217
Heinrich Schuchardte5c22812021-06-02 19:28:22 +02001218 if (ret == EFI_SUCCESS)
1219 ret = EFI_CALL((*fh->delete)(fh));
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001220
1221 return ret;
1222}
1223
1224/**
1225 * efi_capsule_scan_done - reset a scan help function
1226 *
1227 * Reset a scan help function
1228 */
1229static void efi_capsule_scan_done(void)
1230{
1231 EFI_CALL((*bootdev_root->close)(bootdev_root));
1232 bootdev_root = NULL;
1233}
1234
1235/**
Heinrich Schuchardte9e84992021-11-20 11:53:12 +01001236 * check_run_capsules() - check whether capsule update should run
Ilias Apalodimasa38d0cb2021-06-29 07:55:51 +03001237 *
1238 * The spec says OsIndications must be set in order to run the capsule update
1239 * on-disk. Since U-Boot doesn't support runtime SetVariable, allow capsules to
1240 * run explicitly if CONFIG_EFI_IGNORE_OSINDICATIONS is selected
Heinrich Schuchardte9e84992021-11-20 11:53:12 +01001241 *
1242 * Return: EFI_SUCCESS if update to run, EFI_NOT_FOUND otherwise
Ilias Apalodimasa38d0cb2021-06-29 07:55:51 +03001243 */
Heinrich Schuchardte9e84992021-11-20 11:53:12 +01001244static efi_status_t check_run_capsules(void)
Ilias Apalodimasa38d0cb2021-06-29 07:55:51 +03001245{
Sughosh Ganu0f5ca5c2022-06-01 23:30:39 +05301246 u64 os_indications = 0x0;
Ilias Apalodimasa38d0cb2021-06-29 07:55:51 +03001247 efi_uintn_t size;
Heinrich Schuchardte9e84992021-11-20 11:53:12 +01001248 efi_status_t r;
Ilias Apalodimasa38d0cb2021-06-29 07:55:51 +03001249
1250 size = sizeof(os_indications);
Simon Glass90975372022-01-23 12:55:12 -07001251 r = efi_get_variable_int(u"OsIndications", &efi_global_variable_guid,
Heinrich Schuchardte9e84992021-11-20 11:53:12 +01001252 NULL, &size, &os_indications, NULL);
Sughosh Ganu0f5ca5c2022-06-01 23:30:39 +05301253 if (!IS_ENABLED(CONFIG_EFI_IGNORE_OSINDICATIONS) &&
1254 (r != EFI_SUCCESS || size != sizeof(os_indications)))
Heinrich Schuchardte9e84992021-11-20 11:53:12 +01001255 return EFI_NOT_FOUND;
Ilias Apalodimasa38d0cb2021-06-29 07:55:51 +03001256
Heinrich Schuchardte9e84992021-11-20 11:53:12 +01001257 if (os_indications &
1258 EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED) {
1259 os_indications &=
1260 ~EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED;
Simon Glass90975372022-01-23 12:55:12 -07001261 r = efi_set_variable_int(u"OsIndications",
Heinrich Schuchardte9e84992021-11-20 11:53:12 +01001262 &efi_global_variable_guid,
1263 EFI_VARIABLE_NON_VOLATILE |
1264 EFI_VARIABLE_BOOTSERVICE_ACCESS |
1265 EFI_VARIABLE_RUNTIME_ACCESS,
1266 sizeof(os_indications),
1267 &os_indications, false);
1268 if (r != EFI_SUCCESS)
1269 log_err("Setting %ls failed\n", L"OsIndications");
1270 return EFI_SUCCESS;
1271 } else if (IS_ENABLED(CONFIG_EFI_IGNORE_OSINDICATIONS)) {
1272 return EFI_SUCCESS;
Sughosh Ganu0f5ca5c2022-06-01 23:30:39 +05301273 } else {
Heinrich Schuchardte9e84992021-11-20 11:53:12 +01001274 return EFI_NOT_FOUND;
1275 }
Ilias Apalodimasa38d0cb2021-06-29 07:55:51 +03001276}
1277
1278/**
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001279 * efi_launch_capsule - launch capsules
1280 *
1281 * Launch all the capsules in system at boot time.
1282 * Called by efi init code
1283 *
1284 * Return: status codde
1285 */
1286efi_status_t efi_launch_capsules(void)
1287{
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001288 struct efi_capsule_header *capsule = NULL;
1289 u16 **files;
1290 unsigned int nfiles, index, i;
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001291 efi_status_t ret;
Sughosh Ganu1cadae22022-10-21 18:16:03 +05301292 bool capsule_update = true;
1293 bool update_status = true;
1294 bool fw_accept_os = false;
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001295
Heinrich Schuchardte9e84992021-11-20 11:53:12 +01001296 if (check_run_capsules() != EFI_SUCCESS)
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001297 return EFI_SUCCESS;
1298
1299 index = get_last_capsule();
1300
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001301 /*
1302 * Find capsules on disk.
1303 * All the capsules are collected at the beginning because
1304 * capsule files will be removed instantly.
1305 */
1306 nfiles = 0;
1307 files = NULL;
1308 ret = efi_capsule_scan_dir(&files, &nfiles);
1309 if (ret != EFI_SUCCESS)
1310 return ret;
1311 if (!nfiles)
1312 return EFI_SUCCESS;
1313
1314 /* Launch capsules */
1315 for (i = 0, ++index; i < nfiles; i++, index++) {
Heinrich Schuchardte3087a12021-07-10 11:03:27 +02001316 log_debug("Applying %ls\n", files[i]);
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001317 if (index > 0xffff)
1318 index = 0;
1319 ret = efi_capsule_read_file(files[i], &capsule);
1320 if (ret == EFI_SUCCESS) {
Masami Hiramatsu3454a692022-02-16 15:15:42 +09001321 ret = efi_capsule_update_firmware(capsule);
Sughosh Ganu1cadae22022-10-21 18:16:03 +05301322 if (ret != EFI_SUCCESS) {
Masami Hiramatsu4b2f8c12022-02-16 15:16:12 +09001323 log_err("Applying capsule %ls failed.\n",
AKASHI Takahiro0d963782020-11-30 18:12:11 +09001324 files[i]);
Sughosh Ganu1cadae22022-10-21 18:16:03 +05301325 update_status = false;
1326 } else {
Masami Hiramatsu4b2f8c12022-02-16 15:16:12 +09001327 log_info("Applying capsule %ls succeeded.\n",
1328 files[i]);
Sughosh Ganu1cadae22022-10-21 18:16:03 +05301329 if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) {
1330 fwu_post_update_checks(capsule,
1331 &fw_accept_os,
1332 &capsule_update);
1333 }
1334 }
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001335
Masami Hiramatsu1001a102021-11-12 22:05:15 +09001336 /* create CapsuleXXXX */
1337 set_capsule_result(index, capsule, ret);
1338
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001339 free(capsule);
1340 } else {
Heinrich Schuchardte3087a12021-07-10 11:03:27 +02001341 log_err("Reading capsule %ls failed\n", files[i]);
Sughosh Ganu1cadae22022-10-21 18:16:03 +05301342 update_status = false;
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001343 }
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001344 /* delete a capsule either in case of success or failure */
1345 ret = efi_capsule_delete_file(files[i]);
1346 if (ret != EFI_SUCCESS)
Heinrich Schuchardte3087a12021-07-10 11:03:27 +02001347 log_err("Deleting capsule %ls failed\n",
AKASHI Takahiro0d963782020-11-30 18:12:11 +09001348 files[i]);
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001349 }
Sughosh Ganu1cadae22022-10-21 18:16:03 +05301350
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001351 efi_capsule_scan_done();
1352
Sughosh Ganu1cadae22022-10-21 18:16:03 +05301353 if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) {
1354 if (capsule_update == true && update_status == true) {
1355 ret = fwu_post_update_process(fw_accept_os);
1356 } else if (capsule_update == true && update_status == false) {
1357 log_err("All capsules were not updated. Not updating FWU metadata\n");
1358 }
1359 }
1360
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001361 for (i = 0; i < nfiles; i++)
1362 free(files[i]);
1363 free(files);
1364
Masami Hiramatsu4b2f8c12022-02-16 15:16:12 +09001365 /*
1366 * UEFI spec requires to reset system after complete processing capsule
1367 * update on the storage.
1368 */
Masami Hiramatsuff744862022-03-21 22:37:56 +09001369 log_info("Reboot after firmware update.\n");
Masami Hiramatsu4b2f8c12022-02-16 15:16:12 +09001370 /* Cold reset is required for loading the new firmware. */
Masami Hiramatsuff744862022-03-21 22:37:56 +09001371 sysreset_walk_halt(SYSRESET_COLD);
Masami Hiramatsu4b2f8c12022-02-16 15:16:12 +09001372 hang();
1373 /* not reach here */
1374
1375 return 0;
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001376}
1377#endif /* CONFIG_EFI_CAPSULE_ON_DISK */