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