]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg/SerializeVariablesLib: ignore secure variable restore errors
authorjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 28 May 2013 17:21:37 +0000 (17:21 +0000)
committerjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 28 May 2013 17:21:37 +0000 (17:21 +0000)
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

OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.c

index 112f20e052f1772b90bd6d383c094881082e8c38..19569b2ae0eac711f82a94795f4ed2c28b712143 100644 (file)
@@ -284,13 +284,26 @@ IterateVariablesCallbackSetSystemVariable (
   IN  VOID                         *Data
   )
 {
-  return gRT->SetVariable (
-           VariableName,
-           VendorGuid,
-           Attributes,
-           DataSize,
-           Data
-           );
+  EFI_STATUS          Status;\r
+  STATIC CONST UINT32 AuthMask =\r
+                        EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS |\r
+                        EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;\r
+\r
+  Status = gRT->SetVariable (\r
+             VariableName,\r
+             VendorGuid,\r
+             Attributes,\r
+             DataSize,\r
+             Data\r
+             );\r
+\r
+  if (Status == EFI_SECURITY_VIOLATION && (Attributes & AuthMask) != 0) {\r
+    DEBUG ((DEBUG_WARN, "%a: setting authenticated variable \"%s\" "\r
+            "failed with EFI_SECURITY_VIOLATION, ignoring\n", __FUNCTION__,\r
+            VariableName));\r
+    Status = EFI_SUCCESS;\r
+  }\r
+  return Status;\r
 }