]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/VariableAuthenticated/RuntimeDxe/VarCheck.c
SecurityPkg Variable: Implement variable quota management.
[mirror_edk2.git] / SecurityPkg / VariableAuthenticated / RuntimeDxe / VarCheck.c
CommitLineData
17409b7a
SZ
1/** @file\r
2 Implementation functions and structures for var check protocol.\r
3\r
4Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
5This program and the accompanying materials \r
6are licensed and made available under the terms and conditions of the BSD License \r
7which accompanies this distribution. The full text of the license may be found at \r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "Variable.h"\r
16#include <Library/DevicePathLib.h>\r
17\r
18extern LIST_ENTRY mLockedVariableList;\r
19extern BOOLEAN mEndOfDxe;\r
20extern BOOLEAN mEnableLocking;\r
21\r
22#define VAR_CHECK_HANDLER_TABLE_SIZE 0x8\r
23\r
24UINT32 mNumberOfHandler = 0;\r
25UINT32 mMaxNumberOfHandler = 0;\r
26VAR_CHECK_SET_VARIABLE_CHECK_HANDLER *mHandlerTable = NULL;\r
27\r
28typedef struct {\r
29 LIST_ENTRY Link;\r
30 EFI_GUID Guid;\r
31 VAR_CHECK_VARIABLE_PROPERTY VariableProperty;\r
32 //CHAR16 *Name;\r
33} VAR_CHECK_VARIABLE_ENTRY;\r
34\r
35LIST_ENTRY mVarCheckVariableList = INITIALIZE_LIST_HEAD_VARIABLE (mVarCheckVariableList);\r
36\r
37typedef\r
38EFI_STATUS\r
39(EFIAPI *INTERNAL_VAR_CHECK_FUNCTION) (\r
40 IN VAR_CHECK_VARIABLE_PROPERTY *Propery,\r
41 IN UINTN DataSize,\r
42 IN VOID *Data\r
43 );\r
44\r
45typedef struct {\r
46 CHAR16 *Name;\r
47 VAR_CHECK_VARIABLE_PROPERTY VariableProperty;\r
48 INTERNAL_VAR_CHECK_FUNCTION CheckFunction;\r
49} UEFI_DEFINED_VARIABLE_ENTRY;\r
50\r
17409b7a
SZ
51/**\r
52 Internal check for load option.\r
53\r
54 @param[in] VariablePropery Pointer to variable property.\r
55 @param[in] DataSize Data size.\r
56 @param[in] Data Pointer to data buffer.\r
57\r
58 @retval EFI_SUCCESS The SetVariable check result was success.\r
59 @retval EFI_INVALID_PARAMETER The data buffer is not a valid load option.\r
60\r
61**/\r
62EFI_STATUS\r
63EFIAPI\r
64InternalVarCheckLoadOption (\r
65 IN VAR_CHECK_VARIABLE_PROPERTY *VariablePropery,\r
66 IN UINTN DataSize,\r
67 IN VOID *Data\r
68 )\r
69{\r
952ba83c 70 UINT16 FilePathListLength;\r
17409b7a
SZ
71 CHAR16 *Description;\r
72 EFI_DEVICE_PATH_PROTOCOL *FilePathList;\r
73\r
952ba83c 74 FilePathListLength = *((UINT16 *) ((UINTN) Data + sizeof (UINT32)));\r
17409b7a
SZ
75\r
76 //\r
77 // Check Description\r
78 //\r
952ba83c 79 Description = (CHAR16 *) ((UINTN) Data + sizeof (UINT32) + sizeof (UINT16));\r
17409b7a
SZ
80 while (Description < (CHAR16 *) ((UINTN) Data + DataSize)) {\r
81 if (*Description == L'\0') {\r
82 break;\r
83 }\r
84 Description++;\r
85 }\r
86 if ((UINTN) Description >= ((UINTN) Data + DataSize)) {\r
87 return EFI_INVALID_PARAMETER;\r
88 }\r
89 Description++;\r
90\r
91 //\r
92 // Check FilePathList\r
93 //\r
94 FilePathList = (EFI_DEVICE_PATH_PROTOCOL *) Description;\r
952ba83c 95 if ((UINTN) FilePathList > (MAX_ADDRESS - FilePathListLength)) {\r
17409b7a
SZ
96 return EFI_INVALID_PARAMETER;\r
97 }\r
952ba83c 98 if (((UINTN) FilePathList + FilePathListLength) > ((UINTN) Data + DataSize)) {\r
17409b7a
SZ
99 return EFI_INVALID_PARAMETER;\r
100 }\r
952ba83c 101 if (FilePathListLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {\r
17409b7a
SZ
102 return EFI_INVALID_PARAMETER;\r
103 }\r
952ba83c 104 if (!IsDevicePathValid (FilePathList, FilePathListLength)) {\r
17409b7a
SZ
105 return EFI_INVALID_PARAMETER;\r
106 }\r
107\r
108 return EFI_SUCCESS;\r
109}\r
110\r
111/**\r
112 Internal check for key option.\r
113\r
114 @param[in] VariablePropery Pointer to variable property.\r
115 @param[in] DataSize Data size.\r
116 @param[in] Data Pointer to data buffer.\r
117\r
118 @retval EFI_SUCCESS The SetVariable check result was success.\r
119 @retval EFI_INVALID_PARAMETER The data buffer is not a valid key option.\r
120\r
121**/\r
122EFI_STATUS\r
123EFIAPI\r
124InternalVarCheckKeyOption (\r
125 IN VAR_CHECK_VARIABLE_PROPERTY *VariablePropery,\r
126 IN UINTN DataSize,\r
127 IN VOID *Data\r
128 )\r
129{\r
130 if (((DataSize - sizeof (EFI_KEY_OPTION)) % sizeof (EFI_INPUT_KEY)) != 0) {\r
131 return EFI_INVALID_PARAMETER;\r
132 }\r
133\r
134 return EFI_SUCCESS;\r
135}\r
136\r
137/**\r
138 Internal check for device path.\r
139\r
140 @param[in] VariablePropery Pointer to variable property.\r
141 @param[in] DataSize Data size.\r
142 @param[in] Data Pointer to data buffer.\r
143\r
144 @retval EFI_SUCCESS The SetVariable check result was success.\r
145 @retval EFI_INVALID_PARAMETER The data buffer is not a valid device path.\r
146\r
147**/\r
148EFI_STATUS\r
149EFIAPI\r
150InternalVarCheckDevicePath (\r
151 IN VAR_CHECK_VARIABLE_PROPERTY *VariablePropery,\r
152 IN UINTN DataSize,\r
153 IN VOID *Data\r
154 )\r
155{\r
156 if (!IsDevicePathValid ((EFI_DEVICE_PATH_PROTOCOL *) Data, DataSize)) {\r
157 return EFI_INVALID_PARAMETER;\r
158 }\r
159 return EFI_SUCCESS;\r
160}\r
161\r
162/**\r
163 Internal check for ASCII string.\r
164\r
165 @param[in] VariablePropery Pointer to variable property.\r
166 @param[in] DataSize Data size.\r
167 @param[in] Data Pointer to data buffer.\r
168\r
169 @retval EFI_SUCCESS The SetVariable check result was success.\r
170 @retval EFI_INVALID_PARAMETER The data buffer is not a Null-terminated ASCII string.\r
171\r
172**/\r
173EFI_STATUS\r
174EFIAPI\r
175InternalVarCheckAsciiString (\r
176 IN VAR_CHECK_VARIABLE_PROPERTY *VariablePropery,\r
177 IN UINTN DataSize,\r
178 IN VOID *Data\r
179 )\r
180{\r
181 CHAR8 *String;\r
182 UINTN Index;\r
183\r
184 String = (CHAR8 *) Data;\r
185 if (String[DataSize - 1] == '\0') {\r
186 return EFI_SUCCESS;\r
187 } else {\r
188 for (Index = 1; Index < DataSize && (String[DataSize - 1 - Index] != '\0'); Index++);\r
189 if (Index == DataSize) {\r
190 return EFI_INVALID_PARAMETER;\r
191 }\r
192 }\r
193 return EFI_SUCCESS;\r
194}\r
195\r
196/**\r
197 Internal check for size array.\r
198\r
199 @param[in] VariablePropery Pointer to variable property.\r
200 @param[in] DataSize Data size.\r
201 @param[in] Data Pointer to data buffer.\r
202\r
203 @retval EFI_SUCCESS The SetVariable check result was success.\r
204 @retval EFI_INVALID_PARAMETER The DataSize is not size array.\r
205\r
206**/\r
207EFI_STATUS\r
208EFIAPI\r
209InternalVarCheckSizeArray (\r
210 IN VAR_CHECK_VARIABLE_PROPERTY *VariablePropery,\r
211 IN UINTN DataSize,\r
212 IN VOID *Data\r
213 )\r
214{\r
215 if ((DataSize % VariablePropery->MinSize) != 0) {\r
216 return EFI_INVALID_PARAMETER;\r
217 }\r
218 return EFI_SUCCESS;\r
219}\r
220\r
221//\r
222// To prevent name collisions with possible future globally defined variables,\r
223// other internal firmware data variables that are not defined here must be\r
224// saved with a unique VendorGuid other than EFI_GLOBAL_VARIABLE or\r
225// any other GUID defined by the UEFI Specification. Implementations must\r
226// only permit the creation of variables with a UEFI Specification-defined\r
227// VendorGuid when these variables are documented in the UEFI Specification.\r
228//\r
229UEFI_DEFINED_VARIABLE_ENTRY mGlobalVariableList[] = {\r
230 {\r
231 EFI_LANG_CODES_VARIABLE_NAME,\r
232 {\r
233 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
234 0,\r
235 VARIABLE_ATTRIBUTE_BS_RT,\r
236 1,\r
237 MAX_UINTN\r
238 },\r
239 InternalVarCheckAsciiString\r
240 },\r
241 {\r
242 EFI_LANG_VARIABLE_NAME,\r
243 {\r
244 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
245 0,\r
246 VARIABLE_ATTRIBUTE_NV_BS_RT,\r
247 1,\r
248 MAX_UINTN\r
249 },\r
250 InternalVarCheckAsciiString\r
251 },\r
252 {\r
253 EFI_TIME_OUT_VARIABLE_NAME,\r
254 {\r
255 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
256 0,\r
257 VARIABLE_ATTRIBUTE_NV_BS_RT,\r
258 sizeof (UINT16),\r
259 sizeof (UINT16)\r
260 },\r
261 NULL\r
262 },\r
263 {\r
264 EFI_PLATFORM_LANG_CODES_VARIABLE_NAME,\r
265 {\r
266 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
267 0,\r
268 VARIABLE_ATTRIBUTE_BS_RT,\r
269 1,\r
270 MAX_UINTN\r
271 },\r
272 InternalVarCheckAsciiString\r
273 },\r
274 {\r
275 EFI_PLATFORM_LANG_VARIABLE_NAME,\r
276 {\r
277 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
278 0,\r
279 VARIABLE_ATTRIBUTE_NV_BS_RT,\r
280 1,\r
281 MAX_UINTN\r
282 },\r
283 InternalVarCheckAsciiString\r
284 },\r
285 {\r
286 EFI_CON_IN_VARIABLE_NAME,\r
287 {\r
288 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
289 0,\r
290 VARIABLE_ATTRIBUTE_NV_BS_RT,\r
291 sizeof (EFI_DEVICE_PATH_PROTOCOL),\r
292 MAX_UINTN\r
293 },\r
294 InternalVarCheckDevicePath\r
295 },\r
296 {\r
297 EFI_CON_OUT_VARIABLE_NAME,\r
298 {\r
299 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
300 0,\r
301 VARIABLE_ATTRIBUTE_NV_BS_RT,\r
302 sizeof (EFI_DEVICE_PATH_PROTOCOL),\r
303 MAX_UINTN\r
304 },\r
305 InternalVarCheckDevicePath\r
306 },\r
307 {\r
308 EFI_ERR_OUT_VARIABLE_NAME,\r
309 {\r
310 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
311 0,\r
312 VARIABLE_ATTRIBUTE_NV_BS_RT,\r
313 sizeof (EFI_DEVICE_PATH_PROTOCOL),\r
314 MAX_UINTN\r
315 },\r
316 InternalVarCheckDevicePath\r
317 },\r
318 {\r
319 EFI_CON_IN_DEV_VARIABLE_NAME,\r
320 {\r
321 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
322 0,\r
323 VARIABLE_ATTRIBUTE_BS_RT,\r
324 sizeof (EFI_DEVICE_PATH_PROTOCOL),\r
325 MAX_UINTN\r
326 },\r
327 InternalVarCheckDevicePath\r
328 },\r
329 {\r
330 EFI_CON_OUT_DEV_VARIABLE_NAME,\r
331 {\r
332 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
333 0,\r
334 VARIABLE_ATTRIBUTE_BS_RT,\r
335 sizeof (EFI_DEVICE_PATH_PROTOCOL),\r
336 MAX_UINTN\r
337 },\r
338 InternalVarCheckDevicePath\r
339 },\r
340 {\r
341 EFI_ERR_OUT_DEV_VARIABLE_NAME,\r
342 {\r
343 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
344 0,\r
345 VARIABLE_ATTRIBUTE_BS_RT,\r
346 sizeof (EFI_DEVICE_PATH_PROTOCOL),\r
347 MAX_UINTN\r
348 },\r
349 InternalVarCheckDevicePath\r
350 },\r
351 {\r
352 EFI_BOOT_ORDER_VARIABLE_NAME,\r
353 {\r
354 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
355 0,\r
356 VARIABLE_ATTRIBUTE_NV_BS_RT,\r
357 sizeof (UINT16),\r
358 MAX_UINTN\r
359 },\r
360 InternalVarCheckSizeArray\r
361 },\r
362 {\r
363 EFI_BOOT_NEXT_VARIABLE_NAME,\r
364 {\r
365 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
366 0,\r
367 VARIABLE_ATTRIBUTE_NV_BS_RT,\r
368 sizeof (UINT16),\r
369 sizeof (UINT16)\r
370 },\r
371 NULL\r
372 },\r
373 {\r
374 EFI_BOOT_CURRENT_VARIABLE_NAME,\r
375 {\r
376 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
377 0,\r
378 VARIABLE_ATTRIBUTE_BS_RT,\r
379 sizeof (UINT16),\r
380 sizeof (UINT16)\r
381 },\r
382 NULL\r
383 },\r
384 {\r
385 EFI_BOOT_OPTION_SUPPORT_VARIABLE_NAME,\r
386 {\r
387 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
388 0,\r
389 VARIABLE_ATTRIBUTE_BS_RT,\r
390 sizeof (UINT32),\r
391 sizeof (UINT32)\r
392 },\r
393 NULL\r
394 },\r
395 {\r
396 EFI_DRIVER_ORDER_VARIABLE_NAME,\r
397 {\r
398 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
399 0,\r
400 VARIABLE_ATTRIBUTE_NV_BS_RT,\r
401 sizeof (UINT16),\r
402 MAX_UINTN\r
403 },\r
404 InternalVarCheckSizeArray\r
405 },\r
406 {\r
407 EFI_HW_ERR_REC_SUPPORT_VARIABLE_NAME,\r
408 {\r
409 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
410 0,\r
411 VARIABLE_ATTRIBUTE_NV_BS_RT,\r
412 sizeof (UINT16),\r
413 sizeof (UINT16)\r
414 },\r
415 NULL\r
416 },\r
417 {\r
418 EFI_SETUP_MODE_NAME,\r
419 {\r
420 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
421 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,\r
422 VARIABLE_ATTRIBUTE_BS_RT,\r
423 sizeof (UINT8),\r
424 sizeof (UINT8)\r
425 },\r
426 NULL\r
427 },\r
428 {\r
429 EFI_KEY_EXCHANGE_KEY_NAME,\r
430 {\r
431 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
432 0,\r
433 VARIABLE_ATTRIBUTE_NV_BS_RT_AT,\r
434 1,\r
435 MAX_UINTN\r
436 },\r
437 NULL\r
438 },\r
439 {\r
440 EFI_PLATFORM_KEY_NAME,\r
441 {\r
442 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
443 0,\r
444 VARIABLE_ATTRIBUTE_NV_BS_RT_AT,\r
445 1,\r
446 MAX_UINTN\r
447 },\r
448 NULL\r
449 },\r
450 {\r
451 EFI_SIGNATURE_SUPPORT_NAME,\r
452 {\r
453 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
454 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,\r
455 VARIABLE_ATTRIBUTE_BS_RT,\r
456 sizeof (EFI_GUID),\r
457 MAX_UINTN\r
458 },\r
459 InternalVarCheckSizeArray\r
460 },\r
461 {\r
462 EFI_SECURE_BOOT_MODE_NAME,\r
463 {\r
464 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
465 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,\r
466 VARIABLE_ATTRIBUTE_BS_RT,\r
467 sizeof (UINT8),\r
468 sizeof (UINT8)\r
469 },\r
470 NULL\r
471 },\r
472 {\r
473 EFI_KEK_DEFAULT_VARIABLE_NAME,\r
474 {\r
475 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
476 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,\r
477 VARIABLE_ATTRIBUTE_BS_RT,\r
478 1,\r
479 MAX_UINTN\r
480 },\r
481 NULL\r
482 },\r
483 {\r
484 EFI_PK_DEFAULT_VARIABLE_NAME,\r
485 {\r
486 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
487 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,\r
488 VARIABLE_ATTRIBUTE_BS_RT,\r
489 1,\r
490 MAX_UINTN\r
491 },\r
492 NULL\r
493 },\r
494 {\r
495 EFI_DB_DEFAULT_VARIABLE_NAME,\r
496 {\r
497 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
498 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,\r
499 VARIABLE_ATTRIBUTE_BS_RT,\r
500 1,\r
501 MAX_UINTN\r
502 },\r
503 NULL\r
504 },\r
505 {\r
506 EFI_DBX_DEFAULT_VARIABLE_NAME,\r
507 {\r
508 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
509 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,\r
510 VARIABLE_ATTRIBUTE_BS_RT,\r
511 1,\r
512 MAX_UINTN\r
513 },\r
514 NULL\r
515 },\r
516 {\r
517 EFI_DBT_DEFAULT_VARIABLE_NAME,\r
518 {\r
519 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
520 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,\r
521 VARIABLE_ATTRIBUTE_BS_RT,\r
522 1,\r
523 MAX_UINTN\r
524 },\r
525 NULL\r
526 },\r
527 {\r
528 EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME,\r
529 {\r
530 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
531 0,\r
532 VARIABLE_ATTRIBUTE_BS_RT,\r
533 sizeof (UINT64),\r
534 sizeof (UINT64)\r
535 },\r
536 NULL\r
537 },\r
538 {\r
539 EFI_OS_INDICATIONS_VARIABLE_NAME,\r
540 {\r
541 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
542 0,\r
543 VARIABLE_ATTRIBUTE_NV_BS_RT,\r
544 sizeof (UINT64),\r
545 sizeof (UINT64)\r
546 },\r
547 NULL\r
548 },\r
549 {\r
550 EFI_VENDOR_KEYS_VARIABLE_NAME,\r
551 {\r
552 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
553 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,\r
554 VARIABLE_ATTRIBUTE_BS_RT,\r
555 sizeof (UINT8),\r
556 sizeof (UINT8)\r
557 },\r
558 NULL\r
559 },\r
560};\r
561UEFI_DEFINED_VARIABLE_ENTRY mGlobalVariableList2[] = {\r
562 {\r
563 L"Boot####",\r
564 {\r
565 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
566 0,\r
567 VARIABLE_ATTRIBUTE_NV_BS_RT,\r
952ba83c 568 sizeof (UINT32) + sizeof (UINT16),\r
17409b7a
SZ
569 MAX_UINTN\r
570 },\r
571 InternalVarCheckLoadOption\r
572 },\r
573 {\r
574 L"Driver####",\r
575 {\r
576 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
577 0,\r
578 VARIABLE_ATTRIBUTE_NV_BS_RT,\r
952ba83c 579 sizeof (UINT32) + sizeof (UINT16),\r
17409b7a
SZ
580 MAX_UINTN\r
581 },\r
582 InternalVarCheckLoadOption\r
583 },\r
584 {\r
585 L"Key####",\r
586 {\r
587 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
588 0,\r
589 VARIABLE_ATTRIBUTE_NV_BS_RT,\r
590 sizeof (EFI_KEY_OPTION),\r
591 sizeof (EFI_KEY_OPTION) + 3 * sizeof (EFI_INPUT_KEY)\r
592 },\r
593 InternalVarCheckKeyOption\r
594 },\r
595};\r
596\r
597//\r
598// EFI_IMAGE_SECURITY_DATABASE_GUID\r
599//\r
600UEFI_DEFINED_VARIABLE_ENTRY mImageSecurityVariableList[] = {\r
601 {\r
602 EFI_IMAGE_SECURITY_DATABASE,\r
603 {\r
604 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
605 0,\r
606 VARIABLE_ATTRIBUTE_NV_BS_RT_AT,\r
607 1,\r
608 MAX_UINTN\r
609 },\r
610 NULL\r
611 },\r
612 {\r
613 EFI_IMAGE_SECURITY_DATABASE1,\r
614 {\r
615 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
616 0,\r
617 VARIABLE_ATTRIBUTE_NV_BS_RT_AT,\r
618 1,\r
619 MAX_UINTN\r
620 },\r
621 NULL\r
622 },\r
623 {\r
624 EFI_IMAGE_SECURITY_DATABASE2,\r
625 {\r
626 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
627 0,\r
628 VARIABLE_ATTRIBUTE_NV_BS_RT_AT,\r
629 1,\r
630 MAX_UINTN\r
631 },\r
632 NULL\r
633 },\r
634};\r
635\r
636typedef struct {\r
637 EFI_GUID *Guid;\r
638 CHAR16 *Name;\r
639 VAR_CHECK_VARIABLE_PROPERTY VariableProperty;\r
640 INTERNAL_VAR_CHECK_FUNCTION CheckFunction;\r
641} VARIABLE_DRIVER_VARIABLE_ENTRY;\r
642\r
643VARIABLE_DRIVER_VARIABLE_ENTRY mVariableDriverVariableList[] = {\r
644 {\r
645 &gEfiSecureBootEnableDisableGuid,\r
646 EFI_SECURE_BOOT_ENABLE_NAME,\r
647 {\r
648 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
649 0,\r
650 VARIABLE_ATTRIBUTE_NV_BS,\r
651 sizeof (UINT8),\r
652 sizeof (UINT8)\r
952ba83c 653 }\r
17409b7a
SZ
654 },\r
655 {\r
656 &gEfiCustomModeEnableGuid,\r
657 EFI_CUSTOM_MODE_NAME,\r
658 {\r
659 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
660 0,\r
661 VARIABLE_ATTRIBUTE_NV_BS,\r
662 sizeof (UINT8),\r
663 sizeof (UINT8)\r
952ba83c 664 }\r
17409b7a
SZ
665 },\r
666 {\r
667 &gEfiVendorKeysNvGuid,\r
668 EFI_VENDOR_KEYS_NV_VARIABLE_NAME,\r
669 {\r
670 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
671 0,\r
672 VARIABLE_ATTRIBUTE_NV_BS_RT_AT,\r
673 sizeof (UINT8),\r
674 sizeof (UINT8)\r
952ba83c 675 }\r
17409b7a
SZ
676 },\r
677 {\r
678 &gEfiAuthenticatedVariableGuid,\r
679 L"AuthVarKeyDatabase",\r
680 {\r
681 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
682 0,\r
683 VARIABLE_ATTRIBUTE_NV_BS_RT_AW,\r
684 sizeof (UINT8),\r
685 MAX_UINTN\r
952ba83c 686 }\r
17409b7a
SZ
687 },\r
688 {\r
689 &gEfiCertDbGuid,\r
690 L"certdb",\r
691 {\r
692 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
693 0,\r
694 VARIABLE_ATTRIBUTE_NV_BS_RT_AT,\r
695 sizeof (UINT32),\r
696 MAX_UINTN\r
952ba83c
SZ
697 }\r
698 },\r
699 {\r
700 &gEdkiiVarErrorFlagGuid,\r
701 VAR_ERROR_FLAG_NAME,\r
702 {\r
703 VAR_CHECK_VARIABLE_PROPERTY_REVISION,\r
704 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,\r
705 VARIABLE_ATTRIBUTE_NV_BS_RT,\r
706 sizeof (VAR_ERROR_FLAG),\r
707 sizeof (VAR_ERROR_FLAG)\r
708 }\r
17409b7a
SZ
709 },\r
710};\r
711\r
712/**\r
713 Get UEFI defined global variable or image security database variable property.\r
714 The code will check if variable guid is global variable or image security database guid first.\r
715 If yes, further check if variable name is in mGlobalVariableList, mGlobalVariableList2 or mImageSecurityVariableList.\r
716\r
717 @param[in] VariableName Pointer to variable name.\r
718 @param[in] VendorGuid Variable Vendor Guid.\r
719 @param[in] WildcardMatch Try wildcard match or not.\r
720 @param[out] VariableProperty Pointer to variable property.\r
721 @param[out] VarCheckFunction Pointer to check function.\r
722\r
723 @retval EFI_SUCCESS Variable is not global variable or image security database variable.\r
724 @retval EFI_INVALID_PARAMETER Variable is global variable or image security database variable, but variable name is not in the lists.\r
725\r
726**/\r
727EFI_STATUS\r
728GetUefiDefinedVariableProperty (\r
729 IN CHAR16 *VariableName,\r
730 IN EFI_GUID *VendorGuid,\r
731 IN BOOLEAN WildcardMatch,\r
732 OUT VAR_CHECK_VARIABLE_PROPERTY **VariableProperty,\r
733 OUT INTERNAL_VAR_CHECK_FUNCTION *VarCheckFunction OPTIONAL\r
734 )\r
735{\r
736 UINTN Index;\r
737 UINTN NameLength;\r
738\r
952ba83c 739 if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)) {\r
17409b7a
SZ
740 //\r
741 // Try list 1, exactly match.\r
742 //\r
743 for (Index = 0; Index < sizeof (mGlobalVariableList)/sizeof (mGlobalVariableList[0]); Index++) {\r
744 if (StrCmp (mGlobalVariableList[Index].Name, VariableName) == 0) {\r
745 if (VarCheckFunction != NULL) {\r
746 *VarCheckFunction = mGlobalVariableList[Index].CheckFunction;\r
747 }\r
748 *VariableProperty = &mGlobalVariableList[Index].VariableProperty;\r
749 return EFI_SUCCESS;\r
750 }\r
751 }\r
752\r
753 //\r
754 // Try list 2.\r
755 //\r
756 NameLength = StrLen (VariableName) - 4;\r
757 for (Index = 0; Index < sizeof (mGlobalVariableList2)/sizeof (mGlobalVariableList2[0]); Index++) {\r
758 if (WildcardMatch) {\r
759 if ((StrLen (VariableName) == StrLen (mGlobalVariableList2[Index].Name)) &&\r
760 (StrnCmp (mGlobalVariableList2[Index].Name, VariableName, NameLength) == 0) &&\r
761 IsHexaDecimalDigitCharacter (VariableName[NameLength]) &&\r
762 IsHexaDecimalDigitCharacter (VariableName[NameLength + 1]) &&\r
763 IsHexaDecimalDigitCharacter (VariableName[NameLength + 2]) &&\r
764 IsHexaDecimalDigitCharacter (VariableName[NameLength + 3])) {\r
765 if (VarCheckFunction != NULL) {\r
766 *VarCheckFunction = mGlobalVariableList2[Index].CheckFunction;\r
767 }\r
768 *VariableProperty = &mGlobalVariableList2[Index].VariableProperty;\r
769 return EFI_SUCCESS;\r
770 }\r
952ba83c
SZ
771 }\r
772 if (StrCmp (mGlobalVariableList2[Index].Name, VariableName) == 0) {\r
773 if (VarCheckFunction != NULL) {\r
774 *VarCheckFunction = mGlobalVariableList2[Index].CheckFunction;\r
17409b7a 775 }\r
952ba83c
SZ
776 *VariableProperty = &mGlobalVariableList2[Index].VariableProperty;\r
777 return EFI_SUCCESS;\r
17409b7a
SZ
778 }\r
779 }\r
780\r
781 //\r
782 // The variable name is not in the lists.\r
783 //\r
784 return EFI_INVALID_PARAMETER;\r
785 }\r
786\r
787 if (CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid)){\r
788 for (Index = 0; Index < sizeof (mImageSecurityVariableList)/sizeof (mImageSecurityVariableList[0]); Index++) {\r
789 if (StrCmp (mImageSecurityVariableList[Index].Name, VariableName) == 0) {\r
790 if (VarCheckFunction != NULL) {\r
791 *VarCheckFunction = mImageSecurityVariableList[Index].CheckFunction;\r
792 }\r
793 *VariableProperty = &mImageSecurityVariableList[Index].VariableProperty;\r
794 return EFI_SUCCESS;\r
795 }\r
796 }\r
797\r
798 return EFI_INVALID_PARAMETER;\r
799 }\r
800\r
801 //\r
802 // It is not global variable or image security database variable.\r
803 //\r
804 return EFI_SUCCESS;\r
805}\r
806\r
807/**\r
808 Get variable property for variables managed by Varaible driver.\r
809\r
810 @param[in] VariableName Pointer to variable name.\r
811 @param[in] VendorGuid Variable Vendor Guid.\r
17409b7a
SZ
812\r
813 @return Pointer to variable property.\r
814\r
815**/\r
816VAR_CHECK_VARIABLE_PROPERTY *\r
817GetVariableDriverVariableProperty (\r
818 IN CHAR16 *VariableName,\r
952ba83c 819 IN EFI_GUID *VendorGuid\r
17409b7a
SZ
820 )\r
821{\r
822 UINTN Index;\r
823\r
824 for (Index = 0; Index < sizeof (mVariableDriverVariableList)/sizeof (mVariableDriverVariableList[0]); Index++) {\r
825 if ((CompareGuid (mVariableDriverVariableList[Index].Guid, VendorGuid)) && (StrCmp (mVariableDriverVariableList[Index].Name, VariableName) == 0)) {\r
17409b7a
SZ
826 return &mVariableDriverVariableList[Index].VariableProperty;\r
827 }\r
828 }\r
829\r
830 return NULL;\r
831}\r
832\r
833/**\r
834 Internal SetVariable check.\r
835\r
836 @param[in] VariableName Name of Variable to set.\r
837 @param[in] VendorGuid Variable vendor GUID.\r
838 @param[in] Attributes Attribute value of the variable.\r
839 @param[in] DataSize Size of Data to set.\r
840 @param[in] Data Data pointer.\r
841\r
842 @retval EFI_SUCCESS The SetVariable check result was success.\r
843 @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits, name, and GUID was supplied,\r
844 or the DataSize exceeds the minimum or maximum allowed,\r
845 or the Data value is not following UEFI spec for UEFI defined variables.\r
846 @retval EFI_WRITE_PROTECTED The variable in question is read-only.\r
847 @retval Others The return status from check handler.\r
848\r
849**/\r
850EFI_STATUS\r
851EFIAPI\r
852InternalVarCheckSetVariableCheck (\r
853 IN CHAR16 *VariableName,\r
854 IN EFI_GUID *VendorGuid,\r
855 IN UINT32 Attributes,\r
856 IN UINTN DataSize,\r
857 IN VOID *Data\r
858 )\r
859{\r
860 EFI_STATUS Status;\r
861 UINTN Index;\r
862 LIST_ENTRY *Link;\r
863 VAR_CHECK_VARIABLE_ENTRY *Entry;\r
864 CHAR16 *Name;\r
865 VAR_CHECK_VARIABLE_PROPERTY *Property;\r
866 INTERNAL_VAR_CHECK_FUNCTION VarCheckFunction;\r
867\r
868 if (!mEndOfDxe) {\r
869 //\r
870 // Only do check after End Of Dxe.\r
871 //\r
872 return EFI_SUCCESS;\r
873 }\r
874\r
875 Property = NULL;\r
952ba83c
SZ
876 VarCheckFunction = NULL;\r
877\r
878 for ( Link = GetFirstNode (&mVarCheckVariableList)\r
879 ; !IsNull (&mVarCheckVariableList, Link)\r
880 ; Link = GetNextNode (&mVarCheckVariableList, Link)\r
881 ) {\r
882 Entry = BASE_CR (Link, VAR_CHECK_VARIABLE_ENTRY, Link);\r
883 Name = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));\r
884 if (CompareGuid (&Entry->Guid, VendorGuid) && (StrCmp (Name, VariableName) == 0)) {\r
885 Property = &Entry->VariableProperty;\r
886 break;\r
887 }\r
17409b7a
SZ
888 }\r
889 if (Property == NULL) {\r
952ba83c 890 Property = GetVariableDriverVariableProperty (VariableName, VendorGuid);\r
17409b7a
SZ
891 }\r
892 if (Property == NULL) {\r
952ba83c
SZ
893 Status = GetUefiDefinedVariableProperty (VariableName, VendorGuid, TRUE, &Property, &VarCheckFunction);\r
894 if (EFI_ERROR (Status)) {\r
895 DEBUG ((EFI_D_INFO, "[Variable]: Var Check UEFI defined variable fail %r - %g:%s\n", Status, VendorGuid, VariableName));\r
896 return Status;\r
17409b7a
SZ
897 }\r
898 }\r
899 if (Property != NULL) {\r
900 if (mEnableLocking && ((Property->Property & VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY) != 0)) {\r
901 DEBUG ((EFI_D_INFO, "[Variable]: Var Check ReadOnly variable fail %r - %g:%s\n", EFI_WRITE_PROTECTED, VendorGuid, VariableName));\r
902 return EFI_WRITE_PROTECTED;\r
903 }\r
952ba83c 904 if (!((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0))) {\r
17409b7a 905 //\r
952ba83c 906 // Not to delete variable.\r
17409b7a 907 //\r
952ba83c
SZ
908 if ((Attributes & (~EFI_VARIABLE_APPEND_WRITE)) != Property->Attributes) {\r
909 DEBUG ((EFI_D_INFO, "[Variable]: Var Check Attributes(0x%08x to 0x%08x) fail %r - %g:%s\n", Property->Attributes, Attributes, EFI_INVALID_PARAMETER, VendorGuid, VariableName));\r
17409b7a
SZ
910 return EFI_INVALID_PARAMETER;\r
911 }\r
952ba83c
SZ
912 if (DataSize != 0) {\r
913 if ((DataSize < Property->MinSize) || (DataSize > Property->MaxSize)) {\r
914 DEBUG ((EFI_D_INFO, "[Variable]: Var Check DataSize fail(0x%x not in 0x%x - 0x%x) %r - %g:%s\n", DataSize, Property->MinSize, Property->MaxSize, EFI_INVALID_PARAMETER, VendorGuid, VariableName));\r
915 return EFI_INVALID_PARAMETER;\r
916 }\r
917 if (VarCheckFunction != NULL) {\r
918 Status = VarCheckFunction (\r
919 Property,\r
920 DataSize,\r
921 Data\r
922 );\r
923 if (EFI_ERROR (Status)) {\r
924 DEBUG ((EFI_D_INFO, "[Variable]: Internal Var Check function fail %r - %g:%s\n", Status, VendorGuid, VariableName));\r
925 return Status;\r
926 }\r
17409b7a
SZ
927 }\r
928 }\r
929 }\r
930 }\r
931\r
932 for (Index = 0; Index < mNumberOfHandler; Index ++) {\r
933 Status = mHandlerTable[Index] (\r
934 VariableName,\r
935 VendorGuid,\r
936 Attributes,\r
937 DataSize,\r
938 Data\r
939 );\r
940 if (EFI_ERROR (Status)) {\r
941 DEBUG ((EFI_D_INFO, "[Variable]: Var Check handler fail %r - %g:%s\n", Status, VendorGuid, VariableName));\r
942 return Status;\r
943 }\r
944 }\r
945 return EFI_SUCCESS;\r
946}\r
947\r
948/**\r
949 Reallocates more global memory to store the registered handler list.\r
950\r
951 @retval RETURN_SUCCESS Reallocate memory successfully.\r
952 @retval RETURN_OUT_OF_RESOURCES No enough memory to allocate.\r
953\r
954**/\r
955RETURN_STATUS\r
956EFIAPI\r
957ReallocateHandlerTable (\r
958 VOID\r
959 )\r
960{\r
961 VAR_CHECK_SET_VARIABLE_CHECK_HANDLER *HandlerTable;\r
962\r
963 //\r
964 // Reallocate memory for check handler table.\r
965 //\r
966 HandlerTable = ReallocateRuntimePool (\r
967 mMaxNumberOfHandler * sizeof (VAR_CHECK_SET_VARIABLE_CHECK_HANDLER), \r
968 (mMaxNumberOfHandler + VAR_CHECK_HANDLER_TABLE_SIZE) * sizeof (VAR_CHECK_SET_VARIABLE_CHECK_HANDLER), \r
969 mHandlerTable\r
970 );\r
971\r
972 //\r
973 // No enough resource to allocate.\r
974 //\r
975 if (HandlerTable == NULL) {\r
976 return RETURN_OUT_OF_RESOURCES;\r
977 }\r
978\r
979 mHandlerTable = HandlerTable;\r
980 //\r
981 // Increase max handler number.\r
982 //\r
983 mMaxNumberOfHandler = mMaxNumberOfHandler + VAR_CHECK_HANDLER_TABLE_SIZE;\r
984 return RETURN_SUCCESS;\r
985}\r
986\r
987/**\r
988 Register SetVariable check handler.\r
989\r
990 @param[in] Handler Pointer to check handler.\r
991\r
992 @retval EFI_SUCCESS The SetVariable check handler was registered successfully.\r
993 @retval EFI_INVALID_PARAMETER Handler is NULL.\r
994 @retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has\r
995 already been signaled.\r
996 @retval EFI_OUT_OF_RESOURCES There is not enough resource for the SetVariable check handler register request.\r
997 @retval EFI_UNSUPPORTED This interface is not implemented.\r
998 For example, it is unsupported in VarCheck protocol if both VarCheck and SmmVarCheck protocols are present.\r
999\r
1000**/\r
1001EFI_STATUS\r
1002EFIAPI\r
1003VarCheckRegisterSetVariableCheckHandler (\r
1004 IN VAR_CHECK_SET_VARIABLE_CHECK_HANDLER Handler\r
1005 )\r
1006{\r
1007 EFI_STATUS Status;\r
1008\r
1009 if (Handler == NULL) {\r
1010 return EFI_INVALID_PARAMETER;\r
1011 }\r
1012\r
1013 if (mEndOfDxe) {\r
1014 return EFI_ACCESS_DENIED;\r
1015 }\r
1016\r
1017 DEBUG ((EFI_D_INFO, "RegisterSetVariableCheckHandler - 0x%x\n", Handler));\r
1018\r
1019 //\r
1020 // Check whether the handler list is enough to store new handler.\r
1021 //\r
1022 if (mNumberOfHandler == mMaxNumberOfHandler) {\r
1023 //\r
1024 // Allocate more resources for new handler.\r
1025 //\r
1026 Status = ReallocateHandlerTable();\r
1027 if (EFI_ERROR (Status)) {\r
1028 return Status;\r
1029 }\r
1030 }\r
1031\r
1032 //\r
1033 // Register new handler into the handler list.\r
1034 //\r
1035 mHandlerTable[mNumberOfHandler] = Handler;\r
1036 mNumberOfHandler ++;\r
1037\r
1038 return EFI_SUCCESS;\r
1039}\r
1040\r
1041/**\r
952ba83c 1042 Variable property get function.\r
17409b7a 1043\r
952ba83c
SZ
1044 @param[in] Name Pointer to the variable name.\r
1045 @param[in] Guid Pointer to the vendor GUID.\r
1046 @param[in] WildcardMatch Try wildcard match or not.\r
17409b7a
SZ
1047\r
1048 @return Pointer to the property of variable specified by the Name and Guid.\r
1049\r
1050**/\r
1051VAR_CHECK_VARIABLE_PROPERTY *\r
952ba83c
SZ
1052VariablePropertyGetFunction (\r
1053 IN CHAR16 *Name,\r
1054 IN EFI_GUID *Guid,\r
1055 IN BOOLEAN WildcardMatch\r
17409b7a
SZ
1056 )\r
1057{\r
1058 LIST_ENTRY *Link;\r
1059 VAR_CHECK_VARIABLE_ENTRY *Entry;\r
1060 CHAR16 *VariableName;\r
1061 VAR_CHECK_VARIABLE_PROPERTY *Property;\r
1062\r
952ba83c
SZ
1063 for ( Link = GetFirstNode (&mVarCheckVariableList)\r
1064 ; !IsNull (&mVarCheckVariableList, Link)\r
1065 ; Link = GetNextNode (&mVarCheckVariableList, Link)\r
1066 ) {\r
1067 Entry = BASE_CR (Link, VAR_CHECK_VARIABLE_ENTRY, Link);\r
1068 VariableName = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));\r
1069 if (CompareGuid (&Entry->Guid, Guid) && (StrCmp (VariableName, Name) == 0)) {\r
1070 return &Entry->VariableProperty;\r
17409b7a
SZ
1071 }\r
1072 }\r
1073\r
952ba83c
SZ
1074 Property = GetVariableDriverVariableProperty (Name, Guid);\r
1075 if (Property == NULL) {\r
1076 GetUefiDefinedVariableProperty (Name, Guid, WildcardMatch, &Property, NULL);\r
1077 }\r
1078\r
1079 return Property;\r
17409b7a
SZ
1080}\r
1081\r
1082/**\r
1083 Variable property set.\r
1084\r
1085 @param[in] Name Pointer to the variable name.\r
1086 @param[in] Guid Pointer to the vendor GUID.\r
1087 @param[in] VariableProperty Pointer to the input variable property.\r
1088\r
1089 @retval EFI_SUCCESS The property of variable specified by the Name and Guid was set successfully.\r
1090 @retval EFI_INVALID_PARAMETER Name, Guid or VariableProperty is NULL, or Name is an empty string,\r
1091 or the fields of VariableProperty are not valid.\r
1092 @retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has\r
1093 already been signaled.\r
1094 @retval EFI_OUT_OF_RESOURCES There is not enough resource for the variable property set request.\r
1095\r
1096**/\r
1097EFI_STATUS\r
1098EFIAPI\r
1099VarCheckVariablePropertySet (\r
1100 IN CHAR16 *Name,\r
1101 IN EFI_GUID *Guid,\r
1102 IN VAR_CHECK_VARIABLE_PROPERTY *VariableProperty\r
1103 )\r
1104{\r
1105 EFI_STATUS Status;\r
1106 VAR_CHECK_VARIABLE_ENTRY *Entry;\r
1107 CHAR16 *VariableName;\r
1108 VAR_CHECK_VARIABLE_PROPERTY *Property;\r
1109\r
1110 if (Name == NULL || Name[0] == 0 || Guid == NULL) {\r
1111 return EFI_INVALID_PARAMETER;\r
1112 }\r
1113\r
1114 if (VariableProperty == NULL) {\r
1115 return EFI_INVALID_PARAMETER;\r
1116 }\r
1117\r
1118 if (VariableProperty->Revision != VAR_CHECK_VARIABLE_PROPERTY_REVISION) {\r
1119 return EFI_INVALID_PARAMETER;\r
1120 }\r
1121\r
1122 if (mEndOfDxe) {\r
1123 return EFI_ACCESS_DENIED;\r
1124 }\r
1125\r
1126 Status = EFI_SUCCESS;\r
1127\r
1128 AcquireLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
1129\r
952ba83c 1130 Property = VariablePropertyGetFunction (Name, Guid, FALSE);\r
17409b7a
SZ
1131 if (Property != NULL) {\r
1132 CopyMem (Property, VariableProperty, sizeof (*VariableProperty));\r
1133 } else {\r
1134 Entry = AllocateRuntimeZeroPool (sizeof (*Entry) + StrSize (Name));\r
1135 if (Entry == NULL) {\r
1136 Status = EFI_OUT_OF_RESOURCES;\r
1137 goto Done;\r
1138 }\r
1139 VariableName = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));\r
1140 StrnCpy (VariableName, Name, StrLen (Name));\r
1141 CopyGuid (&Entry->Guid, Guid);\r
1142 CopyMem (&Entry->VariableProperty, VariableProperty, sizeof (*VariableProperty));\r
1143 InsertTailList (&mVarCheckVariableList, &Entry->Link);\r
1144 }\r
1145\r
1146Done:\r
1147 ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
1148\r
1149 return Status;\r
1150}\r
1151\r
1152/**\r
952ba83c 1153 Internal variable property get.\r
17409b7a
SZ
1154\r
1155 @param[in] Name Pointer to the variable name.\r
1156 @param[in] Guid Pointer to the vendor GUID.\r
1157 @param[out] VariableProperty Pointer to the output variable property.\r
1158\r
1159 @retval EFI_SUCCESS The property of variable specified by the Name and Guid was got successfully.\r
17409b7a
SZ
1160 @retval EFI_NOT_FOUND The property of variable specified by the Name and Guid was not found.\r
1161\r
1162**/\r
1163EFI_STATUS\r
1164EFIAPI\r
952ba83c 1165InternalVarCheckVariablePropertyGet (\r
17409b7a
SZ
1166 IN CHAR16 *Name,\r
1167 IN EFI_GUID *Guid,\r
1168 OUT VAR_CHECK_VARIABLE_PROPERTY *VariableProperty\r
1169 )\r
1170{\r
1171 LIST_ENTRY *Link;\r
1172 VARIABLE_ENTRY *Entry;\r
1173 CHAR16 *VariableName;\r
1174 BOOLEAN Found;\r
1175 VAR_CHECK_VARIABLE_PROPERTY *Property;\r
1176\r
17409b7a
SZ
1177 Found = FALSE;\r
1178\r
952ba83c 1179 Property = VariablePropertyGetFunction (Name, Guid, TRUE);\r
17409b7a
SZ
1180 if (Property != NULL) {\r
1181 CopyMem (VariableProperty, Property, sizeof (*VariableProperty));\r
1182 Found = TRUE;\r
1183 }\r
1184\r
1185 for ( Link = GetFirstNode (&mLockedVariableList)\r
1186 ; !IsNull (&mLockedVariableList, Link)\r
1187 ; Link = GetNextNode (&mLockedVariableList, Link)\r
1188 ) {\r
1189 Entry = BASE_CR (Link, VARIABLE_ENTRY, Link);\r
1190 VariableName = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));\r
1191 if (CompareGuid (&Entry->Guid, Guid) && (StrCmp (VariableName, Name) == 0)) {\r
1192 VariableProperty->Property |= VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY;\r
1193 if (!Found) {\r
1194 VariableProperty->Revision = VAR_CHECK_VARIABLE_PROPERTY_REVISION;\r
1195 Found = TRUE;\r
1196 }\r
1197 }\r
1198 }\r
1199\r
952ba83c
SZ
1200 return (Found ? EFI_SUCCESS : EFI_NOT_FOUND);\r
1201}\r
1202\r
1203/**\r
1204 Variable property get.\r
1205\r
1206 @param[in] Name Pointer to the variable name.\r
1207 @param[in] Guid Pointer to the vendor GUID.\r
1208 @param[out] VariableProperty Pointer to the output variable property.\r
1209\r
1210 @retval EFI_SUCCESS The property of variable specified by the Name and Guid was got successfully.\r
1211 @retval EFI_INVALID_PARAMETER Name, Guid or VariableProperty is NULL, or Name is an empty string.\r
1212 @retval EFI_NOT_FOUND The property of variable specified by the Name and Guid was not found.\r
1213\r
1214**/\r
1215EFI_STATUS\r
1216EFIAPI\r
1217VarCheckVariablePropertyGet (\r
1218 IN CHAR16 *Name,\r
1219 IN EFI_GUID *Guid,\r
1220 OUT VAR_CHECK_VARIABLE_PROPERTY *VariableProperty\r
1221 )\r
1222{\r
1223 EFI_STATUS Status;\r
1224\r
1225 if (Name == NULL || Name[0] == 0 || Guid == NULL) {\r
1226 return EFI_INVALID_PARAMETER;\r
1227 }\r
1228\r
1229 if (VariableProperty == NULL) {\r
1230 return EFI_INVALID_PARAMETER;\r
1231 }\r
1232\r
1233 AcquireLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
1234\r
1235 Status = InternalVarCheckVariablePropertyGet (Name, Guid, VariableProperty);\r
1236\r
17409b7a
SZ
1237 ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
1238\r
952ba83c 1239 return Status;\r
17409b7a
SZ
1240}\r
1241\r