TianoCore EDK2 master
Loading...
Searching...
No Matches
SmmLockBox.c
Go to the documentation of this file.
1
18#include <PiSmm.h>
23#include <Library/BaseLib.h>
25#include <Library/DebugLib.h>
26#include <Library/SmmMemLib.h>
27#include <Library/LockBoxLib.h>
28
31#include <Protocol/LockBox.h>
32#include <Guid/SmmLockBox.h>
33
34BOOLEAN mLocked = FALSE;
35
45VOID
47 IN EFI_SMM_LOCK_BOX_PARAMETER_SAVE *LockBoxParameterSave
48 )
49{
50 EFI_STATUS Status;
51 EFI_SMM_LOCK_BOX_PARAMETER_SAVE TempLockBoxParameterSave;
52
53 //
54 // Sanity check
55 //
56 if (mLocked) {
57 DEBUG ((DEBUG_ERROR, "SmmLockBox Locked!\n"));
58 LockBoxParameterSave->Header.ReturnStatus = (UINT64)EFI_ACCESS_DENIED;
59 return;
60 }
61
62 CopyMem (&TempLockBoxParameterSave, LockBoxParameterSave, sizeof (EFI_SMM_LOCK_BOX_PARAMETER_SAVE));
63
64 //
65 // Sanity check
66 //
67 if (!SmmIsBufferOutsideSmmValid ((UINTN)TempLockBoxParameterSave.Buffer, (UINTN)TempLockBoxParameterSave.Length)) {
68 DEBUG ((DEBUG_ERROR, "SmmLockBox Save address in SMRAM or buffer overflow!\n"));
69 LockBoxParameterSave->Header.ReturnStatus = (UINT64)EFI_ACCESS_DENIED;
70 return;
71 }
72
73 //
74 // The SpeculationBarrier() call here is to ensure the above range check for
75 // the CommBuffer have been completed before calling into SaveLockBox().
76 //
78
79 //
80 // Save data
81 //
82 Status = SaveLockBox (
83 &TempLockBoxParameterSave.Guid,
84 (VOID *)(UINTN)TempLockBoxParameterSave.Buffer,
85 (UINTN)TempLockBoxParameterSave.Length
86 );
87 LockBoxParameterSave->Header.ReturnStatus = (UINT64)Status;
88 return;
89}
90
96VOID
98 IN EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES *LockBoxParameterSetAttributes
99 )
100{
101 EFI_STATUS Status;
102 EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES TempLockBoxParameterSetAttributes;
103
104 //
105 // Sanity check
106 //
107 if (mLocked) {
108 DEBUG ((DEBUG_ERROR, "SmmLockBox Locked!\n"));
109 LockBoxParameterSetAttributes->Header.ReturnStatus = (UINT64)EFI_ACCESS_DENIED;
110 return;
111 }
112
113 CopyMem (&TempLockBoxParameterSetAttributes, LockBoxParameterSetAttributes, sizeof (EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES));
114
115 //
116 // Update data
117 //
118 Status = SetLockBoxAttributes (
119 &TempLockBoxParameterSetAttributes.Guid,
120 TempLockBoxParameterSetAttributes.Attributes
121 );
122 LockBoxParameterSetAttributes->Header.ReturnStatus = (UINT64)Status;
123 return;
124}
125
135VOID
137 IN EFI_SMM_LOCK_BOX_PARAMETER_UPDATE *LockBoxParameterUpdate
138 )
139{
140 EFI_STATUS Status;
141 EFI_SMM_LOCK_BOX_PARAMETER_UPDATE TempLockBoxParameterUpdate;
142
143 //
144 // Sanity check
145 //
146 if (mLocked) {
147 DEBUG ((DEBUG_ERROR, "SmmLockBox Locked!\n"));
148 LockBoxParameterUpdate->Header.ReturnStatus = (UINT64)EFI_ACCESS_DENIED;
149 return;
150 }
151
152 CopyMem (&TempLockBoxParameterUpdate, LockBoxParameterUpdate, sizeof (EFI_SMM_LOCK_BOX_PARAMETER_UPDATE));
153
154 //
155 // Sanity check
156 //
157 if (!SmmIsBufferOutsideSmmValid ((UINTN)TempLockBoxParameterUpdate.Buffer, (UINTN)TempLockBoxParameterUpdate.Length)) {
158 DEBUG ((DEBUG_ERROR, "SmmLockBox Update address in SMRAM or buffer overflow!\n"));
159 LockBoxParameterUpdate->Header.ReturnStatus = (UINT64)EFI_ACCESS_DENIED;
160 return;
161 }
162
163 //
164 // The SpeculationBarrier() call here is to ensure the above range check for
165 // the CommBuffer have been completed before calling into UpdateLockBox().
166 //
168
169 //
170 // Update data
171 //
172 Status = UpdateLockBox (
173 &TempLockBoxParameterUpdate.Guid,
174 (UINTN)TempLockBoxParameterUpdate.Offset,
175 (VOID *)(UINTN)TempLockBoxParameterUpdate.Buffer,
176 (UINTN)TempLockBoxParameterUpdate.Length
177 );
178 LockBoxParameterUpdate->Header.ReturnStatus = (UINT64)Status;
179 return;
180}
181
191VOID
193 IN EFI_SMM_LOCK_BOX_PARAMETER_RESTORE *LockBoxParameterRestore
194 )
195{
196 EFI_STATUS Status;
197 EFI_SMM_LOCK_BOX_PARAMETER_RESTORE TempLockBoxParameterRestore;
198
199 CopyMem (&TempLockBoxParameterRestore, LockBoxParameterRestore, sizeof (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE));
200
201 //
202 // Sanity check
203 //
204 if (!SmmIsBufferOutsideSmmValid ((UINTN)TempLockBoxParameterRestore.Buffer, (UINTN)TempLockBoxParameterRestore.Length)) {
205 DEBUG ((DEBUG_ERROR, "SmmLockBox Restore address in SMRAM or buffer overflow!\n"));
206 LockBoxParameterRestore->Header.ReturnStatus = (UINT64)EFI_ACCESS_DENIED;
207 return;
208 }
209
210 //
211 // Restore data
212 //
213 if ((TempLockBoxParameterRestore.Length == 0) && (TempLockBoxParameterRestore.Buffer == 0)) {
214 Status = RestoreLockBox (
215 &TempLockBoxParameterRestore.Guid,
216 NULL,
217 NULL
218 );
219 } else {
220 Status = RestoreLockBox (
221 &TempLockBoxParameterRestore.Guid,
222 (VOID *)(UINTN)TempLockBoxParameterRestore.Buffer,
223 (UINTN *)&TempLockBoxParameterRestore.Length
224 );
225 if ((Status == EFI_BUFFER_TOO_SMALL) || (Status == EFI_SUCCESS)) {
226 //
227 // Return the actual Length value.
228 //
229 LockBoxParameterRestore->Length = TempLockBoxParameterRestore.Length;
230 }
231 }
232
233 LockBoxParameterRestore->Header.ReturnStatus = (UINT64)Status;
234 return;
235}
236
242VOID
244 IN EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE *LockBoxParameterRestoreAllInPlace
245 )
246{
247 EFI_STATUS Status;
248
249 Status = RestoreAllLockBoxInPlace ();
250 LockBoxParameterRestoreAllInPlace->Header.ReturnStatus = (UINT64)Status;
251 return;
252}
253
271EFIAPI
273 IN EFI_HANDLE DispatchHandle,
274 IN CONST VOID *Context OPTIONAL,
275 IN OUT VOID *CommBuffer OPTIONAL,
276 IN OUT UINTN *CommBufferSize OPTIONAL
277 )
278{
279 EFI_SMM_LOCK_BOX_PARAMETER_HEADER *LockBoxParameterHeader;
280 UINTN TempCommBufferSize;
281
282 DEBUG ((DEBUG_INFO, "SmmLockBox SmmLockBoxHandler Enter\n"));
283
284 //
285 // If input is invalid, stop processing this SMI
286 //
287 if ((CommBuffer == NULL) || (CommBufferSize == NULL)) {
288 return EFI_SUCCESS;
289 }
290
291 TempCommBufferSize = *CommBufferSize;
292
293 //
294 // Sanity check
295 //
296 if (TempCommBufferSize < sizeof (EFI_SMM_LOCK_BOX_PARAMETER_HEADER)) {
297 DEBUG ((DEBUG_ERROR, "SmmLockBox Command Buffer Size invalid!\n"));
298 return EFI_SUCCESS;
299 }
300
301 if (!SmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) {
302 DEBUG ((DEBUG_ERROR, "SmmLockBox Command Buffer in SMRAM or overflow!\n"));
303 return EFI_SUCCESS;
304 }
305
306 LockBoxParameterHeader = (EFI_SMM_LOCK_BOX_PARAMETER_HEADER *)((UINTN)CommBuffer);
307
308 LockBoxParameterHeader->ReturnStatus = (UINT64)-1;
309
310 DEBUG ((DEBUG_INFO, "SmmLockBox LockBoxParameterHeader - %x\n", (UINTN)LockBoxParameterHeader));
311
312 DEBUG ((DEBUG_INFO, "SmmLockBox Command - %x\n", (UINTN)LockBoxParameterHeader->Command));
313
314 switch (LockBoxParameterHeader->Command) {
315 case EFI_SMM_LOCK_BOX_COMMAND_SAVE:
316 if (TempCommBufferSize < sizeof (EFI_SMM_LOCK_BOX_PARAMETER_SAVE)) {
317 DEBUG ((DEBUG_ERROR, "SmmLockBox Command Buffer Size for SAVE invalid!\n"));
318 break;
319 }
320
321 SmmLockBoxSave ((EFI_SMM_LOCK_BOX_PARAMETER_SAVE *)(UINTN)LockBoxParameterHeader);
322 break;
323 case EFI_SMM_LOCK_BOX_COMMAND_UPDATE:
324 if (TempCommBufferSize < sizeof (EFI_SMM_LOCK_BOX_PARAMETER_UPDATE)) {
325 DEBUG ((DEBUG_ERROR, "SmmLockBox Command Buffer Size for UPDATE invalid!\n"));
326 break;
327 }
328
329 SmmLockBoxUpdate ((EFI_SMM_LOCK_BOX_PARAMETER_UPDATE *)(UINTN)LockBoxParameterHeader);
330 break;
331 case EFI_SMM_LOCK_BOX_COMMAND_RESTORE:
332 if (TempCommBufferSize < sizeof (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE)) {
333 DEBUG ((DEBUG_ERROR, "SmmLockBox Command Buffer Size for RESTORE invalid!\n"));
334 break;
335 }
336
338 break;
339 case EFI_SMM_LOCK_BOX_COMMAND_SET_ATTRIBUTES:
340 if (TempCommBufferSize < sizeof (EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES)) {
341 DEBUG ((DEBUG_ERROR, "SmmLockBox Command Buffer Size for SET_ATTRIBUTES invalid!\n"));
342 break;
343 }
344
346 break;
347 case EFI_SMM_LOCK_BOX_COMMAND_RESTORE_ALL_IN_PLACE:
348 if (TempCommBufferSize < sizeof (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE)) {
349 DEBUG ((DEBUG_ERROR, "SmmLockBox Command Buffer Size for RESTORE_ALL_IN_PLACE invalid!\n"));
350 break;
351 }
352
354 break;
355 default:
356 DEBUG ((DEBUG_ERROR, "SmmLockBox Command invalid!\n"));
357 break;
358 }
359
360 LockBoxParameterHeader->Command = (UINT32)-1;
361
362 DEBUG ((DEBUG_INFO, "SmmLockBox SmmLockBoxHandler Exit\n"));
363
364 return EFI_SUCCESS;
365}
366
379EFIAPI
381 IN CONST EFI_GUID *Protocol,
382 IN VOID *Interface,
383 IN EFI_HANDLE Handle
384 )
385{
386 mLocked = TRUE;
387 return EFI_SUCCESS;
388}
389
400EFIAPI
402 IN EFI_HANDLE ImageHandle,
403 IN EFI_SYSTEM_TABLE *SystemTable
404 )
405{
406 EFI_STATUS Status;
407 EFI_HANDLE DispatchHandle;
408 VOID *Registration;
409
410 //
411 // Register LockBox communication handler
412 //
413 Status = gSmst->SmiHandlerRegister (
415 &gEfiSmmLockBoxCommunicationGuid,
416 &DispatchHandle
417 );
418 ASSERT_EFI_ERROR (Status);
419
420 //
421 // Register SMM Ready To Lock Protocol notification
422 //
423 Status = gSmst->SmmRegisterProtocolNotify (
424 &gEfiSmmReadyToLockProtocolGuid,
426 &Registration
427 );
428 ASSERT_EFI_ERROR (Status);
429
430 //
431 // Install NULL to DXE data base as notify
432 //
433 ImageHandle = NULL;
434 Status = gBS->InstallProtocolInterface (
435 &ImageHandle,
436 &gEfiLockBoxProtocolGuid,
438 NULL
439 );
440 ASSERT_EFI_ERROR (Status);
441
442 return Status;
443}
UINT64 UINTN
VOID EFIAPI SpeculationBarrier(VOID)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
RETURN_STATUS EFIAPI SetLockBoxAttributes(IN GUID *Guid, IN UINT64 Attributes)
RETURN_STATUS EFIAPI RestoreLockBox(IN GUID *Guid, IN VOID *Buffer OPTIONAL, IN OUT UINTN *Length OPTIONAL)
RETURN_STATUS EFIAPI RestoreAllLockBoxInPlace(VOID)
RETURN_STATUS EFIAPI UpdateLockBox(IN GUID *Guid, IN UINTN Offset, IN VOID *Buffer, IN UINTN Length)
RETURN_STATUS EFIAPI SaveLockBox(IN GUID *Guid, IN VOID *Buffer, IN UINTN Length)
#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 OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
EFI_SMM_SYSTEM_TABLE2 * gSmst
EFI_STATUS EFIAPI SmmLockBoxHandler(IN EFI_HANDLE DispatchHandle, IN CONST VOID *Context OPTIONAL, IN OUT VOID *CommBuffer OPTIONAL, IN OUT UINTN *CommBufferSize OPTIONAL)
Definition: SmmLockBox.c:272
VOID SmmLockBoxRestoreAllInPlace(IN EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE *LockBoxParameterRestoreAllInPlace)
Definition: SmmLockBox.c:243
VOID SmmLockBoxUpdate(IN EFI_SMM_LOCK_BOX_PARAMETER_UPDATE *LockBoxParameterUpdate)
Definition: SmmLockBox.c:136
EFI_STATUS EFIAPI SmmReadyToLockEventNotify(IN CONST EFI_GUID *Protocol, IN VOID *Interface, IN EFI_HANDLE Handle)
Definition: SmmLockBox.c:380
VOID SmmLockBoxSetAttributes(IN EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES *LockBoxParameterSetAttributes)
Definition: SmmLockBox.c:97
VOID SmmLockBoxRestore(IN EFI_SMM_LOCK_BOX_PARAMETER_RESTORE *LockBoxParameterRestore)
Definition: SmmLockBox.c:192
EFI_STATUS EFIAPI SmmLockBoxEntryPoint(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: SmmLockBox.c:401
VOID SmmLockBoxSave(IN EFI_SMM_LOCK_BOX_PARAMETER_SAVE *LockBoxParameterSave)
Definition: SmmLockBox.c:46
BOOLEAN EFIAPI SmmIsBufferOutsideSmmValid(IN EFI_PHYSICAL_ADDRESS Buffer, IN UINT64 Length)
Definition: SmmMemLib.c:114
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
@ EFI_NATIVE_INTERFACE
Definition: UefiSpec.h:1193
Definition: Base.h:213