/** @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 definitions 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
  )
{
  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;
  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;
  }

  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;
}
