public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Laszlo Ersek" <lersek@redhat.com>
To: devel@edk2.groups.io, dovmurik@linux.ibm.com
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>,
	Jordan Justen <jordan.l.justen@intel.com>,
	James Bottomley <jejb@linux.ibm.com>,
	Tobin Feldman-Fitzthum <tobin@linux.ibm.com>
Subject: Re: [edk2-devel] [PATCH v3 4/5] OvmfPkg/GenericQemuLoadImageLib: Read cmdline from QemuKernelLoaderFs
Date: Tue, 29 Jun 2021 11:44:42 +0200	[thread overview]
Message-ID: <a3287946-3b56-9250-7aab-94d5d8f70d82@redhat.com> (raw)
In-Reply-To: <20210628105110.379951-5-dovmurik@linux.ibm.com>

On 06/28/21 12:51, Dov Murik wrote:
> Remove the QemuFwCfgLib interface used to read the QEMU cmdline
> (-append argument) and the initrd size.  Instead, use the synthetic
> filesystem QemuKernelLoaderFs which has three files: "kernel", "initrd",
> and "cmdline".
> 
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: James Bottomley <jejb@linux.ibm.com>
> Cc: Tobin Feldman-Fitzthum <tobin@linux.ibm.com>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3457
> Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
> ---
>  OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.inf |   3 +-
>  OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.c   | 151 ++++++++++++++++++--
>  2 files changed, 139 insertions(+), 15 deletions(-)
> 
> diff --git a/OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.inf b/OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.inf
> index b262cb926a4d..9c9e35b1c5b9 100644
> --- a/OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.inf
> +++ b/OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.inf
> @@ -25,14 +25,15 @@ [Packages]
>  
>  [LibraryClasses]
>    DebugLib
> +  FileHandleLib
>    MemoryAllocationLib
>    PrintLib
> -  QemuFwCfgLib
>    UefiBootServicesTableLib
>  
>  [Protocols]
>    gEfiDevicePathProtocolGuid
>    gEfiLoadedImageProtocolGuid
> +  gEfiSimpleFileSystemProtocolGuid
>  
>  [Guids]
>    gQemuKernelLoaderFsMediaGuid
> diff --git a/OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.c b/OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.c
> index 8a29976ae172..66e029397bd6 100644
> --- a/OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.c
> +++ b/OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.c
> @@ -11,13 +11,14 @@
>  #include <Base.h>
>  #include <Guid/QemuKernelLoaderFsMedia.h>
>  #include <Library/DebugLib.h>
> +#include <Library/FileHandleLib.h>
>  #include <Library/MemoryAllocationLib.h>
>  #include <Library/PrintLib.h>
> -#include <Library/QemuFwCfgLib.h>
>  #include <Library/QemuLoadImageLib.h>
>  #include <Library/UefiBootServicesTableLib.h>
>  #include <Protocol/DevicePath.h>
>  #include <Protocol/LoadedImage.h>
> +#include <Protocol/SimpleFileSystem.h>
>  
>  #pragma pack (1)
>  typedef struct {
> @@ -30,6 +31,11 @@ typedef struct {
>    KERNEL_FILE_DEVPATH       FileNode;
>    EFI_DEVICE_PATH_PROTOCOL  EndNode;
>  } KERNEL_VENMEDIA_FILE_DEVPATH;
> +
> +typedef struct {
> +  VENDOR_DEVICE_PATH       VenMediaNode;
> +  EFI_DEVICE_PATH_PROTOCOL EndNode;
> +} SINGLE_VENMEDIA_NODE_DEVPATH;
>  #pragma pack ()
>  
>  STATIC CONST KERNEL_VENMEDIA_FILE_DEVPATH mKernelDevicePath = {
> @@ -51,6 +57,82 @@ STATIC CONST KERNEL_VENMEDIA_FILE_DEVPATH mKernelDevicePath = {
>    }
>  };
>  
> +STATIC CONST SINGLE_VENMEDIA_NODE_DEVPATH mQemuKernelLoaderFsDevicePath = {
> +  {
> +    {
> +      MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP,
> +      { sizeof (VENDOR_DEVICE_PATH) }
> +    },
> +    QEMU_KERNEL_LOADER_FS_MEDIA_GUID
> +  }, {
> +    END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,
> +    { sizeof (EFI_DEVICE_PATH_PROTOCOL) }
> +  }
> +};
> +
> +STATIC
> +EFI_STATUS
> +GetQemuKernelLoaderBlobSize (
> +  IN  EFI_FILE_HANDLE     Root,
> +  IN  CHAR16              *FileName,
> +  OUT UINTN               *Size
> +  )
> +{
> +  EFI_STATUS      Status;
> +  EFI_FILE_HANDLE FileHandle;
> +  UINT64          FileSize;
> +
> +  Status = Root->Open (Root, &FileHandle, FileName, EFI_FILE_MODE_READ, 0);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  Status = FileHandleGetSize (FileHandle, &FileSize);
> +  if (EFI_ERROR (Status)) {
> +    goto CloseFile;
> +  }
> +  if (FileSize > MAX_UINTN) {
> +    Status = EFI_UNSUPPORTED;
> +    goto CloseFile;
> +  }
> +  *Size = (UINTN)FileSize;
> +  Status = EFI_SUCCESS;
> +CloseFile:
> +  FileHandle->Close (FileHandle);
> +  return Status;
> +}
> +
> +STATIC
> +EFI_STATUS
> +ReadWholeQemuKernelLoaderBlob (
> +  IN  EFI_FILE_HANDLE     Root,
> +  IN  CHAR16              *FileName,
> +  IN  UINTN               Size,
> +  OUT VOID                *Buffer
> +  )
> +{
> +  EFI_STATUS      Status;
> +  EFI_FILE_HANDLE FileHandle;
> +  UINTN           ReadSize;
> +
> +  Status = Root->Open (Root, &FileHandle, FileName, EFI_FILE_MODE_READ, 0);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  ReadSize = Size;
> +  Status = FileHandle->Read (FileHandle, &ReadSize, Buffer);
> +  if (EFI_ERROR (Status)) {
> +    goto CloseFile;
> +  }
> +  if (ReadSize != Size) {
> +    Status = EFI_PROTOCOL_ERROR;
> +    goto CloseFile;
> +  }
> +  Status = EFI_SUCCESS;
> +CloseFile:
> +  FileHandle->Close (FileHandle);
> +  return Status;
> +}
> +
>  /**
>    Download the kernel, the initial ramdisk, and the kernel command line from
>    QEMU's fw_cfg. The kernel will be instructed via its command line to load
> @@ -76,12 +158,16 @@ QemuLoadKernelImage (
>    OUT EFI_HANDLE                  *ImageHandle
>    )
>  {
> -  EFI_STATUS                Status;
> -  EFI_HANDLE                KernelImageHandle;
> -  EFI_LOADED_IMAGE_PROTOCOL *KernelLoadedImage;
> -  UINTN                     CommandLineSize;
> -  CHAR8                     *CommandLine;
> -  UINTN                     InitrdSize;
> +  EFI_STATUS                      Status;
> +  EFI_HANDLE                      KernelImageHandle;
> +  EFI_LOADED_IMAGE_PROTOCOL       *KernelLoadedImage;
> +  EFI_DEVICE_PATH_PROTOCOL        *DevicePathNode;
> +  EFI_HANDLE                      FsVolumeHandle;
> +  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FsProtocol;
> +  EFI_FILE_HANDLE                 Root;
> +  UINTN                           CommandLineSize;
> +  CHAR8                           *CommandLine;
> +  UINTN                           InitrdSize;
>  
>    //
>    // Load the image. This should call back into the QEMU EFI loader file system.
> @@ -124,8 +210,38 @@ QemuLoadKernelImage (
>                    );
>    ASSERT_EFI_ERROR (Status);
>  
> -  QemuFwCfgSelectItem (QemuFwCfgItemCommandLineSize);
> -  CommandLineSize = (UINTN)QemuFwCfgRead32 ();
> +  //
> +  // Open the Qemu Kernel Loader abstract filesystem (volume) which will be
> +  // used to query the "initrd" and to read the "cmdline" synthetic files.
> +  //
> +  DevicePathNode = (EFI_DEVICE_PATH_PROTOCOL *)&mQemuKernelLoaderFsDevicePath;
> +  Status = gBS->LocateDevicePath (
> +                  &gEfiSimpleFileSystemProtocolGuid,
> +                  &DevicePathNode,
> +                  &FsVolumeHandle
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    goto UnloadImage;
> +  }
> +
> +  Status = gBS->HandleProtocol (
> +                  FsVolumeHandle,
> +                  &gEfiSimpleFileSystemProtocolGuid,
> +                  (VOID **)&FsProtocol
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    goto UnloadImage;
> +  }
> +
> +  Status = FsProtocol->OpenVolume (FsVolumeHandle, &Root);
> +  if (EFI_ERROR (Status)) {
> +    goto UnloadImage;
> +  }
> +
> +  Status = GetQemuKernelLoaderBlobSize (Root, L"cmdline", &CommandLineSize);
> +  if (EFI_ERROR (Status)) {
> +    goto CloseRoot;
> +  }
>  
>    if (CommandLineSize == 0) {
>      KernelLoadedImage->LoadOptionsSize = 0;
> @@ -133,11 +249,14 @@ QemuLoadKernelImage (
>      CommandLine = AllocatePool (CommandLineSize);
>      if (CommandLine == NULL) {
>        Status = EFI_OUT_OF_RESOURCES;
> -      goto UnloadImage;
> +      goto CloseRoot;
>      }
>  
> -    QemuFwCfgSelectItem (QemuFwCfgItemCommandLineData);
> -    QemuFwCfgReadBytes (CommandLineSize, CommandLine);
> +    Status = ReadWholeQemuKernelLoaderBlob (Root, L"cmdline", CommandLineSize,
> +               CommandLine);
> +    if (EFI_ERROR (Status)) {
> +      goto FreeCommandLine;
> +    }
>  
>      //
>      // Verify NUL-termination of the command line.
> @@ -155,8 +274,10 @@ QemuLoadKernelImage (
>      KernelLoadedImage->LoadOptionsSize = (UINT32)((CommandLineSize - 1) * 2);
>    }
>  
> -  QemuFwCfgSelectItem (QemuFwCfgItemInitrdSize);
> -  InitrdSize = (UINTN)QemuFwCfgRead32 ();
> +  Status = GetQemuKernelLoaderBlobSize (Root, L"initrd", &InitrdSize);
> +  if (EFI_ERROR (Status)) {
> +    goto FreeCommandLine;
> +  }
>  
>    if (InitrdSize > 0) {
>      //
> @@ -199,6 +320,8 @@ FreeCommandLine:
>    if (CommandLineSize > 0) {
>      FreePool (CommandLine);
>    }
> +CloseRoot:
> +  Root->Close (Root);
>  UnloadImage:
>    if (EFI_ERROR (Status)) {
>      gBS->UnloadImage (KernelImageHandle);
> 

Reviewed-by: Laszlo Ersek <lersek@redhat.com>


  reply	other threads:[~2021-06-29  9:44 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-28 10:51 [PATCH v3 0/5] OvmfPkg: Use QemuKernelLoaderFs to read cmdline/initrd Dov Murik
2021-06-28 10:51 ` [PATCH v3 1/5] OvmfPkg/GenericQemuLoadImageLib: plug cmdline blob leak on success Dov Murik
2021-06-29  9:27   ` [edk2-devel] " Laszlo Ersek
2021-06-29 10:23   ` Laszlo Ersek
2021-06-28 10:51 ` [PATCH v3 2/5] OvmfPkg/X86QemuLoadImageLib: " Dov Murik
2021-06-29  9:31   ` [edk2-devel] " Laszlo Ersek
2021-06-29 11:18   ` Laszlo Ersek
2021-06-28 10:51 ` [PATCH v3 3/5] Revert "OvmfPkg/QemuKernelLoaderFsDxe: don't expose kernel command line" Dov Murik
2021-06-29  9:32   ` [edk2-devel] " Laszlo Ersek
2021-06-29 10:23   ` Laszlo Ersek
2021-06-28 10:51 ` [PATCH v3 4/5] OvmfPkg/GenericQemuLoadImageLib: Read cmdline from QemuKernelLoaderFs Dov Murik
2021-06-29  9:44   ` Laszlo Ersek [this message]
2021-06-29 10:23   ` [edk2-devel] " Laszlo Ersek
2021-06-28 10:51 ` [PATCH v3 5/5] OvmfPkg/X86QemuLoadImageLib: State fw_cfg dependency in file header Dov Murik
2021-06-29  9:45   ` [edk2-devel] " Laszlo Ersek
2021-06-29 12:54 ` [edk2-devel] [PATCH v3 0/5] OvmfPkg: Use QemuKernelLoaderFs to read cmdline/initrd Laszlo Ersek
2021-06-29 13:03   ` Dov Murik
2021-06-29 13:30     ` 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=a3287946-3b56-9250-7aab-94d5d8f70d82@redhat.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