/src/fwupd/libfwupdplugin/fu-efi-common.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 2021 Richard Hughes <richard@hughsie.com> |
3 | | * |
4 | | * SPDX-License-Identifier: LGPL-2.1-or-later |
5 | | */ |
6 | | |
7 | | #include "config.h" |
8 | | |
9 | | #include "fu-common.h" |
10 | | #include "fu-efi-common.h" |
11 | | #include "fu-efi-section.h" |
12 | | #include "fu-input-stream.h" |
13 | | #include "fu-partial-input-stream.h" |
14 | | |
15 | | /** |
16 | | * fu_efi_guid_to_name: |
17 | | * @guid: A lowercase GUID string, e.g. `8c8ce578-8a3d-4f1c-9935-896185c32dd3` |
18 | | * |
19 | | * Converts a GUID to the known nice name. |
20 | | * |
21 | | * Returns: identifier string, or %NULL if unknown |
22 | | * |
23 | | * Since: 1.6.2 |
24 | | **/ |
25 | | const gchar * |
26 | | fu_efi_guid_to_name(const gchar *guid) |
27 | 11.6k | { |
28 | 11.6k | if (g_strcmp0(guid, FU_EFI_VOLUME_GUID_FFS1) == 0) |
29 | 0 | return "Volume:Ffs1"; |
30 | 11.6k | if (g_strcmp0(guid, FU_EFI_VOLUME_GUID_FFS2) == 0) |
31 | 2.17k | return "Volume:Ffs2"; |
32 | 9.52k | if (g_strcmp0(guid, FU_EFI_VOLUME_GUID_FFS3) == 0) |
33 | 0 | return "Volume:Ffs3"; |
34 | 9.52k | if (g_strcmp0(guid, FU_EFI_VOLUME_GUID_NVRAM_EVSA) == 0) |
35 | 18 | return "Volume:NvramEvsa"; |
36 | 9.50k | if (g_strcmp0(guid, FU_EFI_VOLUME_GUID_NVRAM_NVAR) == 0) |
37 | 0 | return "Volume:NvramNvar"; |
38 | 9.50k | if (g_strcmp0(guid, FU_EFI_VOLUME_GUID_NVRAM_EVSA2) == 0) |
39 | 0 | return "Volume:NvramEvsa2"; |
40 | 9.50k | if (g_strcmp0(guid, FU_EFI_VOLUME_GUID_APPLE_BOOT) == 0) |
41 | 0 | return "Volume:AppleBoot"; |
42 | 9.50k | if (g_strcmp0(guid, FU_EFI_VOLUME_GUID_PFH1) == 0) |
43 | 0 | return "Volume:Pfh1"; |
44 | 9.50k | if (g_strcmp0(guid, FU_EFI_VOLUME_GUID_PFH2) == 0) |
45 | 0 | return "Volume:Pfh2"; |
46 | 9.50k | if (g_strcmp0(guid, FU_EFI_VOLUME_GUID_HP_FS) == 0) |
47 | 0 | return "Volume:HpFs"; |
48 | 9.50k | if (g_strcmp0(guid, FU_EFI_FILE_GUID_FV_IMAGE) == 0) |
49 | 0 | return "File:FvImage"; |
50 | 9.50k | if (g_strcmp0(guid, FU_EFI_FILE_GUID_MICROCODE) == 0) |
51 | 0 | return "File:Microcode"; |
52 | 9.50k | if (g_strcmp0(guid, FU_EFI_FILE_GUID_BIOS_GUARD) == 0) |
53 | 0 | return "File:BiosGuard"; |
54 | 9.50k | if (g_strcmp0(guid, FU_EFI_SECTION_GUID_LZMA_COMPRESS) == 0) |
55 | 0 | return "Section:LzmaCompress"; |
56 | 9.50k | if (g_strcmp0(guid, FU_EFI_SECTION_GUID_TIANO_COMPRESS) == 0) |
57 | 0 | return "Section:TianoCompress"; |
58 | 9.50k | if (g_strcmp0(guid, FU_EFI_SECTION_GUID_SMBIOS_TABLE) == 0) |
59 | 0 | return "Section:SmbiosTable"; |
60 | 9.50k | if (g_strcmp0(guid, FU_EFI_SECTION_GUID_ESRT_TABLE) == 0) |
61 | 0 | return "Section:EsrtTable"; |
62 | 9.50k | if (g_strcmp0(guid, FU_EFI_SECTION_GUID_ACPI1_TABLE) == 0) |
63 | 0 | return "Section:Acpi1Table"; |
64 | 9.50k | if (g_strcmp0(guid, FU_EFI_SECTION_GUID_ACPI2_TABLE) == 0) |
65 | 0 | return "Section:Acpi2Table"; |
66 | 9.50k | return NULL; |
67 | 9.50k | } |
68 | | /** |
69 | | * fu_efi_parse_sections: |
70 | | * @firmware: #FuFirmware |
71 | | * @stream: a #GInputStream |
72 | | * @flags: #FuFirmwareParseFlags |
73 | | * @error: (nullable): optional return location for an error |
74 | | * |
75 | | * Parses a UEFI section. |
76 | | * |
77 | | * Returns: %TRUE for success |
78 | | * |
79 | | * Since: 2.0.0 |
80 | | **/ |
81 | | gboolean |
82 | | fu_efi_parse_sections(FuFirmware *firmware, |
83 | | GInputStream *stream, |
84 | | gsize offset, |
85 | | FuFirmwareParseFlags flags, |
86 | | GError **error) |
87 | 20.5k | { |
88 | 20.5k | gsize streamsz = 0; |
89 | | |
90 | 20.5k | if (!fu_input_stream_size(stream, &streamsz, error)) |
91 | 0 | return FALSE; |
92 | 61.7k | while (offset < streamsz) { |
93 | 45.6k | g_autoptr(FuFirmware) img = fu_efi_section_new(); |
94 | 45.6k | g_autoptr(GInputStream) partial_stream = NULL; |
95 | | |
96 | | /* parse maximum payload */ |
97 | 45.6k | partial_stream = |
98 | 45.6k | fu_partial_input_stream_new(stream, offset, streamsz - offset, error); |
99 | 45.6k | if (partial_stream == NULL) { |
100 | 0 | g_prefix_error(error, "failed to cut payload: "); |
101 | 0 | return FALSE; |
102 | 0 | } |
103 | 45.6k | if (!fu_firmware_parse_stream(img, |
104 | 45.6k | partial_stream, |
105 | 45.6k | 0x0, |
106 | 45.6k | flags | FU_FIRMWARE_PARSE_FLAG_NO_SEARCH, |
107 | 45.6k | error)) { |
108 | 4.42k | g_prefix_error(error, |
109 | 4.42k | "failed to parse section of size 0x%x: ", |
110 | 4.42k | (guint)streamsz); |
111 | 4.42k | return FALSE; |
112 | 4.42k | } |
113 | | |
114 | | /* invalid */ |
115 | 41.2k | if (fu_firmware_get_size(img) == 0) { |
116 | 0 | g_set_error_literal(error, |
117 | 0 | FWUPD_ERROR, |
118 | 0 | FWUPD_ERROR_INVALID_DATA, |
119 | 0 | "section had zero size"); |
120 | 0 | return FALSE; |
121 | 0 | } |
122 | | |
123 | 41.2k | fu_firmware_set_offset(img, offset); |
124 | 41.2k | if (!fu_firmware_add_image_full(firmware, img, error)) |
125 | 58 | return FALSE; |
126 | | |
127 | | /* next! */ |
128 | 41.1k | offset += fu_common_align_up(fu_firmware_get_size(img), FU_FIRMWARE_ALIGNMENT_4); |
129 | 41.1k | } |
130 | | |
131 | | /* success */ |
132 | 16.0k | return TRUE; |
133 | 20.5k | } |