blob: 843a3e3def4ee41aa54de5126508da1c85c17932 [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
Sughosh Ganu586bb982020-12-30 19:27:09 +053019#include <crypto/pkcs7.h>
20#include <crypto/pkcs7_parser.h>
21#include <linux/err.h>
22
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090023const efi_guid_t efi_guid_capsule_report = EFI_CAPSULE_REPORT_GUID;
AKASHI Takahiro0d963782020-11-30 18:12:11 +090024static const efi_guid_t efi_guid_firmware_management_capsule_id =
25 EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID;
26const efi_guid_t efi_guid_firmware_management_protocol =
27 EFI_FIRMWARE_MANAGEMENT_PROTOCOL_GUID;
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090028
AKASHI Takahiro45b819542020-11-17 09:27:56 +090029#ifdef CONFIG_EFI_CAPSULE_ON_DISK
30/* for file system access */
31static struct efi_file_handle *bootdev_root;
32#endif
33
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090034/**
35 * get_last_capsule - get the last capsule index
36 *
37 * Retrieve the index of the capsule invoked last time from "CapsuleLast"
38 * variable.
39 *
40 * Return:
41 * * > 0 - the last capsule index invoked
42 * * 0xffff - on error, or no capsule invoked yet
43 */
44static __maybe_unused unsigned int get_last_capsule(void)
45{
46 u16 value16[11]; /* "CapsuleXXXX": non-null-terminated */
Heinrich Schuchardt812f6e02021-02-09 20:20:34 +010047 char value[5];
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090048 efi_uintn_t size;
49 unsigned long index = 0xffff;
50 efi_status_t ret;
Heinrich Schuchardt812f6e02021-02-09 20:20:34 +010051 int i;
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090052
53 size = sizeof(value16);
54 ret = efi_get_variable_int(L"CapsuleLast", &efi_guid_capsule_report,
55 NULL, &size, value16, NULL);
Heinrich Schuchardt812f6e02021-02-09 20:20:34 +010056 if (ret != EFI_SUCCESS || size != 22 ||
57 u16_strncmp(value16, L"Capsule", 7))
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090058 goto err;
Heinrich Schuchardt812f6e02021-02-09 20:20:34 +010059 for (i = 0; i < 4; ++i) {
60 u16 c = value16[i + 7];
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090061
Heinrich Schuchardt812f6e02021-02-09 20:20:34 +010062 if (!c || c > 0x7f)
63 goto err;
64 value[i] = c;
65 }
66 value[4] = 0;
67 if (strict_strtoul(value, 16, &index))
68 index = 0xffff;
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090069err:
70 return index;
71}
72
73/**
74 * set_capsule_result - set a result variable
75 * @capsule: Capsule
76 * @return_status: Return status
77 *
78 * Create and set a result variable, "CapsuleXXXX", for the capsule,
79 * @capsule.
80 */
81static __maybe_unused
82void set_capsule_result(int index, struct efi_capsule_header *capsule,
83 efi_status_t return_status)
84{
85 u16 variable_name16[12];
86 struct efi_capsule_result_variable_header result;
87 struct efi_time time;
88 efi_status_t ret;
89
Ilias Apalodimas21575292020-12-31 12:26:46 +020090 efi_create_indexed_name(variable_name16, sizeof(variable_name16),
91 "Capsule", index);
AKASHI Takahiro473d9b32020-11-17 09:27:55 +090092 result.variable_total_size = sizeof(result);
93 result.capsule_guid = capsule->capsule_guid;
94 ret = EFI_CALL((*efi_runtime_services.get_time)(&time, NULL));
95 if (ret == EFI_SUCCESS)
96 memcpy(&result.capsule_processed, &time, sizeof(time));
97 else
98 memset(&result.capsule_processed, 0, sizeof(time));
99 result.capsule_status = return_status;
100 ret = efi_set_variable(variable_name16, &efi_guid_capsule_report,
101 EFI_VARIABLE_NON_VOLATILE |
102 EFI_VARIABLE_BOOTSERVICE_ACCESS |
103 EFI_VARIABLE_RUNTIME_ACCESS,
104 sizeof(result), &result);
105 if (ret)
Heinrich Schuchardte3087a12021-07-10 11:03:27 +0200106 log_err("Setting %ls failed\n", variable_name16);
AKASHI Takahiro473d9b32020-11-17 09:27:55 +0900107}
108
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900109#ifdef CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT
110/**
111 * efi_fmp_find - search for Firmware Management Protocol drivers
112 * @image_type: Image type guid
113 * @instance: Instance number
114 * @handles: Handles of FMP drivers
115 * @no_handles: Number of handles
116 *
117 * Search for Firmware Management Protocol drivers, matching the image
118 * type, @image_type and the machine instance, @instance, from the list,
119 * @handles.
120 *
121 * Return:
122 * * Protocol instance - on success
123 * * NULL - on failure
124 */
125static struct efi_firmware_management_protocol *
126efi_fmp_find(efi_guid_t *image_type, u64 instance, efi_handle_t *handles,
127 efi_uintn_t no_handles)
128{
129 efi_handle_t *handle;
130 struct efi_firmware_management_protocol *fmp;
131 struct efi_firmware_image_descriptor *image_info, *desc;
132 efi_uintn_t info_size, descriptor_size;
133 u32 descriptor_version;
134 u8 descriptor_count;
135 u32 package_version;
136 u16 *package_version_name;
137 bool found = false;
138 int i, j;
139 efi_status_t ret;
140
141 for (i = 0, handle = handles; i < no_handles; i++, handle++) {
142 ret = EFI_CALL(efi_handle_protocol(
143 *handle,
144 &efi_guid_firmware_management_protocol,
145 (void **)&fmp));
146 if (ret != EFI_SUCCESS)
147 continue;
148
149 /* get device's image info */
150 info_size = 0;
151 image_info = NULL;
152 descriptor_version = 0;
153 descriptor_count = 0;
154 descriptor_size = 0;
155 package_version = 0;
156 package_version_name = NULL;
157 ret = EFI_CALL(fmp->get_image_info(fmp, &info_size,
158 image_info,
159 &descriptor_version,
160 &descriptor_count,
161 &descriptor_size,
162 &package_version,
163 &package_version_name));
164 if (ret != EFI_BUFFER_TOO_SMALL)
165 goto skip;
166
167 image_info = malloc(info_size);
168 if (!image_info)
169 goto skip;
170
171 ret = EFI_CALL(fmp->get_image_info(fmp, &info_size,
172 image_info,
173 &descriptor_version,
174 &descriptor_count,
175 &descriptor_size,
176 &package_version,
177 &package_version_name));
178 if (ret != EFI_SUCCESS ||
179 descriptor_version != EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION)
180 goto skip;
181
182 /* matching */
183 for (j = 0, desc = image_info; j < descriptor_count;
184 j++, desc = (void *)desc + descriptor_size) {
185 log_debug("+++ desc[%d] index: %d, name: %ls\n",
186 j, desc->image_index, desc->image_id_name);
187 if (!guidcmp(&desc->image_type_id, image_type) &&
188 (!instance ||
189 !desc->hardware_instance ||
190 desc->hardware_instance == instance))
191 found = true;
192 }
193
194skip:
195 efi_free_pool(package_version_name);
196 free(image_info);
197 EFI_CALL(efi_close_protocol(
198 (efi_handle_t)fmp,
199 &efi_guid_firmware_management_protocol,
200 NULL, NULL));
201 if (found)
202 return fmp;
203 }
204
205 return NULL;
206}
207
Sughosh Ganu586bb982020-12-30 19:27:09 +0530208#if defined(CONFIG_EFI_CAPSULE_AUTHENTICATE)
209
210const efi_guid_t efi_guid_capsule_root_cert_guid =
211 EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID;
212
Sughosh Ganu586bb982020-12-30 19:27:09 +0530213efi_status_t efi_capsule_authenticate(const void *capsule, efi_uintn_t capsule_size,
214 void **image, efi_uintn_t *image_size)
215{
216 u8 *buf;
217 int ret;
218 void *fdt_pkey, *pkey;
219 efi_uintn_t pkey_len;
220 uint64_t monotonic_count;
221 struct efi_signature_store *truststore;
222 struct pkcs7_message *capsule_sig;
223 struct efi_image_regions *regs;
224 struct efi_firmware_image_authentication *auth_hdr;
225 efi_status_t status;
226
227 status = EFI_SECURITY_VIOLATION;
228 capsule_sig = NULL;
229 truststore = NULL;
230 regs = NULL;
231
232 /* Sanity checks */
233 if (capsule == NULL || capsule_size == 0)
234 goto out;
235
236 auth_hdr = (struct efi_firmware_image_authentication *)capsule;
237 if (capsule_size < sizeof(*auth_hdr))
238 goto out;
239
240 if (auth_hdr->auth_info.hdr.dwLength <=
241 offsetof(struct win_certificate_uefi_guid, cert_data))
242 goto out;
243
244 if (guidcmp(&auth_hdr->auth_info.cert_type, &efi_guid_cert_type_pkcs7))
245 goto out;
246
247 *image = (uint8_t *)capsule + sizeof(auth_hdr->monotonic_count) +
248 auth_hdr->auth_info.hdr.dwLength;
249 *image_size = capsule_size - auth_hdr->auth_info.hdr.dwLength -
250 sizeof(auth_hdr->monotonic_count);
251 memcpy(&monotonic_count, &auth_hdr->monotonic_count,
252 sizeof(monotonic_count));
253
254 /* data to be digested */
255 regs = calloc(sizeof(*regs) + sizeof(struct image_region) * 2, 1);
256 if (!regs)
257 goto out;
258
259 regs->max = 2;
260 efi_image_region_add(regs, (uint8_t *)*image,
261 (uint8_t *)*image + *image_size, 1);
262
263 efi_image_region_add(regs, (uint8_t *)&monotonic_count,
264 (uint8_t *)&monotonic_count + sizeof(monotonic_count),
265 1);
266
267 capsule_sig = efi_parse_pkcs7_header(auth_hdr->auth_info.cert_data,
268 auth_hdr->auth_info.hdr.dwLength
269 - sizeof(auth_hdr->auth_info),
270 &buf);
271 if (IS_ERR(capsule_sig)) {
272 debug("Parsing variable's pkcs7 header failed\n");
273 capsule_sig = NULL;
274 goto out;
275 }
276
277 ret = efi_get_public_key_data(&fdt_pkey, &pkey_len);
278 if (ret < 0)
279 goto out;
280
281 pkey = malloc(pkey_len);
282 if (!pkey)
283 goto out;
284
285 memcpy(pkey, fdt_pkey, pkey_len);
286 truststore = efi_build_signature_store(pkey, pkey_len);
287 if (!truststore)
288 goto out;
289
290 /* verify signature */
291 if (efi_signature_verify(regs, capsule_sig, truststore, NULL)) {
292 debug("Verified\n");
293 } else {
294 debug("Verifying variable's signature failed\n");
295 goto out;
296 }
297
298 status = EFI_SUCCESS;
299
300out:
301 efi_sigstore_free(truststore);
302 pkcs7_free_message(capsule_sig);
303 free(regs);
304
305 return status;
306}
307#else
308efi_status_t efi_capsule_authenticate(const void *capsule, efi_uintn_t capsule_size,
309 void **image, efi_uintn_t *image_size)
310{
311 return EFI_UNSUPPORTED;
312}
313#endif /* CONFIG_EFI_CAPSULE_AUTHENTICATE */
314
315
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900316/**
317 * efi_capsule_update_firmware - update firmware from capsule
318 * @capsule_data: Capsule
319 *
320 * Update firmware, using a capsule, @capsule_data. Loading any FMP
321 * drivers embedded in a capsule is not supported.
322 *
323 * Return: status code
324 */
325static efi_status_t efi_capsule_update_firmware(
326 struct efi_capsule_header *capsule_data)
327{
328 struct efi_firmware_management_capsule_header *capsule;
329 struct efi_firmware_management_capsule_image_header *image;
330 size_t capsule_size;
331 void *image_binary, *vendor_code;
332 efi_handle_t *handles;
333 efi_uintn_t no_handles;
334 int item;
335 struct efi_firmware_management_protocol *fmp;
336 u16 *abort_reason;
337 efi_status_t ret = EFI_SUCCESS;
338
339 /* sanity check */
340 if (capsule_data->header_size < sizeof(*capsule) ||
341 capsule_data->header_size >= capsule_data->capsule_image_size)
342 return EFI_INVALID_PARAMETER;
343
344 capsule = (void *)capsule_data + capsule_data->header_size;
345 capsule_size = capsule_data->capsule_image_size
346 - capsule_data->header_size;
347
348 if (capsule->version != 0x00000001)
349 return EFI_UNSUPPORTED;
350
351 handles = NULL;
352 ret = EFI_CALL(efi_locate_handle_buffer(
353 BY_PROTOCOL,
354 &efi_guid_firmware_management_protocol,
355 NULL, &no_handles, (efi_handle_t **)&handles));
356 if (ret != EFI_SUCCESS)
357 return EFI_UNSUPPORTED;
358
359 /* Payload */
360 for (item = capsule->embedded_driver_count;
361 item < capsule->embedded_driver_count
362 + capsule->payload_item_count; item++) {
363 /* sanity check */
364 if ((capsule->item_offset_list[item] + sizeof(*image)
365 >= capsule_size)) {
Heinrich Schuchardte3087a12021-07-10 11:03:27 +0200366 log_err("Capsule does not have enough data\n");
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900367 ret = EFI_INVALID_PARAMETER;
368 goto out;
369 }
370
371 image = (void *)capsule + capsule->item_offset_list[item];
372
373 if (image->version != 0x00000003) {
374 ret = EFI_UNSUPPORTED;
375 goto out;
376 }
377
378 /* find a device for update firmware */
379 /* TODO: should we pass index as well, or nothing but type? */
380 fmp = efi_fmp_find(&image->update_image_type_id,
381 image->update_hardware_instance,
382 handles, no_handles);
383 if (!fmp) {
Heinrich Schuchardte3087a12021-07-10 11:03:27 +0200384 log_err("FMP driver not found for firmware type %pUl, hardware instance %lld\n",
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900385 &image->update_image_type_id,
386 image->update_hardware_instance);
387 ret = EFI_UNSUPPORTED;
388 goto out;
389 }
390
391 /* do update */
392 image_binary = (void *)image + sizeof(*image);
393 vendor_code = image_binary + image->update_image_size;
394
395 abort_reason = NULL;
396 ret = EFI_CALL(fmp->set_image(fmp, image->update_image_index,
397 image_binary,
398 image->update_image_size,
399 vendor_code, NULL,
400 &abort_reason));
401 if (ret != EFI_SUCCESS) {
Heinrich Schuchardte3087a12021-07-10 11:03:27 +0200402 log_err("Firmware update failed: %ls\n",
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900403 abort_reason);
404 efi_free_pool(abort_reason);
405 goto out;
406 }
407 }
408
409out:
410 efi_free_pool(handles);
411
412 return ret;
413}
414#else
415static efi_status_t efi_capsule_update_firmware(
416 struct efi_capsule_header *capsule_data)
417{
418 return EFI_UNSUPPORTED;
419}
420#endif /* CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT */
421
AKASHI Takahiro473d9b32020-11-17 09:27:55 +0900422/**
423 * efi_update_capsule() - process information from operating system
424 * @capsule_header_array: Array of virtual address pointers
425 * @capsule_count: Number of pointers in capsule_header_array
426 * @scatter_gather_list: Array of physical address pointers
427 *
428 * This function implements the UpdateCapsule() runtime service.
429 *
430 * See the Unified Extensible Firmware Interface (UEFI) specification for
431 * details.
432 *
433 * Return: status code
434 */
435efi_status_t EFIAPI efi_update_capsule(
436 struct efi_capsule_header **capsule_header_array,
437 efi_uintn_t capsule_count,
438 u64 scatter_gather_list)
439{
440 struct efi_capsule_header *capsule;
441 unsigned int i;
442 efi_status_t ret;
443
Simon Glass83698b22021-02-07 14:27:02 -0700444 EFI_ENTRY("%p, %zu, %llu\n", capsule_header_array, capsule_count,
AKASHI Takahiro473d9b32020-11-17 09:27:55 +0900445 scatter_gather_list);
446
447 if (!capsule_count) {
448 ret = EFI_INVALID_PARAMETER;
449 goto out;
450 }
451
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900452 ret = EFI_SUCCESS;
AKASHI Takahiro473d9b32020-11-17 09:27:55 +0900453 for (i = 0, capsule = *capsule_header_array; i < capsule_count;
454 i++, capsule = *(++capsule_header_array)) {
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900455 /* sanity check */
456 if (capsule->header_size < sizeof(*capsule) ||
457 capsule->capsule_image_size < sizeof(*capsule)) {
Heinrich Schuchardte3087a12021-07-10 11:03:27 +0200458 log_err("Capsule does not have enough data\n");
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900459 continue;
460 }
461
462 log_debug("Capsule[%d] (guid:%pUl)\n",
463 i, &capsule->capsule_guid);
464 if (!guidcmp(&capsule->capsule_guid,
465 &efi_guid_firmware_management_capsule_id)) {
466 ret = efi_capsule_update_firmware(capsule);
467 } else {
Heinrich Schuchardte3087a12021-07-10 11:03:27 +0200468 log_err("Unsupported capsule type: %pUl\n",
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900469 &capsule->capsule_guid);
470 ret = EFI_UNSUPPORTED;
471 }
472
473 if (ret != EFI_SUCCESS)
474 goto out;
AKASHI Takahiro473d9b32020-11-17 09:27:55 +0900475 }
Jose Marinhoebb61ee2021-03-02 17:26:38 +0000476
477 if (IS_ENABLED(CONFIG_EFI_ESRT)) {
478 /* Rebuild the ESRT to reflect any updated FW images. */
479 ret = efi_esrt_populate();
480 if (ret != EFI_SUCCESS)
Heinrich Schuchardte3087a12021-07-10 11:03:27 +0200481 log_warning("ESRT update failed\n");
Jose Marinhoebb61ee2021-03-02 17:26:38 +0000482 }
Jose Marinhoaf886ce2021-04-19 14:54:33 +0100483out:
Jose Marinhoebb61ee2021-03-02 17:26:38 +0000484
AKASHI Takahiro473d9b32020-11-17 09:27:55 +0900485 return EFI_EXIT(ret);
486}
487
488/**
489 * efi_query_capsule_caps() - check if capsule is supported
490 * @capsule_header_array: Array of virtual pointers
491 * @capsule_count: Number of pointers in capsule_header_array
492 * @maximum_capsule_size: Maximum capsule size
493 * @reset_type: Type of reset needed for capsule update
494 *
495 * This function implements the QueryCapsuleCapabilities() runtime service.
496 *
497 * See the Unified Extensible Firmware Interface (UEFI) specification for
498 * details.
499 *
500 * Return: status code
501 */
502efi_status_t EFIAPI efi_query_capsule_caps(
503 struct efi_capsule_header **capsule_header_array,
504 efi_uintn_t capsule_count,
505 u64 *maximum_capsule_size,
506 u32 *reset_type)
507{
508 struct efi_capsule_header *capsule __attribute__((unused));
509 unsigned int i;
510 efi_status_t ret;
511
Simon Glass83698b22021-02-07 14:27:02 -0700512 EFI_ENTRY("%p, %zu, %p, %p\n", capsule_header_array, capsule_count,
AKASHI Takahiro473d9b32020-11-17 09:27:55 +0900513 maximum_capsule_size, reset_type);
514
515 if (!maximum_capsule_size) {
516 ret = EFI_INVALID_PARAMETER;
517 goto out;
518 }
519
520 *maximum_capsule_size = U64_MAX;
521 *reset_type = EFI_RESET_COLD;
522
523 ret = EFI_SUCCESS;
524 for (i = 0, capsule = *capsule_header_array; i < capsule_count;
525 i++, capsule = *(++capsule_header_array)) {
526 /* TODO */
527 }
528out:
529 return EFI_EXIT(ret);
530}
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900531
532#ifdef CONFIG_EFI_CAPSULE_ON_DISK
533/**
534 * get_dp_device - retrieve a device path from boot variable
535 * @boot_var: Boot variable name
536 * @device_dp Device path
537 *
538 * Retrieve a device patch from boot variable, @boot_var.
539 *
540 * Return: status code
541 */
542static efi_status_t get_dp_device(u16 *boot_var,
543 struct efi_device_path **device_dp)
544{
545 void *buf = NULL;
546 efi_uintn_t size;
547 struct efi_load_option lo;
548 struct efi_device_path *file_dp;
549 efi_status_t ret;
550
551 size = 0;
552 ret = efi_get_variable_int(boot_var, &efi_global_variable_guid,
553 NULL, &size, NULL, NULL);
554 if (ret == EFI_BUFFER_TOO_SMALL) {
555 buf = malloc(size);
556 if (!buf)
557 return EFI_OUT_OF_RESOURCES;
558 ret = efi_get_variable_int(boot_var, &efi_global_variable_guid,
559 NULL, &size, buf, NULL);
560 }
561 if (ret != EFI_SUCCESS)
562 return ret;
563
564 efi_deserialize_load_option(&lo, buf, &size);
565
566 if (lo.attributes & LOAD_OPTION_ACTIVE) {
567 efi_dp_split_file_path(lo.file_path, device_dp, &file_dp);
568 efi_free_pool(file_dp);
569
570 ret = EFI_SUCCESS;
571 } else {
572 ret = EFI_NOT_FOUND;
573 }
574
575 free(buf);
576
577 return ret;
578}
579
580/**
581 * device_is_present_and_system_part - check if a device exists
582 * @dp Device path
583 *
584 * Check if a device pointed to by the device path, @dp, exists and is
585 * located in UEFI system partition.
586 *
587 * Return: true - yes, false - no
588 */
589static bool device_is_present_and_system_part(struct efi_device_path *dp)
590{
591 efi_handle_t handle;
592
593 handle = efi_dp_find_obj(dp, NULL);
594 if (!handle)
595 return false;
596
597 return efi_disk_is_system_part(handle);
598}
599
600/**
601 * find_boot_device - identify the boot device
602 *
603 * Identify the boot device from boot-related variables as UEFI
604 * specification describes and put its handle into bootdev_root.
605 *
606 * Return: status code
607 */
608static efi_status_t find_boot_device(void)
609{
610 char boot_var[9];
611 u16 boot_var16[9], *p, bootnext, *boot_order = NULL;
612 efi_uintn_t size;
613 int i, num;
614 struct efi_simple_file_system_protocol *volume;
615 struct efi_device_path *boot_dev = NULL;
616 efi_status_t ret;
617
618 /* find active boot device in BootNext */
619 bootnext = 0;
620 size = sizeof(bootnext);
621 ret = efi_get_variable_int(L"BootNext",
622 (efi_guid_t *)&efi_global_variable_guid,
623 NULL, &size, &bootnext, NULL);
624 if (ret == EFI_SUCCESS || ret == EFI_BUFFER_TOO_SMALL) {
625 /* BootNext does exist here */
626 if (ret == EFI_BUFFER_TOO_SMALL || size != sizeof(u16)) {
AKASHI Takahiro0d963782020-11-30 18:12:11 +0900627 log_err("BootNext must be 16-bit integer\n");
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900628 goto skip;
629 }
630 sprintf((char *)boot_var, "Boot%04X", bootnext);
631 p = boot_var16;
632 utf8_utf16_strcpy(&p, boot_var);
633
634 ret = get_dp_device(boot_var16, &boot_dev);
635 if (ret == EFI_SUCCESS) {
636 if (device_is_present_and_system_part(boot_dev)) {
637 goto out;
638 } else {
639 efi_free_pool(boot_dev);
640 boot_dev = NULL;
641 }
642 }
643 }
644
645skip:
646 /* find active boot device in BootOrder */
647 size = 0;
648 ret = efi_get_variable_int(L"BootOrder", &efi_global_variable_guid,
649 NULL, &size, NULL, NULL);
650 if (ret == EFI_BUFFER_TOO_SMALL) {
651 boot_order = malloc(size);
652 if (!boot_order) {
653 ret = EFI_OUT_OF_RESOURCES;
654 goto out;
655 }
656
657 ret = efi_get_variable_int(L"BootOrder",
658 &efi_global_variable_guid,
659 NULL, &size, boot_order, NULL);
660 }
661 if (ret != EFI_SUCCESS)
662 goto out;
663
664 /* check in higher order */
665 num = size / sizeof(u16);
666 for (i = 0; i < num; i++) {
667 sprintf((char *)boot_var, "Boot%04X", boot_order[i]);
668 p = boot_var16;
669 utf8_utf16_strcpy(&p, boot_var);
670 ret = get_dp_device(boot_var16, &boot_dev);
671 if (ret != EFI_SUCCESS)
672 continue;
673
674 if (device_is_present_and_system_part(boot_dev))
675 break;
676
677 efi_free_pool(boot_dev);
678 boot_dev = NULL;
679 }
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900680 if (boot_dev) {
681 u16 *path_str;
682
683 path_str = efi_dp_str(boot_dev);
Heinrich Schuchardte3087a12021-07-10 11:03:27 +0200684 log_debug("Boot device %ls\n", path_str);
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900685 efi_free_pool(path_str);
686
687 volume = efi_fs_from_path(boot_dev);
688 if (!volume)
689 ret = EFI_DEVICE_ERROR;
690 else
691 ret = EFI_CALL(volume->open_volume(volume,
692 &bootdev_root));
693 efi_free_pool(boot_dev);
694 } else {
695 ret = EFI_NOT_FOUND;
696 }
AKASHI Takahirofa390e62021-04-20 10:03:16 +0900697out:
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900698 free(boot_order);
699
700 return ret;
701}
702
703/**
704 * efi_capsule_scan_dir - traverse a capsule directory in boot device
705 * @files: Array of file names
706 * @num: Number of elements in @files
707 *
708 * Traverse a capsule directory in boot device.
709 * Called by initialization code, and returns an array of capsule file
710 * names in @files.
711 *
712 * Return: status code
713 */
714static efi_status_t efi_capsule_scan_dir(u16 ***files, unsigned int *num)
715{
716 struct efi_file_handle *dirh;
717 struct efi_file_info *dirent;
718 efi_uintn_t dirent_size, tmp_size;
719 unsigned int count;
720 u16 **tmp_files;
721 efi_status_t ret;
722
723 ret = find_boot_device();
724 if (ret == EFI_NOT_FOUND) {
Heinrich Schuchardte3087a12021-07-10 11:03:27 +0200725 log_debug("Boot device is not set\n");
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900726 *num = 0;
727 return EFI_SUCCESS;
728 } else if (ret != EFI_SUCCESS) {
729 return EFI_DEVICE_ERROR;
730 }
731
732 /* count capsule files */
733 ret = EFI_CALL((*bootdev_root->open)(bootdev_root, &dirh,
734 EFI_CAPSULE_DIR,
735 EFI_FILE_MODE_READ, 0));
736 if (ret != EFI_SUCCESS) {
737 *num = 0;
738 return EFI_SUCCESS;
739 }
740
741 dirent_size = 256;
742 dirent = malloc(dirent_size);
743 if (!dirent)
744 return EFI_OUT_OF_RESOURCES;
745
746 count = 0;
747 while (1) {
748 tmp_size = dirent_size;
749 ret = EFI_CALL((*dirh->read)(dirh, &tmp_size, dirent));
750 if (ret == EFI_BUFFER_TOO_SMALL) {
Heinrich Schuchardtaa27e5d2021-04-11 06:53:04 +0200751 struct efi_file_info *old_dirent = dirent;
752
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900753 dirent = realloc(dirent, tmp_size);
754 if (!dirent) {
Heinrich Schuchardtaa27e5d2021-04-11 06:53:04 +0200755 dirent = old_dirent;
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900756 ret = EFI_OUT_OF_RESOURCES;
757 goto err;
758 }
759 dirent_size = tmp_size;
760 ret = EFI_CALL((*dirh->read)(dirh, &tmp_size, dirent));
761 }
762 if (ret != EFI_SUCCESS)
763 goto err;
764 if (!tmp_size)
765 break;
766
Heinrich Schuchardt76b708a2021-02-09 17:45:33 +0100767 if (!(dirent->attribute & EFI_FILE_DIRECTORY))
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900768 count++;
769 }
770
771 ret = EFI_CALL((*dirh->setpos)(dirh, 0));
772 if (ret != EFI_SUCCESS)
773 goto err;
774
775 /* make a list */
AKASHI Takahiroc8fc12f2021-01-22 10:43:27 +0900776 tmp_files = malloc(count * sizeof(*tmp_files));
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900777 if (!tmp_files) {
778 ret = EFI_OUT_OF_RESOURCES;
779 goto err;
780 }
781
782 count = 0;
783 while (1) {
784 tmp_size = dirent_size;
785 ret = EFI_CALL((*dirh->read)(dirh, &tmp_size, dirent));
786 if (ret != EFI_SUCCESS)
787 goto err;
788 if (!tmp_size)
789 break;
790
791 if (!(dirent->attribute & EFI_FILE_DIRECTORY) &&
792 u16_strcmp(dirent->file_name, L".") &&
793 u16_strcmp(dirent->file_name, L".."))
794 tmp_files[count++] = u16_strdup(dirent->file_name);
795 }
796 /* ignore an error */
797 EFI_CALL((*dirh->close)(dirh));
798
799 /* in ascii order */
800 /* FIXME: u16 version of strcasecmp */
801 qsort(tmp_files, count, sizeof(*tmp_files),
802 (int (*)(const void *, const void *))strcasecmp);
803 *files = tmp_files;
804 *num = count;
805 ret = EFI_SUCCESS;
806err:
807 free(dirent);
808
809 return ret;
810}
811
812/**
813 * efi_capsule_read_file - read in a capsule file
814 * @filename: File name
815 * @capsule: Pointer to buffer for capsule
816 *
817 * Read a capsule file and put its content in @capsule.
818 *
819 * Return: status code
820 */
821static efi_status_t efi_capsule_read_file(const u16 *filename,
822 struct efi_capsule_header **capsule)
823{
824 struct efi_file_handle *dirh, *fh;
825 struct efi_file_info *file_info = NULL;
826 struct efi_capsule_header *buf = NULL;
827 efi_uintn_t size;
828 efi_status_t ret;
829
830 ret = EFI_CALL((*bootdev_root->open)(bootdev_root, &dirh,
831 EFI_CAPSULE_DIR,
832 EFI_FILE_MODE_READ, 0));
833 if (ret != EFI_SUCCESS)
834 return ret;
835 ret = EFI_CALL((*dirh->open)(dirh, &fh, (u16 *)filename,
836 EFI_FILE_MODE_READ, 0));
837 /* ignore an error */
838 EFI_CALL((*dirh->close)(dirh));
839 if (ret != EFI_SUCCESS)
840 return ret;
841
842 /* file size */
843 size = 0;
844 ret = EFI_CALL((*fh->getinfo)(fh, &efi_file_info_guid,
845 &size, file_info));
846 if (ret == EFI_BUFFER_TOO_SMALL) {
847 file_info = malloc(size);
848 if (!file_info) {
849 ret = EFI_OUT_OF_RESOURCES;
850 goto err;
851 }
852 ret = EFI_CALL((*fh->getinfo)(fh, &efi_file_info_guid,
853 &size, file_info));
854 }
855 if (ret != EFI_SUCCESS)
856 goto err;
857 size = file_info->file_size;
858 free(file_info);
859 buf = malloc(size);
860 if (!buf) {
861 ret = EFI_OUT_OF_RESOURCES;
862 goto err;
863 }
864
865 /* fetch data */
866 ret = EFI_CALL((*fh->read)(fh, &size, buf));
867 if (ret == EFI_SUCCESS) {
868 if (size >= buf->capsule_image_size) {
869 *capsule = buf;
870 } else {
871 free(buf);
872 ret = EFI_INVALID_PARAMETER;
873 }
874 } else {
875 free(buf);
876 }
877err:
878 EFI_CALL((*fh->close)(fh));
879
880 return ret;
881}
882
883/**
884 * efi_capsule_delete_file - delete a capsule file
885 * @filename: File name
886 *
887 * Delete a capsule file from capsule directory.
888 *
889 * Return: status code
890 */
891static efi_status_t efi_capsule_delete_file(const u16 *filename)
892{
893 struct efi_file_handle *dirh, *fh;
894 efi_status_t ret;
895
896 ret = EFI_CALL((*bootdev_root->open)(bootdev_root, &dirh,
897 EFI_CAPSULE_DIR,
898 EFI_FILE_MODE_READ, 0));
899 if (ret != EFI_SUCCESS)
900 return ret;
901 ret = EFI_CALL((*dirh->open)(dirh, &fh, (u16 *)filename,
902 EFI_FILE_MODE_READ, 0));
903 /* ignore an error */
904 EFI_CALL((*dirh->close)(dirh));
905
Heinrich Schuchardte5c22812021-06-02 19:28:22 +0200906 if (ret == EFI_SUCCESS)
907 ret = EFI_CALL((*fh->delete)(fh));
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900908
909 return ret;
910}
911
912/**
913 * efi_capsule_scan_done - reset a scan help function
914 *
915 * Reset a scan help function
916 */
917static void efi_capsule_scan_done(void)
918{
919 EFI_CALL((*bootdev_root->close)(bootdev_root));
920 bootdev_root = NULL;
921}
922
923/**
Ilias Apalodimasfac773e2021-06-22 17:38:53 +0300924 * efi_load_capsule_drivers - initialize capsule drivers
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900925 *
Ilias Apalodimasfac773e2021-06-22 17:38:53 +0300926 * Generic FMP drivers backed by DFU
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900927 *
928 * Return: status code
929 */
Ilias Apalodimasfac773e2021-06-22 17:38:53 +0300930efi_status_t __weak efi_load_capsule_drivers(void)
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900931{
AKASHI Takahirof4818e62020-11-30 18:12:12 +0900932 __maybe_unused efi_handle_t handle;
933 efi_status_t ret = EFI_SUCCESS;
934
935 if (IS_ENABLED(CONFIG_EFI_CAPSULE_FIRMWARE_FIT)) {
936 handle = NULL;
937 ret = EFI_CALL(efi_install_multiple_protocol_interfaces(
938 &handle, &efi_guid_firmware_management_protocol,
939 &efi_fmp_fit, NULL));
940 }
941
AKASHI Takahiro7ff3f3c2020-11-17 09:28:00 +0900942 if (IS_ENABLED(CONFIG_EFI_CAPSULE_FIRMWARE_RAW)) {
943 handle = NULL;
944 ret = EFI_CALL(efi_install_multiple_protocol_interfaces(
Masami Hiramatsuf5388522021-06-22 17:38:51 +0300945 &handle,
AKASHI Takahiro7ff3f3c2020-11-17 09:28:00 +0900946 &efi_guid_firmware_management_protocol,
947 &efi_fmp_raw, NULL));
948 }
949
AKASHI Takahirof4818e62020-11-30 18:12:12 +0900950 return ret;
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900951}
952
953/**
Ilias Apalodimasa38d0cb2021-06-29 07:55:51 +0300954 * check_run_capsules - Check whether capsule update should run
955 *
956 * The spec says OsIndications must be set in order to run the capsule update
957 * on-disk. Since U-Boot doesn't support runtime SetVariable, allow capsules to
958 * run explicitly if CONFIG_EFI_IGNORE_OSINDICATIONS is selected
959 */
960static bool check_run_capsules(void)
961{
962 u64 os_indications;
963 efi_uintn_t size;
964 efi_status_t ret;
965
966 if (IS_ENABLED(CONFIG_EFI_IGNORE_OSINDICATIONS))
967 return true;
968
969 size = sizeof(os_indications);
970 ret = efi_get_variable_int(L"OsIndications", &efi_global_variable_guid,
971 NULL, &size, &os_indications, NULL);
972 if (ret == EFI_SUCCESS &&
973 (os_indications
974 & EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED))
975 return true;
976
977 return false;
978}
979
980/**
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900981 * efi_launch_capsule - launch capsules
982 *
983 * Launch all the capsules in system at boot time.
984 * Called by efi init code
985 *
986 * Return: status codde
987 */
988efi_status_t efi_launch_capsules(void)
989{
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900990 struct efi_capsule_header *capsule = NULL;
991 u16 **files;
992 unsigned int nfiles, index, i;
993 u16 variable_name16[12];
994 efi_status_t ret;
995
Ilias Apalodimasa38d0cb2021-06-29 07:55:51 +0300996 if (!check_run_capsules())
AKASHI Takahiro45b819542020-11-17 09:27:56 +0900997 return EFI_SUCCESS;
998
999 index = get_last_capsule();
1000
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001001 /*
1002 * Find capsules on disk.
1003 * All the capsules are collected at the beginning because
1004 * capsule files will be removed instantly.
1005 */
1006 nfiles = 0;
1007 files = NULL;
1008 ret = efi_capsule_scan_dir(&files, &nfiles);
1009 if (ret != EFI_SUCCESS)
1010 return ret;
1011 if (!nfiles)
1012 return EFI_SUCCESS;
1013
1014 /* Launch capsules */
1015 for (i = 0, ++index; i < nfiles; i++, index++) {
Heinrich Schuchardte3087a12021-07-10 11:03:27 +02001016 log_debug("Applying %ls\n", files[i]);
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001017 if (index > 0xffff)
1018 index = 0;
1019 ret = efi_capsule_read_file(files[i], &capsule);
1020 if (ret == EFI_SUCCESS) {
1021 ret = EFI_CALL(efi_update_capsule(&capsule, 1, 0));
1022 if (ret != EFI_SUCCESS)
Heinrich Schuchardte3087a12021-07-10 11:03:27 +02001023 log_err("Applying capsule %ls failed\n",
AKASHI Takahiro0d963782020-11-30 18:12:11 +09001024 files[i]);
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001025
1026 free(capsule);
1027 } else {
Heinrich Schuchardte3087a12021-07-10 11:03:27 +02001028 log_err("Reading capsule %ls failed\n", files[i]);
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001029 }
1030 /* create CapsuleXXXX */
1031 set_capsule_result(index, capsule, ret);
1032
1033 /* delete a capsule either in case of success or failure */
1034 ret = efi_capsule_delete_file(files[i]);
1035 if (ret != EFI_SUCCESS)
Heinrich Schuchardte3087a12021-07-10 11:03:27 +02001036 log_err("Deleting capsule %ls failed\n",
AKASHI Takahiro0d963782020-11-30 18:12:11 +09001037 files[i]);
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001038 }
1039 efi_capsule_scan_done();
1040
1041 for (i = 0; i < nfiles; i++)
1042 free(files[i]);
1043 free(files);
1044
1045 /* CapsuleLast */
Ilias Apalodimas21575292020-12-31 12:26:46 +02001046 efi_create_indexed_name(variable_name16, sizeof(variable_name16),
1047 "Capsule", index - 1);
AKASHI Takahiro45b819542020-11-17 09:27:56 +09001048 efi_set_variable_int(L"CapsuleLast", &efi_guid_capsule_report,
1049 EFI_VARIABLE_READ_ONLY |
1050 EFI_VARIABLE_NON_VOLATILE |
1051 EFI_VARIABLE_BOOTSERVICE_ACCESS |
1052 EFI_VARIABLE_RUNTIME_ACCESS,
1053 22, variable_name16, false);
1054
1055 return ret;
1056}
1057#endif /* CONFIG_EFI_CAPSULE_ON_DISK */