public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Zmuda, Wojciech" <Wojciech.Zmuda@cavium.com>
To: "edk2-devel@lists.01.org" <edk2-devel@lists.01.org>
Subject: SecurityPkg: untrusted OptionRom is loaded despite DENY_EXECUTE_ON_SECURITY_VIOLATION set.
Date: Mon, 16 Oct 2017 16:57:53 +0000	[thread overview]
Message-ID: <CY1PR0701MB1852B97D14ECE74CCA23F08CEF4F0@CY1PR0701MB1852.namprd07.prod.outlook.com> (raw)
In-Reply-To: <CY1PR0701MB185234B24E2441C917CB087EEF4F0@CY1PR0701MB1852.namprd07.prod.outlook.com>

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

    

       reply	other threads:[~2017-10-16 16:54 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CY1PR0701MB185234B24E2441C917CB087EEF4F0@CY1PR0701MB1852.namprd07.prod.outlook.com>
2017-10-16 16:57 ` Zmuda, Wojciech [this message]
2017-10-16 18:11   ` SecurityPkg: untrusted OptionRom is loaded despite DENY_EXECUTE_ON_SECURITY_VIOLATION set Laszlo Ersek
2017-10-17 19:07     ` Zmuda, Wojciech
2017-10-17 19:22       ` Laszlo Ersek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CY1PR0701MB1852B97D14ECE74CCA23F08CEF4F0@CY1PR0701MB1852.namprd07.prod.outlook.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox