OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
LegacyNvramSupport.c
Go to the documentation of this file.
1
14#include <Uefi.h>
15
16#include <Guid/OcVariable.h>
17
18#include <Library/BaseLib.h>
19#include <Library/DebugLib.h>
20#include <Library/MemoryAllocationLib.h>
23#include <Library/UefiLib.h>
24#include <Library/UefiRuntimeServicesTableLib.h>
25
26EFI_STATUS
28 IN CONST CHAR8 *AsciiVariableGuid,
29 OUT GUID *VariableGuid,
30 IN OC_NVRAM_LEGACY_MAP *Schema OPTIONAL,
31 OUT OC_NVRAM_LEGACY_ENTRY **SchemaEntry OPTIONAL
32 )
33{
34 EFI_STATUS Status;
35 UINT32 GuidIndex;
36
37 Status = AsciiStrToGuid (AsciiVariableGuid, VariableGuid);
38 if (EFI_ERROR (Status)) {
39 DEBUG ((DEBUG_WARN, "OCVAR: Failed to convert NVRAM GUID %a - %r\n", AsciiVariableGuid, Status));
40 }
41
42 if (!EFI_ERROR (Status) && (Schema != NULL)) {
43 for (GuidIndex = 0; GuidIndex < Schema->Count; ++GuidIndex) {
44 if (AsciiStrCmp (AsciiVariableGuid, OC_BLOB_GET (Schema->Keys[GuidIndex])) == 0) {
45 *SchemaEntry = Schema->Values[GuidIndex];
46 return Status;
47 }
48 }
49
50 DEBUG ((DEBUG_INFO, "OCVAR: Ignoring NVRAM GUID %a\n", AsciiVariableGuid));
51 Status = EFI_SECURITY_VIOLATION;
52 }
53
54 return Status;
55}
56
57BOOLEAN
59 IN OC_NVRAM_LEGACY_ENTRY *SchemaEntry,
60 IN EFI_GUID *VariableGuid OPTIONAL,
61 IN CONST VOID *VariableName,
62 IN OC_STRING_FORMAT StringFormat
63 )
64{
65 BOOLEAN IsAllowed;
66 UINT32 VariableIndex;
67
68 if (SchemaEntry == NULL) {
69 return TRUE;
70 }
71
72 IsAllowed = FALSE;
73
74 //
75 // TODO: Consider optimising lookup if it causes problems...
76 //
77 for (VariableIndex = 0; VariableIndex < SchemaEntry->Count; ++VariableIndex) {
78 if ((VariableIndex == 0) && (AsciiStrCmp ("*", OC_BLOB_GET (SchemaEntry->Values[VariableIndex])) == 0)) {
79 IsAllowed = TRUE;
80 break;
81 }
82
83 if ( (StringFormat == OcStringFormatAscii)
84 && (AsciiStrCmp ((CONST CHAR8 *)VariableName, OC_BLOB_GET (SchemaEntry->Values[VariableIndex])) == 0))
85 {
86 IsAllowed = TRUE;
87 break;
88 }
89
90 if ( (StringFormat == OcStringFormatUnicode)
91 && (MixedStrCmp ((CONST CHAR16 *)VariableName, OC_BLOB_GET (SchemaEntry->Values[VariableIndex])) == 0))
92 {
93 IsAllowed = TRUE;
94 break;
95 }
96 }
97
98 if (!IsAllowed) {
99 DEBUG ((DEBUG_INFO, "OCVAR: NVRAM %g:%s is not permitted\n", VariableGuid, VariableName));
100 }
101
102 return IsAllowed;
103}
104
105VOID
107 IN CONST CHAR8 *AsciiVariableName,
108 IN EFI_GUID *VariableGuid,
109 IN UINT32 Attributes,
110 IN UINT32 VariableSize,
111 IN VOID *VariableData,
112 IN OC_NVRAM_LEGACY_ENTRY *SchemaEntry OPTIONAL,
113 IN BOOLEAN Overwrite
114 )
115{
116 EFI_STATUS Status;
117 UINTN OriginalVariableSize;
118 CHAR16 *UnicodeVariableName;
119 VOID *OrgValue;
120 UINTN OrgSize;
121 UINT32 OrgAttributes;
122
123 if (!OcVariableIsAllowedBySchemaEntry (SchemaEntry, VariableGuid, AsciiVariableName, OcStringFormatAscii)) {
124 return;
125 }
126
127 UnicodeVariableName = AsciiStrCopyToUnicode (AsciiVariableName, 0);
128
129 if (UnicodeVariableName == NULL) {
130 DEBUG ((DEBUG_WARN, "OCVAR: Failed to convert NVRAM variable name %a\n", AsciiVariableName));
131 return;
132 }
133
134 OriginalVariableSize = 0;
135 Status = gRT->GetVariable (
136 UnicodeVariableName,
137 VariableGuid,
138 NULL,
139 &OriginalVariableSize,
140 NULL
141 );
142
143 if ((Status == EFI_BUFFER_TOO_SMALL) && Overwrite) {
144 Status = GetVariable3 (UnicodeVariableName, VariableGuid, &OrgValue, &OrgSize, &OrgAttributes);
145 if (!EFI_ERROR (Status)) {
146 //
147 // Do not allow overwriting BS-only variables. Ideally we also check for NV attribute,
148 // but it is not set by Duet.
149 //
150 if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS))
151 == (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS))
152 {
153 Status = gRT->SetVariable (UnicodeVariableName, VariableGuid, 0, 0, 0);
154
155 if (EFI_ERROR (Status)) {
156 DEBUG ((
157 DEBUG_INFO,
158 "OCVAR: Failed to delete overwritten variable %g:%a - %r\n",
159 VariableGuid,
160 AsciiVariableName,
161 Status
162 ));
163 Status = EFI_BUFFER_TOO_SMALL;
164 }
165 } else {
166 DEBUG ((
167 DEBUG_INFO,
168 "OCVAR: Overwritten variable %g:%a has invalid attrs - %X\n",
169 VariableGuid,
170 AsciiVariableName,
171 Attributes
172 ));
173 Status = EFI_BUFFER_TOO_SMALL;
174 }
175
176 FreePool (OrgValue);
177 } else {
178 DEBUG ((
179 DEBUG_INFO,
180 "OCVAR: Overwritten variable %g:%a has unknown attrs - %r\n",
181 VariableGuid,
182 AsciiVariableName,
183 Status
184 ));
185 Status = EFI_BUFFER_TOO_SMALL;
186 }
187 }
188
189 if (Status != EFI_BUFFER_TOO_SMALL) {
190 Status = gRT->SetVariable (
191 UnicodeVariableName,
192 VariableGuid,
193 Attributes,
194 VariableSize,
195 VariableData
196 );
197 DEBUG ((
198 EFI_ERROR (Status) && VariableSize > 0 ? DEBUG_WARN : DEBUG_INFO,
199 "OCVAR: Setting NVRAM %g:%a - %r\n",
200 VariableGuid,
201 AsciiVariableName,
202 Status
203 ));
204 } else {
205 DEBUG ((
206 DEBUG_INFO,
207 "OCVAR: Setting NVRAM %g:%a - ignored, exists\n",
208 VariableGuid,
209 AsciiVariableName,
210 Status
211 ));
212 }
213
214 FreePool (UnicodeVariableName);
215}
BOOLEAN OcVariableIsAllowedBySchemaEntry(IN OC_NVRAM_LEGACY_ENTRY *SchemaEntry, IN EFI_GUID *VariableGuid OPTIONAL, IN CONST VOID *VariableName, IN OC_STRING_FORMAT StringFormat)
VOID OcSetNvramVariable(IN CONST CHAR8 *AsciiVariableName, IN EFI_GUID *VariableGuid, IN UINT32 Attributes, IN UINT32 VariableSize, IN VOID *VariableData, IN OC_NVRAM_LEGACY_ENTRY *SchemaEntry OPTIONAL, IN BOOLEAN Overwrite)
EFI_STATUS OcProcessVariableGuid(IN CONST CHAR8 *AsciiVariableGuid, OUT GUID *VariableGuid, IN OC_NVRAM_LEGACY_MAP *Schema OPTIONAL, OUT OC_NVRAM_LEGACY_ENTRY **SchemaEntry OPTIONAL)
INTN MixedStrCmp(IN CONST CHAR16 *FirstString, IN CONST CHAR8 *SecondString)
@ OcStringFormatUnicode
Definition OcStringLib.h:51
@ OcStringFormatAscii
Definition OcStringLib.h:50
CHAR16 * AsciiStrCopyToUnicode(IN CONST CHAR8 *String, IN UINTN Length)
Definition OcAsciiLib.c:119
enum _OC_STRING_FORMAT OC_STRING_FORMAT
#define OC_BLOB_GET(Blob)
EFI_RUNTIME_SERVICES * gRT