/** @file
  Recovery module.

  Caution: This module requires additional review when modified.
  This module will have external input - Capsule-on-Disk Temp Relocation image.
  This external input must be validated carefully to avoid security issue like
  buffer overflow, integer overflow.

  RetrieveRelocatedCapsule() will receive untrusted input and do basic validation.

  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

//
// The package level header files this module uses
//
#include <Uefi.h>
#include <PiPei.h>

//
// The protocols, PPI and GUID defintions for this module
//
#include <Ppi/MasterBootMode.h>
#include <Ppi/FirmwareVolumeInfo.h>
#include <Ppi/ReadOnlyVariable2.h>
#include <Ppi/Capsule.h>
#include <Ppi/CapsuleOnDisk.h>
#include <Ppi/DeviceRecoveryModule.h>

#include <Guid/FirmwareFileSystem2.h>
//
// The Library classes this module consumes
//
#include <Library/DebugLib.h>
#include <Library/PeimEntryPoint.h>
#include <Library/PeiServicesLib.h>
#include <Library/HobLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
#include <Library/CapsuleLib.h>
#include <Library/ReportStatusCodeLib.h>

/**
  Loads a DXE capsule from some media into memory and updates the HOB table
  with the DXE firmware volume information.

  @param[in]  PeiServices   General-purpose services that are available to every PEIM.
  @param[in]  This          Indicates the EFI_PEI_RECOVERY_MODULE_PPI instance.

  @retval EFI_SUCCESS        The capsule was loaded correctly.
  @retval EFI_DEVICE_ERROR   A device error occurred.
  @retval EFI_NOT_FOUND      A recovery DXE capsule cannot be found.

**/
EFI_STATUS
EFIAPI
LoadCapsuleOnDisk (
  IN EFI_PEI_SERVICES               **PeiServices,
  IN EDKII_PEI_CAPSULE_ON_DISK_PPI  *This
  );

static EDKII_PEI_CAPSULE_ON_DISK_PPI  mCapsuleOnDiskPpi = {
  LoadCapsuleOnDisk
};

static EFI_PEI_PPI_DESCRIPTOR  mCapsuleOnDiskPpiList = {
  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
  &gEdkiiPeiCapsuleOnDiskPpiGuid,
  &mCapsuleOnDiskPpi
};

/**
  Determine if capsule comes from memory by checking Capsule PPI.

  @param[in]  PeiServices General purpose services available to every PEIM.

  @retval TRUE   Capsule comes from memory.
  @retval FALSE  No capsule comes from memory.

**/
static
BOOLEAN
CheckCapsuleFromRam (
  IN CONST EFI_PEI_SERVICES  **PeiServices
  )
{
  EFI_STATUS       Status;
  PEI_CAPSULE_PPI  *Capsule;

  Status = PeiServicesLocatePpi (
             &gEfiPeiCapsulePpiGuid,
             0,
             NULL,
             (VOID **)&Capsule
             );
  if (!EFI_ERROR (Status)) {
    Status = Capsule->CheckCapsuleUpdate ((EFI_PEI_SERVICES **)PeiServices);
    if (!EFI_ERROR (Status)) {
      return TRUE;
    }
  }

  return FALSE;
}

/**
  Determine if it is a Capsule On Disk mode.

  @retval TRUE         Capsule On Disk mode.
  @retval FALSE        Not capsule On Disk mode.

**/
static
BOOLEAN
IsCapsuleOnDiskMode (
  VOID
  )
{
  EFI_STATUS                       Status;
  UINTN                            Size;
  EFI_PEI_READ_ONLY_VARIABLE2_PPI  *PPIVariableServices;
  BOOLEAN                          CodRelocInfo;

  Status = PeiServicesLocatePpi (
             &gEfiPeiReadOnlyVariable2PpiGuid,
             0,
             NULL,
             (VOID **)&PPIVariableServices
             );
  ASSERT_EFI_ERROR (Status);

  Size   = sizeof (BOOLEAN);
  Status = PPIVariableServices->GetVariable (
                                  PPIVariableServices,
                                  COD_RELOCATION_INFO_VAR_NAME,
                                  &gEfiCapsuleVendorGuid,
                                  NULL,
                                  &Size,
                                  &CodRelocInfo
                                  );

  if (EFI_ERROR (Status) || (Size != sizeof (BOOLEAN)) || !CodRelocInfo) {
    DEBUG ((DEBUG_ERROR, "Error Get CodRelocationInfo variable %r!\n", Status));
    return FALSE;
  }

  return TRUE;
}

