Hello,

I'd like to ask you for help with understanding Secure Boot policy mechanism, 
specifically DENY_EXECUTE_ON_SECURITY_VIOLATION for 
PcdOptionRomImageVerificationPolicy. The OptionROM in my setup is loaded while, 
in my opinion, it should be rejected.

I'm testing the following scenario: Secure Boot is enabled with my own PK and 
KEK enrolled, but with no db, to make sure nothing unsigned or signed by 
somebody else but me can be executed. A PCIe card with OptionROM (some EBC 
code) is installed. 
gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy  is set to 
0x04 in my platform's package. What I expect, is the OptionROM execution being 
denied, as it is not signed by my certificate. What I observe, on the other 
hand, is a message on the console, that no EBC interpreter is found, which 
suggest, that the  OptionROM is loaded, just fails at the execution of EBC. The 
same message is printed when Secure Boot is disabled.

I tried to understand the code by stepping through it in the DS-5. The 
following part of 
SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c seems 
suspicious to me:

    SecurityStatus = gSecurity->FileAuthenticationState (
                                  gSecurity,
                                  AuthenticationStatus,
                                  OriginalFilePath
                                  );
  }

  //
  // Check Security Status.
  //
  if (EFI_ERROR (SecurityStatus) && SecurityStatus != EFI_SECURITY_VIOLATION) {
    if (SecurityStatus == EFI_ACCESS_DENIED) {
      //
      // Image was not loaded because the platform policy prohibits the image 
from being loaded.
      // It's the only place we could meet EFI_ACCESS_DENIED.
      //
      *ImageHandle = NULL;
    }
    Status = SecurityStatus;
    Image = NULL;
    goto Done;
}

The return code of gSecurity->FileAuthenticationState () (which is implemented 
in MdeModulePkg/Core/Dxe/Image/Image.c:DxeImageVerificationHandler ()), is 
EFI_SECURITY_VIOLATION. Such return code skips this if-statement, that prevents 
the image to be loaded.  According to the comment in the if-statement: for the 
policy to be respected, gSecurity->FileAuthenticationState () should return 
EFI_ACCESS_DENIED.

That being said, I stepped through DxeImageVerificationHandler (). The PCD with 
OptionROM policy is checked correctly. The function handles ALWAYS_EXECUTE and 
NEVER_EXECUTE policies properly and hangs on QUERY_USER_ and 
ALLOW_EXECUTE_ON_SECURITY_VIOLATION.  This seems fine, however there is no code 
handling the DENY_EXECUTE_ON_SECURITY_VIOLATION (0x04) case. Stepping through 
this function shows that the image to be loaded cannot be found in the db 
(correct, as there's no db). Then, the function jumps to its very  end and 
returns EFI_SECURITY_VIOLATION, which skips the aforementioned if-statement:

Done:
  if (Status != EFI_SUCCESS) {
    //
    // Policy decides to defer or reject the image; add its information in 
image executable information table.
    //
    NameStr = ConvertDevicePathToText (File, FALSE, TRUE);
    AddImageExeInfo (Action, NameStr, File, SignatureList, SignatureListSize);
    if (NameStr != NULL) {
      DEBUG((EFI_D_INFO, "The image doesn't pass verification: %s\n", NameStr));
      FreePool(NameStr);
    }
    Status = EFI_SECURITY_VIOLATION;
  }

  if (SignatureList != NULL) {
    FreePool (SignatureList);
  }

  return Status;
}

Is there anything I'm doing wrong trying to prevent untrusted OptionROM 
execution? If my understanding is correct, my case should make 
DxeImageVerificationHandler () return EFI_ACCESS_DENIED here. For example, in 
the snippet above, Status should be set to EFI_ACCESS_DENIED  if Policy == 
DENY_EXECUTE_ON_SECURITY_VIOLATION.

Thank you all for your time,
Wojciech Zmuda

    
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to