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 - 2015, 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/SmmAccess2.h>
39 #include <Protocol/LockBox.h>
40 #include <Guid/SmmLockBox.h>
42 BOOLEAN mLocked
= FALSE
;
45 Dispatch function for SMM lock box save.
47 Caution: This function may receive untrusted input.
48 Restore buffer and length are external input, so this function will validate
51 @param LockBoxParameterSave parameter of lock box save
55 IN EFI_SMM_LOCK_BOX_PARAMETER_SAVE
*LockBoxParameterSave
59 EFI_SMM_LOCK_BOX_PARAMETER_SAVE TempLockBoxParameterSave
;
65 DEBUG ((EFI_D_ERROR
, "SmmLockBox Locked!\n"));
66 LockBoxParameterSave
->Header
.ReturnStatus
= (UINT64
)EFI_ACCESS_DENIED
;
70 CopyMem (&TempLockBoxParameterSave
, LockBoxParameterSave
, sizeof (EFI_SMM_LOCK_BOX_PARAMETER_SAVE
));
75 if (!SmmIsBufferOutsideSmmValid ((UINTN
)TempLockBoxParameterSave
.Buffer
, (UINTN
)TempLockBoxParameterSave
.Length
)) {
76 DEBUG ((EFI_D_ERROR
, "SmmLockBox Save address in SMRAM or buffer overflow!\n"));
77 LockBoxParameterSave
->Header
.ReturnStatus
= (UINT64
)EFI_ACCESS_DENIED
;
84 Status
= SaveLockBox (
85 &TempLockBoxParameterSave
.Guid
,
86 (VOID
*)(UINTN
)TempLockBoxParameterSave
.Buffer
,
87 (UINTN
)TempLockBoxParameterSave
.Length
89 LockBoxParameterSave
->Header
.ReturnStatus
= (UINT64
)Status
;
94 Dispatch function for SMM lock box set attributes.
96 @param LockBoxParameterSetAttributes parameter of lock box set attributes
99 SmmLockBoxSetAttributes (
100 IN EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES
*LockBoxParameterSetAttributes
104 EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES TempLockBoxParameterSetAttributes
;
110 DEBUG ((EFI_D_ERROR
, "SmmLockBox Locked!\n"));
111 LockBoxParameterSetAttributes
->Header
.ReturnStatus
= (UINT64
)EFI_ACCESS_DENIED
;
115 CopyMem (&TempLockBoxParameterSetAttributes
, LockBoxParameterSetAttributes
, sizeof (EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES
));
120 Status
= SetLockBoxAttributes (
121 &TempLockBoxParameterSetAttributes
.Guid
,
122 TempLockBoxParameterSetAttributes
.Attributes
124 LockBoxParameterSetAttributes
->Header
.ReturnStatus
= (UINT64
)Status
;
129 Dispatch function for SMM lock box update.
131 Caution: This function may receive untrusted input.
132 Restore buffer and length are external input, so this function will validate
135 @param LockBoxParameterUpdate parameter of lock box update
139 IN EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
*LockBoxParameterUpdate
143 EFI_SMM_LOCK_BOX_PARAMETER_UPDATE TempLockBoxParameterUpdate
;
149 DEBUG ((EFI_D_ERROR
, "SmmLockBox Locked!\n"));
150 LockBoxParameterUpdate
->Header
.ReturnStatus
= (UINT64
)EFI_ACCESS_DENIED
;
154 CopyMem (&TempLockBoxParameterUpdate
, LockBoxParameterUpdate
, sizeof (EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
));
159 if (!SmmIsBufferOutsideSmmValid ((UINTN
)TempLockBoxParameterUpdate
.Buffer
, (UINTN
)TempLockBoxParameterUpdate
.Length
)) {
160 DEBUG ((EFI_D_ERROR
, "SmmLockBox Update address in SMRAM or buffer overflow!\n"));
161 LockBoxParameterUpdate
->Header
.ReturnStatus
= (UINT64
)EFI_ACCESS_DENIED
;
168 Status
= UpdateLockBox (
169 &TempLockBoxParameterUpdate
.Guid
,
170 (UINTN
)TempLockBoxParameterUpdate
.Offset
,
171 (VOID
*)(UINTN
)TempLockBoxParameterUpdate
.Buffer
,
172 (UINTN
)TempLockBoxParameterUpdate
.Length
174 LockBoxParameterUpdate
->Header
.ReturnStatus
= (UINT64
)Status
;
179 Dispatch function for SMM lock box restore.
181 Caution: This function may receive untrusted input.
182 Restore buffer and length are external input, so this function will validate
185 @param LockBoxParameterRestore parameter of lock box restore
189 IN EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
*LockBoxParameterRestore
193 EFI_SMM_LOCK_BOX_PARAMETER_RESTORE TempLockBoxParameterRestore
;
195 CopyMem (&TempLockBoxParameterRestore
, LockBoxParameterRestore
, sizeof (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
));
200 if (!SmmIsBufferOutsideSmmValid ((UINTN
)TempLockBoxParameterRestore
.Buffer
, (UINTN
)TempLockBoxParameterRestore
.Length
)) {
201 DEBUG ((EFI_D_ERROR
, "SmmLockBox Restore address in SMRAM or buffer overflow!\n"));
202 LockBoxParameterRestore
->Header
.ReturnStatus
= (UINT64
)EFI_ACCESS_DENIED
;
209 if ((TempLockBoxParameterRestore
.Length
== 0) && (TempLockBoxParameterRestore
.Buffer
== 0)) {
210 Status
= RestoreLockBox (
211 &TempLockBoxParameterRestore
.Guid
,
216 Status
= RestoreLockBox (
217 &TempLockBoxParameterRestore
.Guid
,
218 (VOID
*)(UINTN
)TempLockBoxParameterRestore
.Buffer
,
219 (UINTN
*)&TempLockBoxParameterRestore
.Length
222 LockBoxParameterRestore
->Header
.ReturnStatus
= (UINT64
)Status
;
227 Dispatch function for SMM lock box restore all in place.
229 @param LockBoxParameterRestoreAllInPlace parameter of lock box restore all in place
232 SmmLockBoxRestoreAllInPlace (
233 IN EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE
*LockBoxParameterRestoreAllInPlace
238 Status
= RestoreAllLockBoxInPlace ();
239 LockBoxParameterRestoreAllInPlace
->Header
.ReturnStatus
= (UINT64
)Status
;
244 Dispatch function for a Software SMI handler.
246 Caution: This function may receive untrusted input.
247 Communicate buffer and buffer size are external input, so this function will do basic validation.
249 @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
250 @param Context Points to an optional handler context which was specified when the
251 handler was registered.
252 @param CommBuffer A pointer to a collection of data in memory that will
253 be conveyed from a non-SMM environment into an SMM environment.
254 @param CommBufferSize The size of the CommBuffer.
256 @retval EFI_SUCCESS Command is handled successfully.
262 IN EFI_HANDLE DispatchHandle
,
263 IN CONST VOID
*Context OPTIONAL
,
264 IN OUT VOID
*CommBuffer OPTIONAL
,
265 IN OUT UINTN
*CommBufferSize OPTIONAL
268 EFI_SMM_LOCK_BOX_PARAMETER_HEADER
*LockBoxParameterHeader
;
269 UINTN TempCommBufferSize
;
271 DEBUG ((EFI_D_ERROR
, "SmmLockBox SmmLockBoxHandler Enter\n"));
274 // If input is invalid, stop processing this SMI
276 if (CommBuffer
== NULL
|| CommBufferSize
== NULL
) {
280 TempCommBufferSize
= *CommBufferSize
;
285 if (TempCommBufferSize
< sizeof(EFI_SMM_LOCK_BOX_PARAMETER_HEADER
)) {
286 DEBUG ((EFI_D_ERROR
, "SmmLockBox Command Buffer Size invalid!\n"));
289 if (!SmmIsBufferOutsideSmmValid ((UINTN
)CommBuffer
, TempCommBufferSize
)) {
290 DEBUG ((EFI_D_ERROR
, "SmmLockBox Command Buffer in SMRAM or overflow!\n"));
294 LockBoxParameterHeader
= (EFI_SMM_LOCK_BOX_PARAMETER_HEADER
*)((UINTN
)CommBuffer
);
296 LockBoxParameterHeader
->ReturnStatus
= (UINT64
)-1;
298 DEBUG ((EFI_D_ERROR
, "SmmLockBox LockBoxParameterHeader - %x\n", (UINTN
)LockBoxParameterHeader
));
300 DEBUG ((EFI_D_ERROR
, "SmmLockBox Command - %x\n", (UINTN
)LockBoxParameterHeader
->Command
));
302 switch (LockBoxParameterHeader
->Command
) {
303 case EFI_SMM_LOCK_BOX_COMMAND_SAVE
:
304 if (TempCommBufferSize
< sizeof(EFI_SMM_LOCK_BOX_PARAMETER_SAVE
)) {
305 DEBUG ((EFI_D_ERROR
, "SmmLockBox Command Buffer Size for SAVE invalid!\n"));
308 SmmLockBoxSave ((EFI_SMM_LOCK_BOX_PARAMETER_SAVE
*)(UINTN
)LockBoxParameterHeader
);
310 case EFI_SMM_LOCK_BOX_COMMAND_UPDATE
:
311 if (TempCommBufferSize
< sizeof(EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
)) {
312 DEBUG ((EFI_D_ERROR
, "SmmLockBox Command Buffer Size for UPDATE invalid!\n"));
315 SmmLockBoxUpdate ((EFI_SMM_LOCK_BOX_PARAMETER_UPDATE
*)(UINTN
)LockBoxParameterHeader
);
317 case EFI_SMM_LOCK_BOX_COMMAND_RESTORE
:
318 if (TempCommBufferSize
< sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
)) {
319 DEBUG ((EFI_D_ERROR
, "SmmLockBox Command Buffer Size for RESTORE invalid!\n"));
322 SmmLockBoxRestore ((EFI_SMM_LOCK_BOX_PARAMETER_RESTORE
*)(UINTN
)LockBoxParameterHeader
);
324 case EFI_SMM_LOCK_BOX_COMMAND_SET_ATTRIBUTES
:
325 if (TempCommBufferSize
< sizeof(EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES
)) {
326 DEBUG ((EFI_D_ERROR
, "SmmLockBox Command Buffer Size for SET_ATTRIBUTES invalid!\n"));
329 SmmLockBoxSetAttributes ((EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES
*)(UINTN
)LockBoxParameterHeader
);
331 case EFI_SMM_LOCK_BOX_COMMAND_RESTORE_ALL_IN_PLACE
:
332 if (TempCommBufferSize
< sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE
)) {
333 DEBUG ((EFI_D_ERROR
, "SmmLockBox Command Buffer Size for RESTORE_ALL_IN_PLACE invalid!\n"));
336 SmmLockBoxRestoreAllInPlace ((EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE
*)(UINTN
)LockBoxParameterHeader
);
339 DEBUG ((EFI_D_ERROR
, "SmmLockBox Command invalid!\n"));
343 LockBoxParameterHeader
->Command
= (UINT32
)-1;
345 DEBUG ((EFI_D_ERROR
, "SmmLockBox SmmLockBoxHandler Exit\n"));
351 Smm Ready To Lock event notification handler.
353 It sets a flag indicating that SMRAM has been locked.
355 @param[in] Protocol Points to the protocol's unique identifier.
356 @param[in] Interface Points to the interface instance.
357 @param[in] Handle The handle on which the interface was installed.
359 @retval EFI_SUCCESS Notification handler runs successfully.
363 SmmReadyToLockEventNotify (
364 IN CONST EFI_GUID
*Protocol
,
374 Entry Point for LockBox SMM driver.
376 @param[in] ImageHandle Image handle of this driver.
377 @param[in] SystemTable A Pointer to the EFI System Table.
380 @return Others Some error occurs.
384 SmmLockBoxEntryPoint (
385 IN EFI_HANDLE ImageHandle
,
386 IN EFI_SYSTEM_TABLE
*SystemTable
390 EFI_HANDLE DispatchHandle
;
394 // Register LockBox communication handler
396 Status
= gSmst
->SmiHandlerRegister (
398 &gEfiSmmLockBoxCommunicationGuid
,
401 ASSERT_EFI_ERROR (Status
);
404 // Register SMM Ready To Lock Protocol notification
406 Status
= gSmst
->SmmRegisterProtocolNotify (
407 &gEfiSmmReadyToLockProtocolGuid
,
408 SmmReadyToLockEventNotify
,
411 ASSERT_EFI_ERROR (Status
);
414 // Install NULL to DXE data base as notify
417 Status
= gBS
->InstallProtocolInterface (
419 &gEfiLockBoxProtocolGuid
,
420 EFI_NATIVE_INTERFACE
,
423 ASSERT_EFI_ERROR (Status
);