/**
  Gets capsule images from relocated capsule buffer.
  Create Capsule hob for each Capsule.

  Caution: This function may receive untrusted input.
  Capsule-on-Disk Temp Relocation image is external input, so this function
  will validate Capsule-on-Disk Temp Relocation image to make sure the content
  is read within the buffer.

  @param[in]  RelocCapsuleBuf        Buffer pointer to the relocated capsule.
  @param[in]  RelocCapsuleTotalSize  Total size of the relocated capsule.

  @retval EFI_SUCCESS     Succeed to get capsules and create hob.
  @retval Others          Fail to get capsules and create hob.

**/
static
EFI_STATUS
RetrieveRelocatedCapsule (
  IN UINT8  *RelocCapsuleBuf,
  IN UINTN  RelocCapsuleTotalSize
  )
{
  UINTN   Index;
  UINT8   *CapsuleDataBufEnd;
  UINT8   *CapsulePtr;
  UINT32  CapsuleSize;
  UINT64  TotalImageSize;
  UINTN   CapsuleNum;

  //
  // Temp file contains at least 2 capsule (including 1 capsule name capsule) & 1 UINT64
  //
  if (RelocCapsuleTotalSize < sizeof (UINT64) + sizeof (EFI_CAPSULE_HEADER) * 2) {
    return EFI_INVALID_PARAMETER;
  }

  CopyMem (&TotalImageSize, RelocCapsuleBuf, sizeof (UINT64));

  DEBUG ((
    DEBUG_INFO,
    "ProcessRelocatedCapsule CapsuleBuf %x TotalCapSize %lx\n",
    RelocCapsuleBuf,
    TotalImageSize
    ));

  RelocCapsuleBuf += sizeof (UINT64);

  //
  // TempCaspule file length check
  //
  if ((MAX_ADDRESS - TotalImageSize <= sizeof (UINT64)) ||
      ((UINT64)RelocCapsuleTotalSize != TotalImageSize + sizeof (UINT64)) ||
      ((UINTN)(MAX_ADDRESS - (PHYSICAL_ADDRESS)(UINTN)RelocCapsuleBuf) <= TotalImageSize))
  {
    return EFI_INVALID_PARAMETER;
  }

  CapsuleDataBufEnd = RelocCapsuleBuf + TotalImageSize;

  //
  // TempCapsule file integrity check over Capsule Header to ensure no data corruption in NV Var & Relocation storage
  //
  CapsulePtr = RelocCapsuleBuf;
  CapsuleNum = 0;

  while (CapsulePtr < CapsuleDataBufEnd) {
    if (((CapsuleDataBufEnd - CapsulePtr) < sizeof (EFI_CAPSULE_HEADER)) ||
        (((EFI_CAPSULE_HEADER *)CapsulePtr)->CapsuleImageSize < sizeof (EFI_CAPSULE_HEADER)) ||
        ((UINTN)(MAX_ADDRESS - (PHYSICAL_ADDRESS)(UINTN)CapsulePtr) < ((EFI_CAPSULE_HEADER *)CapsulePtr)->CapsuleImageSize)
        )
    {
      break;
    }

    CapsulePtr += ((EFI_CAPSULE_HEADER *)CapsulePtr)->CapsuleImageSize;
    CapsuleNum++;
  }

  if (CapsulePtr != CapsuleDataBufEnd) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Capsule count must be less than PcdCapsuleMax, avoid building too many CvHobs to occupy all the free space in HobList.
  //
  if (CapsuleNum > PcdGet16 (PcdCapsuleMax)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Re-iterate the capsule buffer to create Capsule hob & Capsule Name Str Hob for each Capsule saved in relocated capsule file
  //
  CapsulePtr = RelocCapsuleBuf;
  Index      = 0;
  while (CapsulePtr < CapsuleDataBufEnd) {
    CapsuleSize = ((EFI_CAPSULE_HEADER *)CapsulePtr)->CapsuleImageSize;
    BuildCvHob ((EFI_PHYSICAL_ADDRESS)(UINTN)CapsulePtr, CapsuleSize);

    DEBUG ((DEBUG_INFO, "Capsule saved in address %x size %x\n", CapsulePtr, CapsuleSize));

    CapsulePtr += CapsuleSize;
    Index++;
  }

  return EFI_SUCCESS;
}

/**
  Recovery module entrypoint

  @param[in] FileHandle   Handle of the file being invoked.
  @param[in] PeiServices  Describes the list of possible PEI Services.

  @return EFI_SUCCESS Recovery module is initialized.
**/
EFI_STATUS
EFIAPI
InitializeCapsuleOnDiskLoad (
  IN       EFI_PEI_FILE_HANDLE  FileHandle,
  IN CONST EFI_PEI_SERVICES     **PeiServices
  )
{
  EFI_STATUS  Status;
  UINTN       BootMode;
  UINTN       FileNameSize;

  BootMode = GetBootModeHob ();
  ASSERT (BootMode == BOOT_ON_FLASH_UPDATE);

  //
  // If there are capsules provisioned in memory, quit.
  // Only one capsule resource is accept, CapsuleOnRam's priority is higher than CapsuleOnDisk.
  //
  if (CheckCapsuleFromRam (PeiServices)) {
    DEBUG ((DEBUG_ERROR, "Capsule On Memory Detected! Quit.\n"));
    return EFI_ABORTED;
  }

  DEBUG_CODE_BEGIN ();
  VOID  *CapsuleOnDiskModePpi;

  if (!IsCapsuleOnDiskMode ()) {
    return EFI_NOT_FOUND;
  }

  //
  // Check Capsule On Disk Relocation flag. If exists, load capsule & create Capsule Hob
  //
  Status = PeiServicesLocatePpi (
             &gEdkiiPeiBootInCapsuleOnDiskModePpiGuid,
             0,
             NULL,
             (VOID **)&CapsuleOnDiskModePpi
             );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Locate CapsuleOnDiskModePpi error %x\n", Status));
    return Status;
  }

  DEBUG_CODE_END ();

  Status = PeiServicesInstallPpi (&mCapsuleOnDiskPpiList);
  ASSERT_EFI_ERROR (Status);

  FileNameSize = PcdGetSize (PcdCoDRelocationFileName);
  Status       = PcdSetPtrS (PcdRecoveryFileName, &FileNameSize, (VOID *)PcdGetPtr (PcdCoDRelocationFileName));
  ASSERT_EFI_ERROR (Status);

  return Status;
}

