diff --git a/Utilities/TestExt4Dxe/Makefile b/Utilities/TestExt4Dxe/Makefile new file mode 100644 index 00000000..e73eddb7 --- /dev/null +++ b/Utilities/TestExt4Dxe/Makefile @@ -0,0 +1,31 @@ +## @file +# Copyright (c) 2022, Mikhail Krichanov. All rights reserved. +# SPDX-License-Identifier: BSD-3-Clause +## + +# CC=clang DEBUG=1 FUZZ=1 SANITIZE=1 make -j4 fuzz +PROJECT = TestExt4Dxe +PRODUCT = $(PROJECT)$(INFIX)$(SUFFIX) +OBJS = $(PROJECT).o +OBJS += BaseUcs2Utf8Lib.o BaseOrderedCollectionRedBlackTreeLib.o +OBJS += BlockGroup.o Collation.o Crc16.o Crc32c.o Directory.o DiskUtil.o +OBJS += Ext4Dxe.o Extents.o File.o Inode.o Partition.o Superblock.o + +ifeq ($(UDK_PATH),) + ifneq ($(PACKAGES_PATH),) + UDK_PATH := $(PACKAGES_PATH) + else + UDK_PATH ?= ../../UDK + endif +endif + +OC_USER = $(UDK_PATH)/OpenCorePkg + +include $(OC_USER)/User/Makefile + +CFLAGS += -I$(UDK_PATH)/RedfishPkg/Include +CFLAGS += -I$(UDK_PATH)/edk2-platforms/Features/Ext4Pkg/Ext4Dxe + +VPATH += $(UDK_PATH)/RedfishPkg/Library/BaseUcs2Utf8Lib:$\ + $(UDK_PATH)/MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib:$\ + $(UDK_PATH)/edk2-platforms/Features/Ext4Pkg/Ext4Dxe diff --git a/Utilities/TestExt4Dxe/TestExt4Dxe.c b/Utilities/TestExt4Dxe/TestExt4Dxe.c new file mode 100644 index 00000000..9f14dae6 --- /dev/null +++ b/Utilities/TestExt4Dxe/TestExt4Dxe.c @@ -0,0 +1,203 @@ +/** @file + Copyright (c) 2022, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause +**/ +#include + +#include +#include + +EFI_GUID gEfiUnicodeCollationProtocolGuid = { 0x1D85CD7F, 0xF43D, 0x11D2, { 0x9A, 0x0C, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }}; +EFI_GUID gEfiDiskIoProtocolGuid = { 0xCE345171, 0xBA0B, 0x11D2, { 0x8E, 0x4F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B }}; +EFI_GUID gEfiDiskIo2ProtocolGuid = { 0x151c8eae, 0x7f2c, 0x472c, { 0x9e, 0x54, 0x98, 0x28, 0x19, 0x4f, 0x6a, 0x88 }}; +EFI_GUID gEfiFileSystemInfoGuid = { 0x09576E93, 0x6D3F, 0x11D2, { 0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B }}; + +UINT8 _gPcd_FixedAtBuild_PcdUefiVariableDefaultLang[4] = {101, 110, 103, 0 }; +UINT8 _gPcd_FixedAtBuild_PcdUefiVariableDefaultPlatformLang[6] = {101, 110, 45, 85, 83, 0 }; + +UINTN mFuzzOffset; +UINTN mFuzzSize; +CONST UINT8 *mFuzzPointer; + +EFI_STATUS +EFIAPI +EfiLibInstallAllDriverProtocols2 ( + IN CONST EFI_HANDLE ImageHandle, + IN CONST EFI_SYSTEM_TABLE *SystemTable, + IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, + IN EFI_HANDLE DriverBindingHandle, + IN CONST EFI_COMPONENT_NAME_PROTOCOL *ComponentName, OPTIONAL + IN CONST EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2, OPTIONAL + IN CONST EFI_DRIVER_CONFIGURATION_PROTOCOL *DriverConfiguration, OPTIONAL + IN CONST EFI_DRIVER_CONFIGURATION2_PROTOCOL *DriverConfiguration2, OPTIONAL + IN CONST EFI_DRIVER_DIAGNOSTICS_PROTOCOL *DriverDiagnostics, OPTIONAL + IN CONST EFI_DRIVER_DIAGNOSTICS2_PROTOCOL *DriverDiagnostics2 OPTIONAL + ) +{ + abort(); + return EFI_NOT_FOUND; +} + +EFI_STATUS +EFIAPI +EfiLibUninstallAllDriverProtocols2 ( + IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, + IN CONST EFI_COMPONENT_NAME_PROTOCOL *ComponentName, OPTIONAL + IN CONST EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2, OPTIONAL + IN CONST EFI_DRIVER_CONFIGURATION_PROTOCOL *DriverConfiguration, OPTIONAL + IN CONST EFI_DRIVER_CONFIGURATION2_PROTOCOL *DriverConfiguration2, OPTIONAL + IN CONST EFI_DRIVER_DIAGNOSTICS_PROTOCOL *DriverDiagnostics, OPTIONAL + IN CONST EFI_DRIVER_DIAGNOSTICS2_PROTOCOL *DriverDiagnostics2 OPTIONAL + ) +{ + abort(); + return EFI_NOT_FOUND; +} + +EFI_STATUS +EFIAPI +FuzzReadDisk ( + IN EFI_DISK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN UINT64 Offset, + IN UINTN BufferSize, + OUT VOID *Buffer + ) +{ + if (Buffer == NULL) { + return EFI_INVALID_PARAMETER; + } + + if ((mFuzzSize - mFuzzOffset) < BufferSize) { + return EFI_OUT_OF_RESOURCES; + } + CopyMem (Buffer, mFuzzPointer, BufferSize); + mFuzzPointer += BufferSize; + mFuzzOffset += BufferSize; + + return EFI_SUCCESS; +} + +INT32 LLVMFuzzerTestOneInput(CONST UINT8 *FuzzData, UINTN FuzzSize) { + EFI_STATUS Status; + EXT4_PARTITION *Part; + EFI_FILE_PROTOCOL *This; + UINT64 BufferSize; + VOID *Buffer; + EFI_FILE_PROTOCOL *NewHandle; + CHAR16 *FileName; + + mFuzzOffset = 0; + mFuzzPointer = FuzzData; + mFuzzSize = FuzzSize; + + Part = AllocateZeroPool (sizeof (*Part)); + if (Part == NULL) { + return 0; + } + ASAN_CHECK_MEMORY_REGION (Part, sizeof(EXT4_PARTITION)); + + InitializeListHead (&Part->OpenFiles); + + Part->DiskIo = AllocateZeroPool (sizeof (EFI_DISK_IO_PROTOCOL)); + if (Part->DiskIo == NULL) { + FreePool (Part); + return 0; + } + ASAN_CHECK_MEMORY_REGION (Part->DiskIo, sizeof(EFI_DISK_IO_PROTOCOL)); + + Part->DiskIo->ReadDisk = FuzzReadDisk; + + Part->BlockIo = AllocateZeroPool (sizeof (EFI_BLOCK_IO_PROTOCOL)); + if (Part->BlockIo == NULL) { + FreePool (Part->DiskIo); + FreePool (Part); + return 0; + } + ASAN_CHECK_MEMORY_REGION (Part->BlockIo, sizeof(EFI_BLOCK_IO_PROTOCOL)); + + Part->BlockIo->Media = AllocateZeroPool (sizeof (EFI_BLOCK_IO_MEDIA)); + if (Part->BlockIo->Media == NULL) { + FreePool (Part->BlockIo); + FreePool (Part->DiskIo); + FreePool (Part); + return 0; + } + ASAN_CHECK_MEMORY_REGION (Part->BlockIo->Media, sizeof(EFI_BLOCK_IO_MEDIA)); + + Status = Ext4OpenSuperblock (Part); + if (EFI_ERROR (Status)) { + FreePool (Part->BlockIo->Media); + FreePool (Part->BlockIo); + FreePool (Part->DiskIo); + FreePool (Part); + return 0; + } + + Part->Interface.Revision = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION; + Part->Interface.OpenVolume = Ext4OpenVolume; + + BufferSize = 100; + Buffer = AllocateZeroPool (BufferSize); + if (Buffer == NULL) { + FreePool (Part->BlockIo->Media); + FreePool (Part->BlockIo); + FreePool (Part->DiskIo); + FreePool (Part); + return 0; + } + ASAN_CHECK_MEMORY_REGION (Buffer, BufferSize); + + FileName = AllocateZeroPool (BufferSize); + if (FileName == NULL) { + FreePool (Buffer); + FreePool (Part->BlockIo->Media); + FreePool (Part->BlockIo); + FreePool (Part->DiskIo); + FreePool (Part); + return 0; + } + ASAN_CHECK_MEMORY_REGION (FileName, BufferSize); + + if ((mFuzzSize - mFuzzOffset) < BufferSize) { + FreePool (Buffer); + FreePool (FileName); + FreePool (Part->BlockIo->Media); + FreePool (Part->BlockIo); + FreePool (Part->DiskIo); + FreePool (Part); + return 0; + } + CopyMem (FileName, mFuzzPointer, BufferSize - 2); + mFuzzPointer += BufferSize - 2; + mFuzzOffset += BufferSize - 2; + + This = (EFI_FILE_PROTOCOL *) Part->Root; + + Status = Ext4Open (This, &NewHandle, FileName, EFI_FILE_MODE_READ, 0); + if (Status == EFI_SUCCESS) { + Ext4ReadFile (NewHandle, &BufferSize, Buffer); + } + + FreePool (Buffer); + FreePool (FileName); + FreePool (Part->BlockIo->Media); + FreePool (Part->BlockIo); + FreePool (Part->DiskIo); + FreePool (Part); + + return 0; +} + +int ENTRY_POINT(int argc, char** argv) { + uint32_t f; + uint8_t *b; + if ((b = UserReadFile(argc > 1 ? argv[1] : "in.bin", &f)) == NULL) { + DEBUG ((DEBUG_ERROR, "Read fail\n")); + return -1; + } + + LLVMFuzzerTestOneInput(b, f); + FreePool(b); + return 0; +}