4 Caution: This module requires additional review when modified.
5 This driver will have external input - communicate buffer in SMM mode.
6 This external input must be validated carefully to avoid security issue like
7 buffer overflow, integer overflow.
9 SmmLockBoxHandler(), SmmLockBoxRestore(), SmmLockBoxUpdate(), SmmLockBoxSave()
10 will receive untrusted input and do basic validation.
12 Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
14 This program and the accompanying materials
15 are licensed and made available under the terms and conditions
16 of the BSD License which accompanies this distribution. The
17 full text of the license may be found at
18 http://opensource.org/licenses/bsd-license.php
20 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
21 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
26 #include <Library/UefiDriverEntryPoint.h>
27 #include <Library/UefiBootServicesTableLib.h>
28 #include <Library/UefiRuntimeServicesTableLib.h>
29 #include <Library/SmmServicesTableLib.h>
30 #include <Library/BaseLib.h>
31 #include <Library/BaseMemoryLib.h>
32 #include <Library/DebugLib.h>
33 #include <Library/SmmMemLib.h>
34 #include <Library/LockBoxLib.h>
36 #include <Protocol/SmmReadyToLock.h>
37 #include <Protocol/SmmCommunication.h>
38 #include <Protocol/LockBox.h>
39 #include <Guid/SmmLockBox.h>
41 BOOLEAN mLocked
= FALSE
;
44 Dispatch function for SMM lock box save.
46 Caution: This function may receive untrusted input.
47 Restore buffer and length are external input, so this function will validate
50 @param LockBoxParameterSave parameter of lock box save
54 IN EFI_SMM_LOCK_BOX_PARAMETER_SAVE
*LockBoxParameterSave
58 EFI_SMM_LOCK_BOX_PARAMETER_SAVE TempLockBoxParameterSave
;
64 DEBUG ((EFI_D_ERROR
, "SmmLockBox Locked!\n"));
65 LockBoxParameterSave
->Header
.ReturnStatus
= (UINT64
)EFI_ACCESS_DENIED
;
69 CopyMem (&TempLockBoxParameterSave
, LockBoxParameterSave
, sizeof (EFI_SMM_LOCK_BOX_PARAMETER_SAVE
));
74 if (!SmmIsBufferOutsideSmmValid ((UINTN
)TempLockBoxParameterSave
.Buffer
, (UINTN
)TempLockBoxParameterSave
.Length
)) {
75 DEBUG ((EFI_D_ERROR
, "SmmLockBox Save address in SMRAM or buffer overflow!\n"));
76 LockBoxParameterSave
->Header
.ReturnStatus
= (UINT64
)EFI_ACCESS_DENIED
;
83 Status
= SaveLockBox (
84 &TempLockBoxParameterSave
.Guid
,
85 (VOID
*)(UINTN
)TempLockBoxParameterSave
.Buffer
,
86 (UINTN
)TempLockBoxParameterSave
.Length
88 LockBoxParameterSave
->Header
.ReturnStatus
= (UINT64
)Status
;
93 Dispatch function for SMM lock box set attributes.
95 @param LockBoxParameterSetAttributes parameter of lock box set attributes
98 SmmLockBoxSetAttributes (
99 IN EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES
*LockBoxParameterSetAttributes
103 EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES TempLockBoxParameterSetAttributes
;
109 DEBUG ((EFI_D_ERROR
, "SmmLockBox Locked!\n"));
110 LockBoxParameterSetAttributes
->Header
.ReturnStatus
= (UINT64
)EFI_ACCESS_DENIED
;
114 CopyMem (&TempLockBoxParameterSetAttributes
, LockBoxParameterSetAttributes
, sizeof (EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES
));
119 Status
= SetLockBoxAttributes (
120 &TempLockBoxParameterSetAttributes
.Guid
,
121 TempLockBoxParameterSetAttributes
.Attributes
123 LockBoxParameterSetAttributes
->Header
.ReturnStatus
= (UINT64
)Status
;
128 Dispatch function for SMM lock box update.
130 Caution: This function may receive untrusted input.
131 Restore buffer and length are external input, so this function will validate
134 @param LockBoxParameterUpdate parameter of lock box update
138 IN EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
*LockBoxParameterUpdate
142 EFI_SMM_LOCK_BOX_PARAMETER_UPDATE TempLockBoxParameterUpdate
;
148 DEBUG ((EFI_D_ERROR
, "SmmLockBox Locked!\n"));
149 LockBoxParameterUpdate
->Header
.ReturnStatus
= (UINT64
)EFI_ACCESS_DENIED
;
153 CopyMem (&TempLockBoxParameterUpdate
, LockBoxParameterUpdate
, sizeof (EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
));
158 if (!SmmIsBufferOutsideSmmValid ((UINTN
)TempLockBoxParameterUpdate
.Buffer
, (UINTN
)TempLockBoxParameterUpdate
.Length
)) {
159 DEBUG ((EFI_D_ERROR
, "SmmLockBox Update address in SMRAM or buffer overflow!\n"));
160 LockBoxParameterUpdate
->Header
.ReturnStatus
= (UINT64
)EFI_ACCESS_DENIED
;
167 Status
= UpdateLockBox (
168 &TempLockBoxParameterUpdate
.Guid
,
169 (UINTN
)TempLockBoxParameterUpdate
.Offset
,
170 (VOID
*)(UINTN
)TempLockBoxParameterUpdate
.Buffer
,
171 (UINTN
)TempLockBoxParameterUpdate
.Length
173 LockBoxParameterUpdate
->Header
.ReturnStatus
= (UINT64
)Status
;
178 Dispatch function for SMM lock box restore.
180 Caution: This function may receive untrusted input.
181 Restore buffer and length are external input, so this function will validate
184 @param LockBoxParameterRestore parameter of lock box restore
188 IN EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
*LockBoxParameterRestore
192 EFI_SMM_LOCK_BOX_PARAMETER_RESTORE TempLockBoxParameterRestore
;
194 CopyMem (&TempLockBoxParameterRestore
, LockBoxParameterRestore
, sizeof (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
));
199 if (!SmmIsBufferOutsideSmmValid ((UINTN
)TempLockBoxParameterRestore
.Buffer
, (UINTN
)TempLockBoxParameterRestore
.Length
)) {
200 DEBUG ((EFI_D_ERROR
, "SmmLockBox Restore address in SMRAM or buffer overflow!\n"));
201 LockBoxParameterRestore
->Header
.ReturnStatus
= (UINT64
)EFI_ACCESS_DENIED
;
208 if ((TempLockBoxParameterRestore
.Length
== 0) && (TempLockBoxParameterRestore
.Buffer
== 0)) {
209 Status
= RestoreLockBox (
210 &TempLockBoxParameterRestore
.Guid
,
215 Status
= RestoreLockBox (
216 &TempLockBoxParameterRestore
.Guid
,
217 (VOID
*)(UINTN
)TempLockBoxParameterRestore
.Buffer
,
218 (UINTN
*)&TempLockBoxParameterRestore
.Length
220 if (Status
== EFI_BUFFER_TOO_SMALL
) {
221 LockBoxParameterRestore
->Length
= TempLockBoxParameterRestore
.Length
;
224 LockBoxParameterRestore
->Header
.ReturnStatus
= (UINT64
)Status
;
229 Dispatch function for SMM lock box restore all in place.
231 @param LockBoxParameterRestoreAllInPlace parameter of lock box restore all in place
234 SmmLockBoxRestoreAllInPlace (
235 IN EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE
*LockBoxParameterRestoreAllInPlace
240 Status
= RestoreAllLockBoxInPlace ();
241 LockBoxParameterRestoreAllInPlace
->Header
.ReturnStatus
= (UINT64
)Status
;
246 Dispatch function for a Software SMI handler.
248 Caution: This function may receive untrusted input.
249 Communicate buffer and buffer size are external input, so this function will do basic validation.
251 @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
252 @param Context Points to an optional handler context which was specified when the
253 handler was registered.
254 @param CommBuffer A pointer to a collection of data in memory that will
255 be conveyed from a non-SMM environment into an SMM environment.
256 @param CommBufferSize The size of the CommBuffer.
258 @retval EFI_SUCCESS Command is handled successfully.
264 IN EFI_HANDLE DispatchHandle
,
265 IN CONST VOID
*Context OPTIONAL
,
266 IN OUT VOID
*CommBuffer OPTIONAL
,
267 IN OUT UINTN
*CommBufferSize OPTIONAL
270 EFI_SMM_LOCK_BOX_PARAMETER_HEADER
*LockBoxParameterHeader
;
271 UINTN TempCommBufferSize
;
273 DEBUG ((DEBUG_INFO
, "SmmLockBox SmmLockBoxHandler Enter\n"));
276 // If input is invalid, stop processing this SMI
278 if (CommBuffer
== NULL
|| CommBufferSize
== NULL
) {
282 TempCommBufferSize
= *CommBufferSize
;
287 if (TempCommBufferSize
< sizeof(EFI_SMM_LOCK_BOX_PARAMETER_HEADER
)) {
288 DEBUG ((EFI_D_ERROR
, "SmmLockBox Command Buffer Size invalid!\n"));
291 if (!SmmIsBufferOutsideSmmValid ((UINTN
)CommBuffer
, TempCommBufferSize
)) {
292 DEBUG ((EFI_D_ERROR
, "SmmLockBox Command Buffer in SMRAM or overflow!\n"));
296 LockBoxParameterHeader
= (EFI_SMM_LOCK_BOX_PARAMETER_HEADER
*)((UINTN
)CommBuffer
);
298 LockBoxParameterHeader
->ReturnStatus
= (UINT64
)-1;
300 DEBUG ((DEBUG_INFO
, "SmmLockBox LockBoxParameterHeader - %x\n", (UINTN
)LockBoxParameterHeader
));
302 DEBUG ((DEBUG_INFO
, "SmmLockBox Command - %x\n", (UINTN
)LockBoxParameterHeader
->Command
));
304 switch (LockBoxParameterHeader
->Command
) {
305 case EFI_SMM_LOCK_BOX_COMMAND_SAVE
:
306 if (TempCommBufferSize
< sizeof(EFI_SMM_LOCK_BOX_PARAMETER_SAVE
)) {
307 DEBUG ((EFI_D_ERROR
, "SmmLockBox Command Buffer Size for SAVE invalid!\n"));
310 SmmLockBoxSave ((EFI_SMM_LOCK_BOX_PARAMETER_SAVE
*)(UINTN
)LockBoxParameterHeader
);
312 case EFI_SMM_LOCK_BOX_COMMAND_UPDATE
:
313 if (TempCommBufferSize
< sizeof(EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
)) {
314 DEBUG ((EFI_D_ERROR
, "SmmLockBox Command Buffer Size for UPDATE invalid!\n"));
317 SmmLockBoxUpdate ((EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
*)(UINTN
)LockBoxParameterHeader
);
319 case EFI_SMM_LOCK_BOX_COMMAND_RESTORE
:
320 if (TempCommBufferSize
< sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
)) {
321 DEBUG ((EFI_D_ERROR
, "SmmLockBox Command Buffer Size for RESTORE invalid!\n"));
324 SmmLockBoxRestore ((EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
*)(UINTN
)LockBoxParameterHeader
);
326 case EFI_SMM_LOCK_BOX_COMMAND_SET_ATTRIBUTES
:
327 if (TempCommBufferSize
< sizeof(EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES
)) {
328 DEBUG ((EFI_D_ERROR
, "SmmLockBox Command Buffer Size for SET_ATTRIBUTES invalid!\n"));
331 SmmLockBoxSetAttributes ((EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES
*)(UINTN
)LockBoxParameterHeader
);
333 case EFI_SMM_LOCK_BOX_COMMAND_RESTORE_ALL_IN_PLACE
:
334 if (TempCommBufferSize
< sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE
)) {
335 DEBUG ((EFI_D_ERROR
, "SmmLockBox Command Buffer Size for RESTORE_ALL_IN_PLACE invalid!\n"));
338 SmmLockBoxRestoreAllInPlace ((EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE
*)(UINTN
)LockBoxParameterHeader
);
341 DEBUG ((EFI_D_ERROR
, "SmmLockBox Command invalid!\n"));
345 LockBoxParameterHeader
->Command
= (UINT32
)-1;
347 DEBUG ((DEBUG_INFO
, "SmmLockBox SmmLockBoxHandler Exit\n"));
353 Smm Ready To Lock event notification handler.
355 It sets a flag indicating that SMRAM has been locked.
357 @param[in] Protocol Points to the protocol's unique identifier.
358 @param[in] Interface Points to the interface instance.
359 @param[in] Handle The handle on which the interface was installed.
361 @retval EFI_SUCCESS Notification handler runs successfully.
365 SmmReadyToLockEventNotify (
366 IN CONST EFI_GUID
*Protocol
,
376 Entry Point for LockBox SMM driver.
378 @param[in] ImageHandle Image handle of this driver.
379 @param[in] SystemTable A Pointer to the EFI System Table.
382 @return Others Some error occurs.
386 SmmLockBoxEntryPoint (
387 IN EFI_HANDLE ImageHandle
,
388 IN EFI_SYSTEM_TABLE
*SystemTable
392 EFI_HANDLE DispatchHandle
;
396 // Register LockBox communication handler
398 Status
= gSmst
->SmiHandlerRegister (
400 &gEfiSmmLockBoxCommunicationGuid
,
403 ASSERT_EFI_ERROR (Status
);
406 // Register SMM Ready To Lock Protocol notification
408 Status
= gSmst
->SmmRegisterProtocolNotify (
409 &gEfiSmmReadyToLockProtocolGuid
,
410 SmmReadyToLockEventNotify
,
413 ASSERT_EFI_ERROR (Status
);
416 // Install NULL to DXE data base as notify
419 Status
= gBS
->InstallProtocolInterface (
421 &gEfiLockBoxProtocolGuid
,
422 EFI_NATIVE_INTERFACE
,
425 ASSERT_EFI_ERROR (Status
);