/**
  Loads a DXE capsule from some media into memory and updates the HOB table
  with the DXE firmware volume information.

  @param[in]  PeiServices   General-purpose services that are available to every PEIM.
  @param[in]  This          Indicates the EFI_PEI_RECOVERY_MODULE_PPI instance.

  @retval EFI_SUCCESS        The capsule was loaded correctly.
  @retval EFI_DEVICE_ERROR   A device error occurred.
  @retval EFI_NOT_FOUND      A recovery DXE capsule cannot be found.

**/
EFI_STATUS
EFIAPI
LoadCapsuleOnDisk (
  IN EFI_PEI_SERVICES               **PeiServices,
  IN EDKII_PEI_CAPSULE_ON_DISK_PPI  *This
  )
{
  EFI_STATUS                          Status;
  EFI_PEI_DEVICE_RECOVERY_MODULE_PPI  *DeviceRecoveryPpi;
  UINTN                               NumberRecoveryCapsules;
  UINTN                               Instance;
  UINTN                               CapsuleInstance;
  UINTN                               CapsuleSize;
  EFI_GUID                            CapsuleType;
  VOID                                *CapsuleBuffer;

  DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Load Capsule On Disk Entry\n"));

  for (Instance = 0; ; Instance++) {
    Status = PeiServicesLocatePpi (
               &gEfiPeiDeviceRecoveryModulePpiGuid,
               Instance,
               NULL,
               (VOID **)&DeviceRecoveryPpi
               );
    DEBUG ((DEBUG_INFO, "LoadCapsuleOnDisk - LocateRecoveryPpi (%d) - %r\n", Instance, Status));
    if (EFI_ERROR (Status)) {
      if (Instance == 0) {
        REPORT_STATUS_CODE (
          EFI_ERROR_CODE | EFI_ERROR_MAJOR,
          (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_RECOVERY_PPI_NOT_FOUND)
          );
      }

      break;
    }

    NumberRecoveryCapsules = 0;
    Status                 = DeviceRecoveryPpi->GetNumberRecoveryCapsules (
                                                  (EFI_PEI_SERVICES **)PeiServices,
                                                  DeviceRecoveryPpi,
                                                  &NumberRecoveryCapsules
                                                  );
    DEBUG ((DEBUG_INFO, "LoadCapsuleOnDisk - GetNumberRecoveryCapsules (%d) - %r\n", NumberRecoveryCapsules, Status));
    if (EFI_ERROR (Status)) {
      continue;
    }

    for (CapsuleInstance = 1; CapsuleInstance <= NumberRecoveryCapsules; CapsuleInstance++) {
      CapsuleSize = 0;
      Status      = DeviceRecoveryPpi->GetRecoveryCapsuleInfo (
                                         (EFI_PEI_SERVICES **)PeiServices,
                                         DeviceRecoveryPpi,
                                         CapsuleInstance,
                                         &CapsuleSize,
                                         &CapsuleType
                                         );
      DEBUG ((DEBUG_INFO, "LoadCapsuleOnDisk - GetRecoveryCapsuleInfo (%d - %x) - %r\n", CapsuleInstance, CapsuleSize, Status));
      if (EFI_ERROR (Status)) {
        break;
      }

      //
      // Allocate the memory so that it gets preserved into DXE.
      // Capsule is special because it may need to populate to system table
      //
      CapsuleBuffer = AllocateRuntimePages (EFI_SIZE_TO_PAGES (CapsuleSize));

      if (CapsuleBuffer == NULL) {
        DEBUG ((DEBUG_ERROR, "LoadCapsuleOnDisk - AllocateRuntimePages fail\n"));
        continue;
      }

      Status = DeviceRecoveryPpi->LoadRecoveryCapsule (
                                    (EFI_PEI_SERVICES **)PeiServices,
                                    DeviceRecoveryPpi,
                                    CapsuleInstance,
                                    CapsuleBuffer
                                    );
      DEBUG ((DEBUG_INFO, "LoadCapsuleOnDisk - LoadRecoveryCapsule (%d) - %r\n", CapsuleInstance, Status));
      if (EFI_ERROR (Status)) {
        FreePages (CapsuleBuffer, EFI_SIZE_TO_PAGES (CapsuleSize));
        break;
      }

      //
      // Capsule Update Mode, Split relocated Capsule buffer into different capsule vehical hobs.
      //
      Status = RetrieveRelocatedCapsule (CapsuleBuffer, CapsuleSize);

      break;
    }

    if (EFI_ERROR (Status)) {
      REPORT_STATUS_CODE (
        EFI_ERROR_CODE | EFI_ERROR_MAJOR,
        (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_NO_RECOVERY_CAPSULE)
        );
    }

    return Status;
  }

  //
  // Any attack against GPT, Relocation Info Variable or temp relocation file will result in no Capsule HOB and return EFI_NOT_FOUND.
  // After flow to DXE phase. since no capsule hob is detected. Platform will clear Info flag and force restart.
  // No volunerability will be exposed
  //

  return EFI_NOT_FOUND;
}
