TianoCore EDK2 master
Loading...
Searching...
No Matches
VarCheckHiiLibCommon.c
Go to the documentation of this file.
1
6#include <Uefi.h>
7#include <Library/DebugLib.h>
8
9#include "VarCheckHii.h"
11EFI_HANDLE mEfiVariableCheckHiiHandle = NULL;
12GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mVarCheckHiiHex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
13
21VOID
23 IN UINTN Indent,
24 IN UINTN Offset,
25 IN UINTN DataSize,
26 IN VOID *UserData
27 )
28{
29 UINT8 *Data;
30
31 CHAR8 Val[50];
32
33 CHAR8 Str[20];
34
35 UINT8 TempByte;
36 UINTN Size;
37 UINTN Index;
38
39 Data = UserData;
40 while (DataSize != 0) {
41 Size = 16;
42 if (Size > DataSize) {
43 Size = DataSize;
44 }
45
46 for (Index = 0; Index < Size; Index += 1) {
47 TempByte = Data[Index];
48 Val[Index * 3 + 0] = mVarCheckHiiHex[TempByte >> 4];
49 Val[Index * 3 + 1] = mVarCheckHiiHex[TempByte & 0xF];
50 Val[Index * 3 + 2] = (CHAR8)((Index == 7) ? '-' : ' ');
51 Str[Index] = (CHAR8)((TempByte < ' ' || TempByte > 'z') ? '.' : TempByte);
52 }
53
54 Val[Index * 3] = 0;
55 Str[Index] = 0;
56 DEBUG ((DEBUG_INFO, "%*a%08X: %-48a *%a*\r\n", Indent, "", Offset, Val, Str));
57
58 Data += Size;
59 Offset += Size;
60 DataSize -= Size;
61 }
62}
63
72BOOLEAN
75 IN VOID *Data,
76 IN UINTN DataSize
77 )
78{
79 UINT64 OneData;
80 UINT64 Minimum;
81 UINT64 Maximum;
82 UINT64 OneValue;
83 UINT8 *Ptr;
84 UINT8 Index;
85 UINT8 MaxContainers;
86 UINT8 StartBit;
87 UINT8 EndBit;
88 UINT8 TotalBits;
89 UINT16 VarOffsetByteLevel;
90 UINT8 StorageWidthByteLevel;
91
92 if (HiiQuestion->BitFieldStore) {
93 VarOffsetByteLevel = HiiQuestion->VarOffset / 8;
94 TotalBits = HiiQuestion->VarOffset % 8 + HiiQuestion->StorageWidth;
95 StorageWidthByteLevel = (TotalBits % 8 == 0 ? TotalBits / 8 : TotalBits / 8 + 1);
96 } else {
97 VarOffsetByteLevel = HiiQuestion->VarOffset;
98 StorageWidthByteLevel = HiiQuestion->StorageWidth;
99 }
100
101 if (((UINT32)VarOffsetByteLevel + StorageWidthByteLevel) > DataSize) {
102 DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: (VarOffset(0x%04x) + StorageWidth(0x%02x)) > Size(0x%x)\n", VarOffsetByteLevel, StorageWidthByteLevel, DataSize));
103 return FALSE;
104 }
105
106 OneData = 0;
107 CopyMem (&OneData, (UINT8 *)Data + VarOffsetByteLevel, StorageWidthByteLevel);
108 if (HiiQuestion->BitFieldStore) {
109 //
110 // Get the value from the bit field.
111 //
112 StartBit = HiiQuestion->VarOffset % 8;
113 EndBit = StartBit + HiiQuestion->StorageWidth - 1;
114 OneData = BitFieldRead64 (OneData, StartBit, EndBit);
115 }
116
117 switch (HiiQuestion->OpCode) {
118 case EFI_IFR_ONE_OF_OP:
119 Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ONEOF *)HiiQuestion + 1);
120 while ((UINTN)Ptr < (UINTN)HiiQuestion + HiiQuestion->Length) {
121 OneValue = 0;
122 if (HiiQuestion->BitFieldStore) {
123 //
124 // For OneOf stored in bit field, the value of options are saved as UINT32 type.
125 //
126 CopyMem (&OneValue, Ptr, sizeof (UINT32));
127 } else {
128 CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth);
129 }
130
131 if (OneData == OneValue) {
132 //
133 // Match
134 //
135 break;
136 }
137
138 if (HiiQuestion->BitFieldStore) {
139 Ptr += sizeof (UINT32);
140 } else {
141 Ptr += HiiQuestion->StorageWidth;
142 }
143 }
144
145 if ((UINTN)Ptr >= ((UINTN)HiiQuestion + HiiQuestion->Length)) {
146 //
147 // No match
148 //
149 DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: OneOf mismatch (0x%lx)\n", OneData));
150 DEBUG_CODE (
151 VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion);
152 );
153 return FALSE;
154 }
155
156 break;
157
158 case EFI_IFR_CHECKBOX_OP:
159 if ((OneData != 0) && (OneData != 1)) {
160 DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: CheckBox mismatch (0x%lx)\n", OneData));
161 DEBUG_CODE (
162 VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion);
163 );
164 return FALSE;
165 }
166
167 break;
168
169 case EFI_IFR_NUMERIC_OP:
170 Minimum = 0;
171 Maximum = 0;
172 Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_NUMERIC *)HiiQuestion + 1);
173 if (HiiQuestion->BitFieldStore) {
174 //
175 // For Numeric stored in bit field, the value of Maximum/Minimum are saved as UINT32 type.
176 //
177 CopyMem (&Minimum, Ptr, sizeof (UINT32));
178 Ptr += sizeof (UINT32);
179 CopyMem (&Maximum, Ptr, sizeof (UINT32));
180 Ptr += sizeof (UINT32);
181 } else {
182 CopyMem (&Minimum, Ptr, HiiQuestion->StorageWidth);
183 Ptr += HiiQuestion->StorageWidth;
184 CopyMem (&Maximum, Ptr, HiiQuestion->StorageWidth);
185 Ptr += HiiQuestion->StorageWidth;
186 }
187
188 //
189 // No need to check Step, because it is ONLY for UI.
190 //
191 if ((OneData < Minimum) || (OneData > Maximum)) {
192 DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: Numeric mismatch (0x%lx)\n", OneData));
193 DEBUG_CODE (
194 VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion);
195 );
196 return FALSE;
197 }
198
199 break;
200
201 case EFI_IFR_ORDERED_LIST_OP:
202 MaxContainers = ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion)->MaxContainers;
203 if (((UINT32)HiiQuestion->VarOffset + HiiQuestion->StorageWidth * MaxContainers) > DataSize) {
204 DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: (VarOffset(0x%04x) + StorageWidth(0x%02x) * MaxContainers(0x%02x)) > Size(0x%x)\n", HiiQuestion->VarOffset, HiiQuestion->StorageWidth, MaxContainers, DataSize));
205 return FALSE;
206 }
207
208 for (Index = 0; Index < MaxContainers; Index++) {
209 OneData = 0;
210 CopyMem (&OneData, (UINT8 *)Data + HiiQuestion->VarOffset + HiiQuestion->StorageWidth * Index, HiiQuestion->StorageWidth);
211 if (OneData == 0) {
212 //
213 // The value of 0 is used to determine if a particular "slot" in the array is empty.
214 //
215 continue;
216 }
217
218 Ptr = (UINT8 *)((VAR_CHECK_HII_QUESTION_ORDEREDLIST *)HiiQuestion + 1);
219 while ((UINTN)Ptr < ((UINTN)HiiQuestion + HiiQuestion->Length)) {
220 OneValue = 0;
221 CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth);
222 if (OneData == OneValue) {
223 //
224 // Match
225 //
226 break;
227 }
228
229 Ptr += HiiQuestion->StorageWidth;
230 }
231
232 if ((UINTN)Ptr >= ((UINTN)HiiQuestion + HiiQuestion->Length)) {
233 //
234 // No match
235 //
236 DEBUG ((DEBUG_INFO, "VarCheckHiiQuestion fail: OrderedList mismatch\n"));
237 DEBUG_CODE (
238 VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->StorageWidth * MaxContainers, (UINT8 *)Data + HiiQuestion->VarOffset);
239 );
240 DEBUG_CODE (
241 VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *)HiiQuestion);
242 );
243 return FALSE;
244 }
245 }
246
247 break;
248
249 default:
250 ASSERT (FALSE);
251 break;
252 }
253
254 return TRUE;
255}
256
270EFIAPI
272 IN VAR_CHECK_HII_VARIABLE_HEADER *HiiVariableBin,
273 IN UINTN HiiVariableBinSize,
274 IN CHAR16 *VariableName,
275 IN EFI_GUID *VendorGuid,
276 IN UINT32 Attributes,
277 IN UINTN DataSize,
278 IN VOID *Data
279 )
280{
283
284 if (HiiVariableBin == NULL) {
285 return EFI_SUCCESS;
286 }
287
288 if ((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0)) {
289 //
290 // Do not check delete variable.
291 //
292 }
293
294 //
295 // For Hii Variable header align.
296 //
297 HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (HiiVariableBin);
298 while ((UINTN)HiiVariable < ((UINTN)HiiVariableBin + HiiVariableBinSize)) {
299 if ((StrCmp ((CHAR16 *)(HiiVariable + 1), VariableName) == 0) &&
300 (CompareGuid (&HiiVariable->Guid, VendorGuid)))
301 {
302 //
303 // Found the Hii Variable that could be used to do check.
304 //
305 DEBUG ((DEBUG_INFO, "VarCheckHiiVariable - %s:%g with Attributes = 0x%08x Size = 0x%x\n", VariableName, VendorGuid, Attributes, DataSize));
306 if (HiiVariable->Attributes != Attributes) {
307 DEBUG ((DEBUG_INFO, "VarCheckHiiVariable fail for Attributes - 0x%08x\n", HiiVariable->Attributes));
308 return EFI_SECURITY_VIOLATION;
309 }
310
311 if (DataSize == 0) {
312 DEBUG ((DEBUG_INFO, "VarCheckHiiVariable - CHECK PASS with DataSize == 0 !\n"));
313 return EFI_SUCCESS;
314 }
315
316 if (HiiVariable->Size != DataSize) {
317 DEBUG ((DEBUG_INFO, "VarCheckHiiVariable fail for Size - 0x%x\n", HiiVariable->Size));
318 return EFI_SECURITY_VIOLATION;
319 }
320
321 //
322 // Do the check.
323 // For Hii Question header align.
324 //
325 HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->HeaderLength));
326 while ((UINTN)HiiQuestion < ((UINTN)HiiVariable + HiiVariable->Length)) {
327 if (!VarCheckHiiQuestion (HiiQuestion, Data, DataSize)) {
328 return EFI_SECURITY_VIOLATION;
329 }
330
331 //
332 // For Hii Question header align.
333 //
334 HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *)HEADER_ALIGN (((UINTN)HiiQuestion + HiiQuestion->Length));
335 }
336
337 DEBUG ((DEBUG_INFO, "VarCheckHiiVariable - ALL CHECK PASS!\n"));
338 return EFI_SUCCESS;
339 }
340
341 //
342 // For Hii Variable header align.
343 //
344 HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *)HEADER_ALIGN (((UINTN)HiiVariable + HiiVariable->Length));
345 }
346
347 // Not found, so pass.
348 return EFI_SUCCESS;
349}
UINT64 UINTN
INTN EFIAPI StrCmp(IN CONST CHAR16 *FirstString, IN CONST CHAR16 *SecondString)
Definition: String.c:109
UINT64 EFIAPI BitFieldRead64(IN UINT64 Operand, IN UINTN StartBit, IN UINTN EndBit)
Definition: BitField.c:719
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define GLOBAL_REMOVE_IF_UNREFERENCED
Definition: Base.h:48
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define DEBUG_CODE(Expression)
Definition: DebugLib.h:590
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_STATUS EFIAPI CheckHiiVariableCommon(IN VAR_CHECK_HII_VARIABLE_HEADER *HiiVariableBin, IN UINTN HiiVariableBinSize, IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, IN UINT32 Attributes, IN UINTN DataSize, IN VOID *Data)
BOOLEAN VarCheckHiiQuestion(IN VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion, IN VOID *Data, IN UINTN DataSize)
VOID VarCheckHiiInternalDumpHex(IN UINTN Indent, IN UINTN Offset, IN UINTN DataSize, IN VOID *UserData)
Definition: Base.h:213