diff options
author | jljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524> | 2013-05-28 17:21:37 +0000 |
---|---|---|
committer | jljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524> | 2013-05-28 17:21:37 +0000 |
commit | e678f9db899adbc986e68b5e400f465c00529121 (patch) | |
tree | 2a91466e00a41e4ae5153098e17c43bbacd0552c /OvmfPkg | |
parent | 61f1b7c51e77b71c0101d4af172aee1d08a1096c (diff) | |
download | edk2-e678f9db899adbc986e68b5e400f465c00529121.zip edk2-e678f9db899adbc986e68b5e400f465c00529121.tar.gz edk2-e678f9db899adbc986e68b5e400f465c00529121.tar.bz2 |
OvmfPkg/SerializeVariablesLib: ignore secure variable restore errors
OvmfPkg's file-based NvVar storage is read back as follows at boot (all
paths under OvmfPkg/Library/):
PlatformBdsPolicyBehavior() [PlatformBdsLib/BdsPlatform.c]
PlatformBdsRestoreNvVarsFromHardDisk()
VisitAllInstancesOfProtocol
for each simple file system:
VisitingFileSystemInstance()
ConnectNvVarsToFileSystem() [NvVarsFileLib/NvVarsFileLib.c]
LoadNvVarsFromFs() [NvVarsFileLib/FsAccess.c]
ReadNvVarsFile()
+-------------> SerializeVariablesSetSerializedVariables() [SerializeVariablesLib/SerializeVariablesLib.c]
| SerializeVariablesIterateInstanceVariables()
| +-------------> IterateVariablesInBuffer()
| | for each loaded / deserialized variable:
| +-|-----------------> IterateVariablesCallbackSetSystemVariable()
| | | gRT->SetVariable()
| | |
| | IterateVariablesInBuffer() stops processing variables as soon as the
| | first error is encountered from the callback function.
| |
| | In this case the callback function is
| IterateVariablesCallbackSetSystemVariable(), selected by
SerializeVariablesSetSerializedVariables().
The result is that no NvVar is restored from the file after the first
gRT->SetVariable() failure.
On my system such a failure
- never happens in an OVMF build with secure boot disabled,
- happens *immediately* with SECURE_BOOT_ENABLE, because the first
variable to restore is "AuthVarKeyDatabase".
"AuthVarKeyDatabase" has the EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
attribute set. Since the loop tries to restore it before any keys (PK, KEK
etc) are enrolled, gRT->SetVariable() rejects it with
EFI_SECURITY_VIOLATION. Consequently the NvVar restore loop terminates
immediately, and we never reach non-authenticated variables such as
Boot#### and BootOrder.
Until work on KVM-compatible flash emulation converges between qemu and
OvmfPkg, improve the SECURE_BOOT_ENABLE boot experience by masking
EFI_SECURITY_VIOLATION in the callback:
- authenticated variables continue to be rejected same as before, but
- at least we allow the loop to progress and restore non-authenticated
variables, for example boot options.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14390 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'OvmfPkg')
-rw-r--r-- | OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.c | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.c b/OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.c index 112f20e..19569b2 100644 --- a/OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.c +++ b/OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.c @@ -284,13 +284,26 @@ IterateVariablesCallbackSetSystemVariable ( IN VOID *Data ) { - return gRT->SetVariable ( - VariableName, - VendorGuid, - Attributes, - DataSize, - Data - ); + EFI_STATUS Status;
+ STATIC CONST UINT32 AuthMask =
+ EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS |
+ EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
+
+ Status = gRT->SetVariable (
+ VariableName,
+ VendorGuid,
+ Attributes,
+ DataSize,
+ Data
+ );
+
+ if (Status == EFI_SECURITY_VIOLATION && (Attributes & AuthMask) != 0) {
+ DEBUG ((DEBUG_WARN, "%a: setting authenticated variable \"%s\" "
+ "failed with EFI_SECURITY_VIOLATION, ignoring\n", __FUNCTION__,
+ VariableName));
+ Status = EFI_SUCCESS;
+ }
+ return Status;
} |