VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.c

Last change on this file was 99404, checked in by vboxsync, 2 years ago

Devices/EFI/FirmwareNew: Update to edk2-stable202302 and make it build, bugref:4643

  • Property svn:eol-style set to native
File size: 15.4 KB
Line 
1/** @file -- VariablePolicyHelperLib.c
2This library contains helper functions for marshalling and registering
3new policies with the VariablePolicy infrastructure.
4
5This library is currently written against VariablePolicy revision 0x00010000.
6
7Copyright (c) Microsoft Corporation.
8SPDX-License-Identifier: BSD-2-Clause-Patent
9
10**/
11
12#include <Uefi.h>
13
14#include <Library/BaseLib.h>
15#include <Library/DebugLib.h>
16#include <Library/BaseMemoryLib.h>
17#include <Library/MemoryAllocationLib.h>
18
19#include <Protocol/VariablePolicy.h>
20
21/**
22 This internal helper function populates the header structure,
23 all common fields, and takes care of fix-ups.
24
25 NOTE: Only use this internally. Assumes correctly-sized buffers.
26
27 @param[out] EntPtr Pointer to the buffer to be populated.
28 @param[in] Namespace Pointer to an EFI_GUID for the target variable namespace that this policy will protect.
29 @param[in] MinSize MinSize for the VariablePolicy.
30 @param[in] MaxSize MaxSize for the VariablePolicy.
31 @param[in] AttributesMustHave AttributesMustHave for the VariablePolicy.
32 @param[in] AttributesCantHave AttributesCantHave for the VariablePolicy.
33 @param[in] LockPolicyType LockPolicyType for the VariablePolicy.
34
35**/
36STATIC
37VOID
38PopulateCommonData (
39 OUT VARIABLE_POLICY_ENTRY *EntPtr,
40 IN CONST EFI_GUID *Namespace,
41 IN UINT32 MinSize,
42 IN UINT32 MaxSize,
43 IN UINT32 AttributesMustHave,
44 IN UINT32 AttributesCantHave,
45 IN UINT8 LockPolicyType
46 )
47{
48 EntPtr->Version = VARIABLE_POLICY_ENTRY_REVISION;
49 CopyGuid (&EntPtr->Namespace, Namespace);
50 EntPtr->MinSize = MinSize;
51 EntPtr->MaxSize = MaxSize;
52 EntPtr->AttributesMustHave = AttributesMustHave;
53 EntPtr->AttributesCantHave = AttributesCantHave;
54 EntPtr->LockPolicyType = LockPolicyType;
55
56 // NOTE: As a heler, fix up MaxSize for compatibility with the old model.
57 if (EntPtr->MaxSize == 0) {
58 EntPtr->MaxSize = VARIABLE_POLICY_NO_MAX_SIZE;
59 }
60
61 return;
62}
63
64/**
65 This helper function will allocate and populate a new VariablePolicy
66 structure for a policy that does not contain any sub-structures (such as
67 VARIABLE_LOCK_ON_VAR_STATE_POLICY).
68
69 NOTE: Caller will need to free structure once finished.
70
71 @param[in] Namespace Pointer to an EFI_GUID for the target variable namespace that this policy will protect.
72 @param[in] Name [Optional] If provided, a pointer to the CHAR16 array for the target variable name.
73 Otherwise, will create a policy that targets an entire namespace.
74 @param[in] MinSize MinSize for the VariablePolicy.
75 @param[in] MaxSize MaxSize for the VariablePolicy.
76 @param[in] AttributesMustHave AttributesMustHave for the VariablePolicy.
77 @param[in] AttributesCantHave AttributesCantHave for the VariablePolicy.
78 @param[in] LockPolicyType LockPolicyType for the VariablePolicy.
79 @param[out] NewEntry If successful, will be set to a pointer to the allocated buffer containing the
80 new policy.
81
82 @retval EFI_SUCCESS Operation completed successfully and structure is populated.
83 @retval EFI_INVALID_PARAMETER Namespace is NULL.
84 @retval EFI_INVALID_PARAMETER LockPolicyType is invalid for a basic structure.
85 @retval EFI_BUFFER_TOO_SMALL Finished structure would not fit in UINT16 size.
86 @retval EFI_OUT_OF_RESOURCES Could not allocate sufficient space for structure.
87
88**/
89EFI_STATUS
90EFIAPI
91CreateBasicVariablePolicy (
92 IN CONST EFI_GUID *Namespace,
93 IN CONST CHAR16 *Name OPTIONAL,
94 IN UINT32 MinSize,
95 IN UINT32 MaxSize,
96 IN UINT32 AttributesMustHave,
97 IN UINT32 AttributesCantHave,
98 IN UINT8 LockPolicyType,
99 OUT VARIABLE_POLICY_ENTRY **NewEntry
100 )
101{
102 UINTN TotalSize;
103 UINTN NameSize;
104 VARIABLE_POLICY_ENTRY *EntPtr;
105 CHAR16 *CopyName;
106
107 // Check some initial invalid parameters for this function.
108 if ((Namespace == NULL) || (NewEntry == NULL)) {
109 return EFI_INVALID_PARAMETER;
110 }
111
112 if ((LockPolicyType != VARIABLE_POLICY_TYPE_NO_LOCK) &&
113 (LockPolicyType != VARIABLE_POLICY_TYPE_LOCK_NOW) &&
114 (LockPolicyType != VARIABLE_POLICY_TYPE_LOCK_ON_CREATE))
115 {
116 return EFI_INVALID_PARAMETER;
117 }
118
119 //
120 // Set NameSize to suppress incorrect compiler/analyzer warnings
121 //
122 NameSize = 0;
123
124 // Now we've gotta determine the total size of the buffer required for
125 // the VariablePolicy structure.
126 TotalSize = sizeof (VARIABLE_POLICY_ENTRY);
127 if (Name != NULL) {
128 NameSize = StrnSizeS (Name, MAX_UINT16);
129 TotalSize += NameSize;
130 }
131
132 // Make sure the size fits within a VARIABLE_POLICY_ENTRY.Size.
133 ASSERT (TotalSize <= MAX_UINT16);
134 if (TotalSize > MAX_UINT16) {
135 return EFI_BUFFER_TOO_SMALL;
136 }
137
138 // Allocate a buffer to hold all the data. We're on the home stretch.
139 *NewEntry = AllocatePool (TotalSize);
140 if (*NewEntry == NULL) {
141 return EFI_OUT_OF_RESOURCES;
142 }
143
144 // If we're still here, we're basically done.
145 // Copy the data and GET... OUT....
146 EntPtr = *NewEntry;
147 PopulateCommonData (
148 EntPtr,
149 Namespace,
150 MinSize,
151 MaxSize,
152 AttributesMustHave,
153 AttributesCantHave,
154 LockPolicyType
155 );
156 EntPtr->Size = (UINT16)TotalSize; // This is safe because we've already checked.
157 EntPtr->OffsetToName = sizeof (VARIABLE_POLICY_ENTRY);
158 if (Name != NULL) {
159 CopyName = (CHAR16 *)((UINT8 *)EntPtr + EntPtr->OffsetToName);
160 CopyMem (CopyName, Name, NameSize);
161 }
162
163 return EFI_SUCCESS;
164}
165
166/**
167 This helper function will allocate and populate a new VariablePolicy
168 structure for a policy with a lock type of VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE.
169
170 NOTE: Caller will need to free structure once finished.
171
172 @param[in] Namespace Pointer to an EFI_GUID for the target variable namespace that this policy will protect.
173 @param[in] Name [Optional] If provided, a pointer to the CHAR16 array for the target variable name.
174 Otherwise, will create a policy that targets an entire namespace.
175 @param[in] MinSize MinSize for the VariablePolicy.
176 @param[in] MaxSize MaxSize for the VariablePolicy.
177 @param[in] AttributesMustHave AttributesMustHave for the VariablePolicy.
178 @param[in] AttributesCantHave AttributesCantHave for the VariablePolicy.
179 @param[in] VarStateNamespace Pointer to the EFI_GUID for the VARIABLE_LOCK_ON_VAR_STATE_POLICY.Namespace.
180 @param[in] VarStateValue Value for the VARIABLE_LOCK_ON_VAR_STATE_POLICY.Value.
181 @param[in] VarStateName Pointer to the CHAR16 array for the VARIABLE_LOCK_ON_VAR_STATE_POLICY.Name.
182 @param[out] NewEntry If successful, will be set to a pointer to the allocated buffer containing the
183 new policy.
184
185 @retval EFI_SUCCESS Operation completed successfully and structure is populated.
186 @retval EFI_INVALID_PARAMETER Namespace, VarStateNamespace, VarStateName is NULL.
187 @retval EFI_BUFFER_TOO_SMALL Finished structure would not fit in UINT16 size.
188 @retval EFI_OUT_OF_RESOURCES Could not allocate sufficient space for structure.
189
190**/
191EFI_STATUS
192EFIAPI
193CreateVarStateVariablePolicy (
194 IN CONST EFI_GUID *Namespace,
195 IN CONST CHAR16 *Name OPTIONAL,
196 IN UINT32 MinSize,
197 IN UINT32 MaxSize,
198 IN UINT32 AttributesMustHave,
199 IN UINT32 AttributesCantHave,
200 IN CONST EFI_GUID *VarStateNamespace,
201 IN UINT8 VarStateValue,
202 IN CONST CHAR16 *VarStateName,
203 OUT VARIABLE_POLICY_ENTRY **NewEntry
204 )
205{
206 UINTN TotalSize;
207 UINTN NameSize;
208 UINTN VarStateNameSize;
209 VARIABLE_POLICY_ENTRY *EntPtr;
210 CHAR16 *CopyName;
211 VARIABLE_LOCK_ON_VAR_STATE_POLICY *CopyPolicy;
212
213 // Check some initial invalid parameters for this function.
214 if ((Namespace == NULL) || (VarStateNamespace == NULL) ||
215 (VarStateName == NULL) || (NewEntry == NULL))
216 {
217 return EFI_INVALID_PARAMETER;
218 }
219
220 // Now we've gotta determine the total size of the buffer required for
221 // the VariablePolicy structure.
222 VarStateNameSize = StrnSizeS (VarStateName, MAX_UINT16);
223 TotalSize = sizeof (VARIABLE_POLICY_ENTRY) +
224 sizeof (VARIABLE_LOCK_ON_VAR_STATE_POLICY) +
225 VarStateNameSize;
226 if (Name != NULL) {
227 NameSize = StrnSizeS (Name, MAX_UINT16);
228 TotalSize += NameSize;
229 }
230
231 // Make sure the size fits within a VARIABLE_POLICY_ENTRY.Size.
232 ASSERT (TotalSize <= MAX_UINT16);
233 if (TotalSize > MAX_UINT16) {
234 return EFI_BUFFER_TOO_SMALL;
235 }
236
237 // Allocate a buffer to hold all the data. We're on the home stretch.
238 *NewEntry = AllocatePool (TotalSize);
239 if (*NewEntry == NULL) {
240 return EFI_OUT_OF_RESOURCES;
241 }
242
243 // If we're still here, we're basically done.
244 // Copy the data and GET... OUT....
245 EntPtr = *NewEntry;
246 PopulateCommonData (
247 EntPtr,
248 Namespace,
249 MinSize,
250 MaxSize,
251 AttributesMustHave,
252 AttributesCantHave,
253 VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE
254 );
255 EntPtr->Size = (UINT16)TotalSize; // This is safe because we've already checked.
256 EntPtr->OffsetToName = sizeof (VARIABLE_POLICY_ENTRY) +
257 sizeof (VARIABLE_LOCK_ON_VAR_STATE_POLICY) +
258 (UINT16)VarStateNameSize;
259
260 CopyPolicy = (VARIABLE_LOCK_ON_VAR_STATE_POLICY *)((UINT8 *)EntPtr + sizeof (VARIABLE_POLICY_ENTRY));
261 CopyName = (CHAR16 *)((UINT8 *)CopyPolicy + sizeof (VARIABLE_LOCK_ON_VAR_STATE_POLICY));
262 CopyGuid (&CopyPolicy->Namespace, VarStateNamespace);
263 CopyPolicy->Value = VarStateValue;
264 CopyMem (CopyName, VarStateName, VarStateNameSize);
265
266 if (Name != NULL) {
267 CopyName = (CHAR16 *)((UINT8 *)EntPtr + EntPtr->OffsetToName);
268 CopyMem (CopyName, Name, NameSize);
269 }
270
271 return EFI_SUCCESS;
272}
273
274/**
275 This helper function does everything that CreateBasicVariablePolicy() does, but also
276 uses the passed in protocol to register the policy with the infrastructure.
277 Does not return a buffer, does not require the caller to free anything.
278
279 @param[in] VariablePolicy Pointer to a valid instance of the VariablePolicy protocol.
280 @param[in] Namespace Pointer to an EFI_GUID for the target variable namespace that this policy will protect.
281 @param[in] Name [Optional] If provided, a pointer to the CHAR16 array for the target variable name.
282 Otherwise, will create a policy that targets an entire namespace.
283 @param[in] MinSize MinSize for the VariablePolicy.
284 @param[in] MaxSize MaxSize for the VariablePolicy.
285 @param[in] AttributesMustHave AttributesMustHave for the VariablePolicy.
286 @param[in] AttributesCantHave AttributesCantHave for the VariablePolicy.
287 @param[in] LockPolicyType LockPolicyType for the VariablePolicy.
288
289 @retval EFI_INVALID_PARAMETER VariablePolicy pointer is NULL.
290 @retval EFI_STATUS Status returned by CreateBasicVariablePolicy() or RegisterVariablePolicy().
291
292**/
293EFI_STATUS
294EFIAPI
295RegisterBasicVariablePolicy (
296 IN EDKII_VARIABLE_POLICY_PROTOCOL *VariablePolicy,
297 IN CONST EFI_GUID *Namespace,
298 IN CONST CHAR16 *Name OPTIONAL,
299 IN UINT32 MinSize,
300 IN UINT32 MaxSize,
301 IN UINT32 AttributesMustHave,
302 IN UINT32 AttributesCantHave,
303 IN UINT8 LockPolicyType
304 )
305{
306 VARIABLE_POLICY_ENTRY *NewEntry;
307 EFI_STATUS Status;
308
309 // Check the simple things.
310 if (VariablePolicy == NULL) {
311 return EFI_INVALID_PARAMETER;
312 }
313
314 // Create the new entry and make sure that everything worked.
315 NewEntry = NULL;
316 Status = CreateBasicVariablePolicy (
317 Namespace,
318 Name,
319 MinSize,
320 MaxSize,
321 AttributesMustHave,
322 AttributesCantHave,
323 LockPolicyType,
324 &NewEntry
325 );
326
327 // If that was successful, attempt to register the new policy.
328 if (!EFI_ERROR (Status)) {
329 Status = VariablePolicy->RegisterVariablePolicy (NewEntry);
330 }
331
332 // If we allocated the buffer, free the buffer.
333 if (NewEntry != NULL) {
334 FreePool (NewEntry);
335 }
336
337 return Status;
338}
339
340/**
341 This helper function does everything that CreateBasicVariablePolicy() does, but also
342 uses the passed in protocol to register the policy with the infrastructure.
343 Does not return a buffer, does not require the caller to free anything.
344
345 @param[in] VariablePolicy Pointer to a valid instance of the VariablePolicy protocol.
346 @param[in] Namespace Pointer to an EFI_GUID for the target variable namespace that this policy will protect.
347 @param[in] Name [Optional] If provided, a pointer to the CHAR16 array for the target variable name.
348 Otherwise, will create a policy that targets an entire namespace.
349 @param[in] MinSize MinSize for the VariablePolicy.
350 @param[in] MaxSize MaxSize for the VariablePolicy.
351 @param[in] AttributesMustHave AttributesMustHave for the VariablePolicy.
352 @param[in] AttributesCantHave AttributesCantHave for the VariablePolicy.
353 @param[in] VarStateNamespace Pointer to the EFI_GUID for the VARIABLE_LOCK_ON_VAR_STATE_POLICY.Namespace.
354 @param[in] VarStateName Pointer to the CHAR16 array for the VARIABLE_LOCK_ON_VAR_STATE_POLICY.Name.
355 @param[in] VarStateValue Value for the VARIABLE_LOCK_ON_VAR_STATE_POLICY.Value.
356
357 @retval EFI_INVALID_PARAMETER VariablePolicy pointer is NULL.
358 @retval EFI_STATUS Status returned by CreateBasicVariablePolicy() or RegisterVariablePolicy().
359
360**/
361EFI_STATUS
362EFIAPI
363RegisterVarStateVariablePolicy (
364 IN EDKII_VARIABLE_POLICY_PROTOCOL *VariablePolicy,
365 IN CONST EFI_GUID *Namespace,
366 IN CONST CHAR16 *Name OPTIONAL,
367 IN UINT32 MinSize,
368 IN UINT32 MaxSize,
369 IN UINT32 AttributesMustHave,
370 IN UINT32 AttributesCantHave,
371 IN CONST EFI_GUID *VarStateNamespace,
372 IN CONST CHAR16 *VarStateName,
373 IN UINT8 VarStateValue
374 )
375{
376 VARIABLE_POLICY_ENTRY *NewEntry;
377 EFI_STATUS Status;
378
379 // Check the simple things.
380 if (VariablePolicy == NULL) {
381 return EFI_INVALID_PARAMETER;
382 }
383
384 // Create the new entry and make sure that everything worked.
385 NewEntry = NULL;
386 Status = CreateVarStateVariablePolicy (
387 Namespace,
388 Name,
389 MinSize,
390 MaxSize,
391 AttributesMustHave,
392 AttributesCantHave,
393 VarStateNamespace,
394 VarStateValue,
395 VarStateName,
396 &NewEntry
397 );
398
399 // If that was successful, attempt to register the new policy.
400 if (!EFI_ERROR (Status)) {
401 Status = VariablePolicy->RegisterVariablePolicy (NewEntry);
402 }
403
404 // If we allocated the buffer, free the buffer.
405 if (NewEntry != NULL) {
406 FreePool (NewEntry);
407 }
408
409 return Status;
410}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette