Acidanthera UEFI Development Kit based on EDK II edk2-stable202311
Go to file
Laszlo Ersek 4e39b75e7e MdeModulePkg/DiskIoDxe: fix source/destination pointer of overrun transfer
DiskIoCreateSubtaskList() may split the transfer into three segments:
- a leading segment, called underrun, which is the fractional, trailing
  subset of the first underlying block,
- a middle segment, which is an integral multiple of underlying blocks,
- a trailing segment, called overrun, which is the fractional, leading
  subset of the last underlying block.

This is an example read from the /EFI/BOOT/BOOTX64.EFI file, on the
RHEL-6.4 installation ISO (debug log enabled with EFI_D_BLKIO). The
underlying block size is 2048 bytes (IDE CD-ROM).

DiskIo: Create subtasks for task: Offset/BufferSize/Buffer = 0000000000004600/00002000/BD890018
  R:Lba/Offset/Length/WorkingBuffer/Buffer = 0000000000000008/00000600/00000200/BD90D000/BD890018
  R:Lba/Offset/Length/WorkingBuffer/Buffer = 000000000000000C/00000000/00000600/BD90D000/BD890218
  R:Lba/Offset/Length/WorkingBuffer/Buffer = 0000000000000009/00000000/00001800/00000000/BD890218

The first line corresponds to the underrun.
The second line corresponds to the overrun.
The third line corresponds to the middle segment.

In decimal:
- task: read 8192 bytes from offset 17920, storing it at BD890018
- underrun:
    - read block 8 [16384..18432) into the transfer area,
    - copy 512 bytes from offset 1536 of the transfer area to BD890018
      (target buffer offset 0, running total: 512)
- middle segment:
    - read blocks 9, 10, 11 [18432..24576) into the transfer area,
    - copy 6144 bytes from offset 0 of the transfer area to BD890218
      (target buffer offset 512, running total: 6656)
- overrun:
    - read block 12 [24576..26624) into the transfer area,
    - copy 1536 bytes from offset 0 of the transfer area to BD890218 (!!!)
      (target buffer offset 512 (!!!), running total 8192)

The values marked with (!!!) constitute the bug --
DiskIoCreateSubtaskList() doesn't take the size of the middle segment into
account when it calculates the destination (for reads) or source (for
writes) pointer for the overrun. This leads to data corruption.

When reading, data is copied form the transfer area to the target buffer
with

  CopyMem (Subtask->Buffer, Subtask->WorkingBuffer + Subtask->Offset, Subtask->Length);

calls in DiskIo2OnReadWriteComplete() for nonblocking reads, and in
DiskIo2ReadWriteDisk() for blocking reads. Therefore it's enough to adjust
Subtask->Buffer when it is initialized. (See BD891A18 below.)

DiskIo: Create subtasks for task: Offset/BufferSize/Buffer = 0000000000004600/00002000/BD890018
  R:Lba/Offset/Length/WorkingBuffer/Buffer = 0000000000000008/00000600/00000200/BD90D000/BD890018
  R:Lba/Offset/Length/WorkingBuffer/Buffer = 000000000000000C/00000000/00000600/BD90D000/BD891A18
  R:Lba/Offset/Length/WorkingBuffer/Buffer = 0000000000000009/00000000/00001800/00000000/BD890218

The patched call to DiskIoCreateSubtask() is also executed for write
requests. The changed Subtask->Buffer initialization fixes the "overrun
half writes" in DiskIo2ReadWriteDisk() too:

  //
  // A sub task before this one should be a block read operation, causing
  // the WorkingBuffer filled with the entire one block data.
  //
  CopyMem (Subtask->WorkingBuffer + Subtask->Offset, Subtask->Buffer, Subtask->Length);

This code doubles for underrun and overrun half-writes. The patch doesn't
modify the underrun case.

If we're storing the overrun at the beginning of the pre-read last block
(which we're going to write out as a full block), then
- Subtask->Offset == 0,
- Subtask->Length == OverRun,
- the first byte *not* accessed in the source area is
  ((Buffer + UnderRunLength) + BufferSize) + OverRun.

Contributed-under: TianoCore Contribution Agreement 1.0

Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14602 6f19259b-4bc3-4df7-8a09-765794883524
2013-08-26 02:47:41 +00:00
AppPkg - For writing sin_port, htons() must be used. 2013-02-08 21:34:26 +00:00
ArmPkg ArmPkg/ArmGicLib.h: Added macro to retrieve the information from the ICCIDR 2013-08-21 12:08:06 +00:00
ArmPlatformPkg ArmPlatformPkg/ArmVExpressPkg: Added 'EfiResetPlatformSpecific' to ResetSystemLib 2013-08-21 14:45:02 +00:00
BaseTools Sync BaseTool trunk (version r2599) into EDKII BaseTools. 2013-08-23 02:18:16 +00:00
BeagleBoardPkg ArmPlatform/ArmPlatformLib: Introduced ArmPlatformPeiBootAction() 2013-05-10 12:49:10 +00:00
Conf Adding top-level Conf directory for next generation of EDK II build infrastructure tools. 2007-06-20 19:33:23 +00:00
CryptoPkg Enhance error handling code after calling BIO_new in BaseCryptLib. 2013-08-07 08:11:14 +00:00
DuetPkg Fix DuetPkg build failure after adding the new reset type EfiResetPlatformSpecific. 2013-08-22 05:55:29 +00:00
EdkCompatibilityPkg Fix the typo in the description of EFI_PLATFORM_TO_DRIVER_CONFIGURATION_QUERY. 2013-08-23 08:31:11 +00:00
EdkShellBinPkg Update to new SVN URL in readme.txt 2013-06-08 05:26:39 +00:00
EdkShellPkg Update to new SVN URL in readme.txt 2013-06-08 05:26:39 +00:00
EmbeddedPkg EmbeddedPkg/EmbeddedPkg.dsc: Fixed PCD settings 2013-08-23 18:21:46 +00:00
EmulatorPkg EmulatorPkg: Use FaultTolerantWritePei driver. 2013-07-03 09:24:07 +00:00
FatBinPkg Add the AArch64 FAT binary to the EDK2 repository. 2013-08-15 01:18:05 +00:00
IntelFrameworkModulePkg Update all the code to consume the ConvertDevicePathToText, ConvertDevicePathNodeToText, ConvertTextToDevicePath and ConvertTextToDeviceNode APIs in DevicePathLib. 2013-07-26 03:14:08 +00:00
IntelFrameworkPkg Fill the ImageHandle and DriverBindingHandle field of Driver Binding Protocol before installing the Driver Binding Protocol instance. 2013-07-10 02:06:49 +00:00
MdeModulePkg MdeModulePkg/DiskIoDxe: fix source/destination pointer of overrun transfer 2013-08-26 02:47:41 +00:00
MdePkg Update SetVariable() function description for the clarification of requirements to update timestamp associated with authenticated variable. 2013-08-23 08:37:31 +00:00
NetworkPkg Roll back the changes in revision 14294 since it will cause iSCSI security authentication issue. 2013-07-10 05:52:58 +00:00
Nt32Pkg Do not lock the volume when the volume maps to a file instead of a physical disk. 2013-08-22 05:44:23 +00:00
Omap35xxPkg EmbeddedPkg: Introduced a separate SerialPortExtLib library 2013-03-12 00:40:11 +00:00
OptionRomPkg Fix OptionRomPkg build failure. 2013-08-21 08:57:13 +00:00
OvmfPkg OvmfPkg: Virtio: load used ring element strictly after loading used index 2013-08-23 18:46:03 +00:00
PcAtChipsetPkg Fix PciHostBridge driver to return success for EfiPciHostBridgeEndEnumeration to fix OVMF boot no display issue. 2013-07-22 07:35:51 +00:00
PerformancePkg Update all the code to consume the ConvertDevicePathToText, ConvertDevicePathNodeToText, ConvertTextToDevicePath and ConvertTextToDeviceNode APIs in DevicePathLib. 2013-07-26 03:14:08 +00:00
SecurityPkg Fix a bug in secure boot configuration driver: Enroll DB/KEK will disable Attempt Secure Boot option. 2013-08-22 09:46:03 +00:00
ShellBinPkg ShellBinPkg/UefiShell: Updated Shell Binary for ARM architecture 2013-06-17 09:58:18 +00:00
ShellPkg ShellPkg: Fix potentially uninitialized variable compiler warning 2013-08-23 15:21:16 +00:00
SourceLevelDebugPkg Updated connecting HOST version information from 1.3 to 1.3.1. 2013-05-08 08:29:11 +00:00
StdLib StdLib: Add Aarch64 support. 2013-07-23 18:51:51 +00:00
StdLibPrivateInternalFiles StdLib: Add internal use only header for interactive I/O. 2012-12-11 21:03:57 +00:00
UefiCpuPkg Fix build issue on DDK3790 tool chain. 2013-02-05 01:35:29 +00:00
UnixPkg UnixPkg: Remove UnixPkg files (It is replaced by EmulatorPkg) 2013-07-29 21:09:55 +00:00
BuildNotes2.txt Update to new SVN URL in readme.txt 2013-06-08 05:26:39 +00:00
edksetup.bat Added VS2010 support in edksetup script. 2012-04-10 07:45:35 +00:00
edksetup.sh Correct copyright year 2011-02-16 12:21:31 +00:00