Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | // SPDX-License-Identifier: GPL-2.0+ /* * EFI boot manager * * Copyright (c) 2018 AKASHI Takahiro, et.al. */ #define LOG_CATEGORY LOGC_EFI #include <charset.h> #include <log.h> #include <malloc.h> #include <efi_loader.h> #include <asm/unaligned.h> /** * efi_set_load_options() - set the load options of a loaded image * * @handle: the image handle * @load_options_size: size of load options * @load_options: pointer to load options * Return: status code */ efi_status_t efi_set_load_options(efi_handle_t handle, efi_uintn_t load_options_size, void *load_options) { struct efi_loaded_image *loaded_image_info; struct efi_handler *handler; efi_status_t ret; ret = efi_search_protocol(handle, &efi_guid_loaded_image, &handler); if (ret != EFI_SUCCESS) return EFI_INVALID_PARAMETER; loaded_image_info = handler->protocol_interface; loaded_image_info->load_options = load_options; loaded_image_info->load_options_size = load_options_size; return EFI_SUCCESS; } /** * efi_deserialize_load_option() - parse serialized data * * Parse serialized data describing a load option and transform it to the * efi_load_option structure. * * @lo: pointer to target * @data: serialized data * @size: size of the load option, on return size of the optional data * Return: status code */ efi_status_t efi_deserialize_load_option(struct efi_load_option *lo, u8 *data, efi_uintn_t *size) { efi_uintn_t len; len = sizeof(u32); if (*size < len + 2 * sizeof(u16)) return EFI_INVALID_PARAMETER; lo->attributes = get_unaligned_le32(data); data += len; *size -= len; len = sizeof(u16); lo->file_path_length = get_unaligned_le16(data); data += len; *size -= len; lo->label = (u16 *)data; len = u16_strnlen(lo->label, *size / sizeof(u16) - 1); if (lo->label[len]) return EFI_INVALID_PARAMETER; len = (len + 1) * sizeof(u16); if (*size < len) return EFI_INVALID_PARAMETER; data += len; *size -= len; len = lo->file_path_length; if (*size < len) return EFI_INVALID_PARAMETER; lo->file_path = (struct efi_device_path *)data; if (efi_dp_check_length(lo->file_path, len) < 0) return EFI_INVALID_PARAMETER; data += len; *size -= len; lo->optional_data = data; return EFI_SUCCESS; } /** * efi_serialize_load_option() - serialize load option * * Serialize efi_load_option structure into byte stream for BootXXXX. * * @data: buffer for serialized data * @lo: load option * Return: size of allocated buffer */ unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 **data) { unsigned long label_len; unsigned long size; u8 *p; label_len = u16_strsize(lo->label); /* total size */ size = sizeof(lo->attributes); size += sizeof(lo->file_path_length); size += label_len; size += lo->file_path_length; if (lo->optional_data) size += (utf8_utf16_strlen((const char *)lo->optional_data) + 1) * sizeof(u16); p = malloc(size); if (!p) return 0; /* copy data */ *data = p; memcpy(p, &lo->attributes, sizeof(lo->attributes)); p += sizeof(lo->attributes); memcpy(p, &lo->file_path_length, sizeof(lo->file_path_length)); p += sizeof(lo->file_path_length); memcpy(p, lo->label, label_len); p += label_len; memcpy(p, lo->file_path, lo->file_path_length); p += lo->file_path_length; if (lo->optional_data) { utf8_utf16_strcpy((u16 **)&p, (const char *)lo->optional_data); p += sizeof(u16); /* size of trailing \0 */ } return size; } |