diff --git a/Debug/Scripts/gdb_uefi.py b/Debug/Scripts/gdb_uefi.py index d49b822045a..32101b84c59 100644 --- a/Debug/Scripts/gdb_uefi.py +++ b/Debug/Scripts/gdb_uefi.py @@ -233,12 +233,13 @@ def pe_optional(self, pe): # Returns the symbol file name for a PE image. # - def pe_parse_debug(self, pe): + def pe_parse_debug(self, base): + pe = self.pe_headers(base) opt = self.pe_optional(pe) debug_dir_entry = opt['DataDirectory'][6] - dep = debug_dir_entry['VirtualAddress'] + opt['ImageBase'] + dep = debug_dir_entry['VirtualAddress'] + int(base) dep = dep.cast(self.ptype('EFI_IMAGE_DEBUG_DIRECTORY_ENTRY')) - cvp = dep.dereference()['RVA'] + opt['ImageBase'] + cvp = dep.dereference()['RVA'] + int(base) cvv = cvp.cast(self.ptype('UINT32')).dereference() if cvv == self.CV_NB10: return cvp + self.sizeof('EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY') @@ -328,7 +329,7 @@ def parse_image(self, image, syms): pe = self.pe_headers(base) opt = self.pe_optional(pe) file = self.pe_file(pe) - sym_name = self.pe_parse_debug(pe) + sym_name = self.pe_parse_debug(base) sections = self.pe_sections(opt, file, base) # For ELF and Mach-O-derived images... @@ -362,7 +363,7 @@ def parse_edii(self, edii, count): entry = entry['NormalImage'] self.parse_image(entry['LoadedImageProtocolInstance'], syms) else: - print(f"Skipping unknown EFI_DEBUG_IMAGE_INFO(Type 0x{entry['ImageInfoType'].dereference():x})") + print(f"Skipping unknown EFI_DEBUG_IMAGE_INFO(Type {str(entry['ImageInfoType'].dereference())})") index += 1 gdb.execute('symbol-file') print('Loading new symbols...') diff --git a/Debug/Scripts/lldb_uefi.py b/Debug/Scripts/lldb_uefi.py index 67010e4744f..b1b29149413 100644 --- a/Debug/Scripts/lldb_uefi.py +++ b/Debug/Scripts/lldb_uefi.py @@ -265,12 +265,13 @@ def pe_optional(self, pe): # Returns the symbol file name for a PE image. # - def pe_parse_debug(self, pe): + def pe_parse_debug(self, base): + pe = self.pe_headers(base) opt = self.pe_optional(pe) debug_dir_entry = opt.GetValueForExpressionPath('.DataDirectory[6]') - dep = self.get_field(debug_dir_entry, 'VirtualAddress') + self.get_field(opt, 'ImageBase') + dep = self.get_field(debug_dir_entry, 'VirtualAddress') + base dep = self.typed_ptr(self.ptype('EFI_IMAGE_DEBUG_DIRECTORY_ENTRY'), dep) - cvp = self.get_field(dep, 'RVA') + self.get_field(opt, 'ImageBase') + cvp = self.get_field(dep, 'RVA') + base # FIXME: UINT32 should be used here instead of unsigned, but LLDB+PDB type system is broken. cvv = self.typed_ptr(self.ptype('unsigned'), cvp).Dereference().GetValueAsUnsigned() if cvv == self.CV_NB10: @@ -310,7 +311,7 @@ def parse_image(self, image, syms): pe = self.pe_headers(base) opt = self.pe_optional(pe) file = self.pe_file(pe) - sym_address = self.pe_parse_debug(pe) + sym_address = self.pe_parse_debug(base) sections = self.pe_sections(opt, file, base) if sym_address == 0: @@ -373,7 +374,7 @@ def parse_edii(self, edii, count): entry = entry.GetChildMemberWithName('NormalImage') self.parse_image(entry.GetChildMemberWithName('LoadedImageProtocolInstance'), syms) else: - print(f'Skipping unknown EFI_DEBUG_IMAGE_INFO (Type 0x{image_type:x})') + print(f'Skipping unknown EFI_DEBUG_IMAGE_INFO (Type {str(image_type)})') index = index + 1 print('Loading new symbols...') for sym in syms: diff --git a/Docs/Configuration.md5 b/Docs/Configuration.md5 index bea6e63a8c9..2428e1cec42 100644 --- a/Docs/Configuration.md5 +++ b/Docs/Configuration.md5 @@ -1 +1 @@ -38f39473b89b08538cc2b6a049804b51 +32a9068c12dd2418920da6e0b992c8d9 diff --git a/Docs/Configuration.pdf b/Docs/Configuration.pdf index 561bdf076f7..1542e2d8534 100644 Binary files a/Docs/Configuration.pdf and b/Docs/Configuration.pdf differ diff --git a/Docs/Configuration.tex b/Docs/Configuration.tex index 155a43f8ee9..f1dfa2d0c1f 100755 --- a/Docs/Configuration.tex +++ b/Docs/Configuration.tex @@ -667,6 +667,7 @@ \subsection{Contribution}\label{configuration-comp} git clone --depth=1 https://github.com/acidanthera/audk UDK cd UDK git submodule update --init --recommend-shallow +rm -rf OpenCorePkg git clone --depth=1 https://github.com/acidanthera/OpenCorePkg . ./edksetup.sh make -C BaseTools @@ -8720,7 +8721,9 @@ \subsection{Quirks Properties}\label{uefiquirkprops} \emph{Note 2}: While this quirk can increase GPU PCI BAR sizes, this will not work on most firmware as is, because the quirk does not relocate BARs in memory, - and they will likely overlap. Contributions to improve this feature are welcome. + and they will likely overlap. In most cases it is best to either update the + firmware to the latest version or customise it with a specialised driver + like \href{https://github.com/xCuri0/ReBarUEFI}{ReBarUEFI}. \item \texttt{TscSyncTimeout}\\ diff --git a/Docs/Differences/Differences.pdf b/Docs/Differences/Differences.pdf index 80b87544fab..1fc4e896f85 100644 Binary files a/Docs/Differences/Differences.pdf and b/Docs/Differences/Differences.pdf differ diff --git a/Docs/Differences/Differences.tex b/Docs/Differences/Differences.tex index cd0c5c49d5e..380b47bf009 100644 --- a/Docs/Differences/Differences.tex +++ b/Docs/Differences/Differences.tex @@ -1,7 +1,7 @@ \documentclass[]{article} %DIF LATEXDIFF DIFFERENCE FILE -%DIF DEL PreviousConfiguration.tex Mon Jan 2 19:56:37 2023 -%DIF ADD ../Configuration.tex Mon Jan 2 19:56:37 2023 +%DIF DEL PreviousConfiguration.tex Mon Jan 2 20:13:00 2023 +%DIF ADD ../Configuration.tex Sun Jan 8 15:18:30 2023 \usepackage{lmodern} \usepackage{amssymb,amsmath} @@ -118,7 +118,7 @@ %DIF HYPERREF PREAMBLE %DIF PREAMBLE \providecommand{\DIFadd}[1]{\texorpdfstring{\DIFaddtex{#1}}{#1}} %DIF PREAMBLE \providecommand{\DIFdel}[1]{\texorpdfstring{\DIFdeltex{#1}}{}} %DIF PREAMBLE -%DIF COLORLISTINGS PREAMBLE %DIF PREAMBLE +%DIF LISTINGS PREAMBLE %DIF PREAMBLE \RequirePackage{listings} %DIF PREAMBLE \RequirePackage{color} %DIF PREAMBLE \lstdefinelanguage{DIFcode}{ %DIF PREAMBLE @@ -723,15 +723,18 @@ \subsection{Contribution}\label{configuration-comp} The latest Xcode version is recommended for use despite the toolchain name. An example command sequence is as follows: -\begin{lstlisting}[caption=Compilation Commands, label=compile, style=ocbash] +\DIFmodbegin +\begin{lstlisting}[caption=Compilation Commands, label=compile, style=ocbash,alsolanguage=DIFcode] git clone --depth=1 https://github.com/acidanthera/audk UDK cd UDK git submodule update --init --recommend-shallow +%DIF > rm -rf OpenCorePkg git clone --depth=1 https://github.com/acidanthera/OpenCorePkg . ./edksetup.sh make -C BaseTools build -a X64 -b RELEASE -t XCODE5 -p OpenCorePkg/OpenCorePkg.dsc \end{lstlisting} +\DIFmodend For IDE usage Xcode projects are available in the root of the repositories. Another approach could be using \href{https://microsoft.github.io/language-server-protocol}{Language Server Protocols}. For example, \href{https://www.sublimetext.com}{Sublime Text} with @@ -8780,7 +8783,9 @@ \subsection{Quirks Properties}\label{uefiquirkprops} \emph{Note 2}: While this quirk can increase GPU PCI BAR sizes, this will not work on most firmware as is, because the quirk does not relocate BARs in memory, - and they will likely overlap. Contributions to improve this feature are welcome. + and they will likely overlap. \DIFdelbegin \DIFdel{Contributions to improve this feature are welcome}\DIFdelend \DIFaddbegin \DIFadd{In most cases it is best to either update the + firmware to the latest version or customise it with a specialised driver + like }\href{https://github.com/xCuri0/ReBarUEFI}{\DIFadd{ReBarUEFI}}\DIFaddend . \item \texttt{TscSyncTimeout}\\ diff --git a/Docs/Errata/Errata.pdf b/Docs/Errata/Errata.pdf index da462672740..b76806b237b 100644 Binary files a/Docs/Errata/Errata.pdf and b/Docs/Errata/Errata.pdf differ diff --git a/Docs/Errata/Errata.tex b/Docs/Errata/Errata.tex index 7580189d02c..0dc72c837e8 100755 --- a/Docs/Errata/Errata.tex +++ b/Docs/Errata/Errata.tex @@ -315,6 +315,25 @@ \section{Issue list}\label{issuelist} \end{itemize} +\item + \textbf{Identifier}: \texttt{ERR088-1} \\ + \textbf{Published}: 2023-01-07 21:29 MSK \\ + \textbf{Updated}: 2023-01-07 21:29 MSK \\ + \textbf{Affected versions}: 0.8.8 \\ + \textbf{Resolved in}: 0.8.9 (\href{https://github.com/acidanthera/OpenCorePkg/commit/092af5d99c764cbe06372dfed3fa03af719550cc}{092af5d9}) \\ + \textbf{Description}: + + Loading macOS in OpenDuet may fail. Reference: + \href{https://github.com/acidanthera/bugtracker/issues/2190}{acidanthera/bugtracker\#2190}. + + \textbf{Possible workarounds}: + \begin{itemize} + \tightlist + + \item Update OpenDuet to master version + + \end{itemize} + \end{itemize} \end{document} diff --git a/Docs/Flavours.md b/Docs/Flavours.md index 735e81c462b..0ea69941515 100644 --- a/Docs/Flavours.md +++ b/Docs/Flavours.md @@ -138,7 +138,7 @@ If providing just one file, name it `Shell.icns` if the theming of the icon is g - **Shell** - Any shell-style tool - **UEFIShell:Shell** - EDK II UEFI Shell - As an example of how flavours work: **UEFIShell:Shell** will try `UEFIShell.icns`, then `Shell.icns` (and then, by OC default behaviour, `Tool.icns`, then `HardDrive.icns`) - - _**NB**: Including **UEFIShell** anywhere in the flavour triggers picker audio-assist for "UEFI Shell"_ + - _**Note**: Including **UEFIShell** anywhere in the flavour triggers picker audio-assist for "UEFI Shell"_ - **OpenShell:UEFIShell:Shell** - Themed specifically for OpenCore OpenShell (which is a variant of the EDK II UEFI Shell) - This is the recommended flavour to use for `OpenShell.efi`, as is done in the sample config files - Although this is the recommended *flavour*, icon artists are not required to provide this icon file, since this flavour will automatically find and use `Shell.icns` or `UEFIShell.icns` anyway @@ -155,11 +155,11 @@ If providing `NVRAMTool.icns`, it should be themed so that it could be applied t - **ResetNVRAM:NVRAMTool** - Reset NVRAM tool (`ResetNVRAM.icns`) - This is the recommended flavour, used for the entry created by the `ResetNvramEntry.efi` driver. - As another example of how flavours work: **ResetNVRAM:NVRAMTool** will look for `ResetNVRAM.icns`, then `NVRAMTool.icns` (and then, by OC default behaviour, `Tool.icns` then `HardDrive.icns`) - - **NB**: Including **ResetNVRAM** anywhere in a user flavour triggers picker audio-assist and builtin label support for "Reset NVRAM" + - **Note**: Including **ResetNVRAM** anywhere in a user flavour triggers picker audio-assist and builtin label support for "Reset NVRAM" - **ToggleSIP:NVRAMTool** - Icon themed for Toggle SIP tool (`ToggleSIP.icns`) - **ToggleSIP_Enabled:ToggleSIP:NVRAMTool** - Icon themed for Toggle SIP tool when SIP is enabled (system is protected) - **ToggleSIP_Disabled:ToggleSIP:NVRAMTool** - Icon themed for Toggle SIP tool when SIP is disabled (system is unprotected) - - **NB**: Including **ToggleSIP_Enabled** or **ToggleSIP_Disabled** anywhere in a user flavour triggers picker audio-assist and builtin label support for the two states of the Toggle SIP menu entry + - **Note**: Including **ToggleSIP_Enabled** or **ToggleSIP_Disabled** anywhere in a user flavour triggers picker audio-assist and builtin label support for the two states of the Toggle SIP menu entry ### Other Tools diff --git a/Include/Acidanthera/Library/OcBootManagementLib.h b/Include/Acidanthera/Library/OcBootManagementLib.h index 8d7b57a9580..1a6eb90f374 100644 --- a/Include/Acidanthera/Library/OcBootManagementLib.h +++ b/Include/Acidanthera/Library/OcBootManagementLib.h @@ -1837,7 +1837,7 @@ OcImageLoaderLoad ( include spaces, and '\' can be used within quoted or unquoted values to escape any character (including space and '"'). - NB Var names and values are left as pointers to within the original raw LoadOptions + Note: Var names and values are left as pointers to within the original raw LoadOptions string, which may be modified during processing. @param[in] LoadedImage Loaded image handle. @@ -1867,7 +1867,7 @@ OcParseLoadOptions ( character (including space and double quote). Comments (if any) run from hash symbol to end of same line. - NB Var names and values are left as pointers to within the raw string, which may + Note: Var names and values are left as pointers to within the raw string, which may be modified during processing. @param[in] StrVars Raw var string. diff --git a/Include/Acidanthera/Library/OcFileLib.h b/Include/Acidanthera/Library/OcFileLib.h index 84bd304adde..8846d6eada6 100644 --- a/Include/Acidanthera/Library/OcFileLib.h +++ b/Include/Acidanthera/Library/OcFileLib.h @@ -308,7 +308,7 @@ OcEnsureDirectoryFile ( /** Process directory item. - NB Successful processing must return EFI_SUCCESS or EFI_NOT_FOUND, or further + Note: Successful processing must return EFI_SUCCESS or EFI_NOT_FOUND, or further processing will be aborted. Return EFI_NOT_FOUND to continue processing but act if no file found. diff --git a/Include/Apple/IndustryStandard/AppleIntelCpuInfo.h b/Include/Apple/IndustryStandard/AppleIntelCpuInfo.h index 06696f4dd0c..07415776ca1 100644 --- a/Include/Apple/IndustryStandard/AppleIntelCpuInfo.h +++ b/Include/Apple/IndustryStandard/AppleIntelCpuInfo.h @@ -24,7 +24,7 @@ * * These are meant to identify the CPU's marketing name - an * application can map these to (possibly) localized strings. - * NB: the encodings of the CPU families are intentionally arbitrary. + * Note: the encodings of the CPU families are intentionally arbitrary. * There is no ordering, and you should never try to deduce whether * or not some feature is available based on the family. * Use feature flags (eg, hw.optional.altivec) to test for optional diff --git a/Include/Apple/IndustryStandard/AppleSmc.h b/Include/Apple/IndustryStandard/AppleSmc.h index 20dbca2736a..346d5cbc57a 100644 --- a/Include/Apple/IndustryStandard/AppleSmc.h +++ b/Include/Apple/IndustryStandard/AppleSmc.h @@ -20,7 +20,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. // we define SMC_MAKE_IDENTIFIER to produce Little Endian keys in UEFI (EFIAPI), // and Big Endian keys in all other places. // -// NB: This code assumes Little Endian host byte order, which so far is the +// Note: This code assumes Little Endian host byte order, which so far is the // only supported byte order in UEFI. // #ifdef EFIAPI diff --git a/Library/OcAppleKernelLib/LegacyBcopy.nasm b/Library/OcAppleKernelLib/LegacyBcopy.nasm index 6d2249bff2e..15670e7c025 100644 --- a/Library/OcAppleKernelLib/LegacyBcopy.nasm +++ b/Library/OcAppleKernelLib/LegacyBcopy.nasm @@ -52,7 +52,7 @@ Lbcopy: ; void *memcpy(void *dst, const void *src, size_t len) ; void *memmove(void *dst, const void *src, size_t len) ; -; NB: These need to be 32 bytes from bcopy(). +; Note: These need to be 32 bytes from bcopy(). ;------------------------------------------------------------------------------ align 32 Lmemcpy: diff --git a/Library/OcBootManagementLib/HotKeySupport.c b/Library/OcBootManagementLib/HotKeySupport.c index b2432134c79..04e4fb44fdf 100644 --- a/Library/OcBootManagementLib/HotKeySupport.c +++ b/Library/OcBootManagementLib/HotKeySupport.c @@ -320,7 +320,7 @@ GetPickerKeyInfo ( } // - // NB As historically SHIFT handling here is considered a 'hotkey': + // Note: As historically SHIFT handling here is considered a 'hotkey': // it's original reason for being here is to fix difficulties in // detecting this and other hotkey modifiers during no-picker boot. // @@ -792,7 +792,7 @@ OcInitHotKeys ( } // - // NB Raw AKMA is also still used for HotKeys, since we really do need + // Note: Raw AKMA is also still used for HotKeys, since we really do need // three different types of keys response for fluent UI behaviour. // diff --git a/Platform/OpenLinuxBoot/LoaderEntry.c b/Platform/OpenLinuxBoot/LoaderEntry.c index b350b1fc156..53a879e1e86 100644 --- a/Platform/OpenLinuxBoot/LoaderEntry.c +++ b/Platform/OpenLinuxBoot/LoaderEntry.c @@ -87,7 +87,7 @@ typedef enum ENTRY_PARSE_STATE_ { // First match, therefore Ubuntu should come after similar variants, // and probably very short strings should come last in case they // occur elsewhere in another kernel version string. -// NB: Should be kept in sync with Flavours.md. +// Note: Should be kept in sync with Flavours.md. // STATIC CHAR8 * diff --git a/User/Library/UserMisc.c b/User/Library/UserMisc.c index e96483f28b3..0f2e9bdbb6c 100644 --- a/User/Library/UserMisc.c +++ b/User/Library/UserMisc.c @@ -14,10 +14,7 @@ CpuBreakpoint ( VOID ) { - ASSERT (FALSE); - - while (TRUE) { - } + abort (); } VOID diff --git a/User/Library/UserPcd.c b/User/Library/UserPcd.c index 6728b1fb36c..0f450aa7446 100644 --- a/User/Library/UserPcd.c +++ b/User/Library/UserPcd.c @@ -4,10 +4,14 @@ **/ #include +#include #define _PCD_VALUE_PcdUefiLibMaxPrintBufferSize 320U #define _PCD_VALUE_PcdUgaConsumeSupport ((BOOLEAN)1U) -#define _PCD_VALUE_PcdDebugPropertyMask 0x23U +#define _PCD_VALUE_PcdDebugPropertyMask (\ + DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED \ + | DEBUG_PROPERTY_DEBUG_PRINT_ENABLED \ + | DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED ) #define _PCD_VALUE_PcdDebugClearMemoryValue 0xAFU #define _PCD_VALUE_PcdFixedDebugPrintErrorLevel 0x80000002U #define _PCD_VALUE_PcdDebugPrintErrorLevel 0x80000002U diff --git a/Utilities/TestExt4Dxe/TestExt4Dxe.c b/Utilities/TestExt4Dxe/TestExt4Dxe.c old mode 100755 new mode 100644 index f4351e7d10d..068c9bd849b --- a/Utilities/TestExt4Dxe/TestExt4Dxe.c +++ b/Utilities/TestExt4Dxe/TestExt4Dxe.c @@ -9,17 +9,22 @@ #include #include -#define MAP_TABLE_SIZE 0x100 -#define CHAR_FAT_VALID 0x01 +#define OPEN_FILE_MODES_COUNT 3 +#define MAP_TABLE_SIZE 0x100 +#define CHAR_FAT_VALID 0x01 #define TO_UPPER(a) (CHAR16) ((a) <= 0xFF ? mEngUpperMap[a] : (a)) 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; +STATIC UINTN mFuzzOffset; +STATIC UINTN mFuzzSize; +STATIC CONST UINT8 *mFuzzPointer; + +STATIC EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *mEfiSfsInterface; + +STATIC UINT64 mOpenFileModes[OPEN_FILE_MODES_COUNT] = { EFI_FILE_MODE_READ, EFI_FILE_MODE_WRITE, EFI_FILE_MODE_CREATE }; CHAR8 mEngUpperMap[MAP_TABLE_SIZE]; CHAR8 mEngLowerMap[MAP_TABLE_SIZE]; @@ -192,6 +197,47 @@ EfiLibUninstallAllDriverProtocols2 ( return EFI_NOT_FOUND; } +EFI_STATUS +EFIAPI +WrapInstallMultipleProtocolInterfaces ( + IN OUT EFI_HANDLE *Handle, + ... + ) +{ + VA_LIST Args; + EFI_STATUS Status; + EFI_GUID *Protocol; + VOID *Interface; + + if (Handle == NULL) { + return EFI_INVALID_PARAMETER; + } + + VA_START (Args, Handle); + for (Status = EFI_SUCCESS; !EFI_ERROR (Status);) { + // + // If protocol is NULL, then it's the end of the list + // + Protocol = VA_ARG (Args, EFI_GUID *); + if (Protocol == NULL) { + break; + } + + Interface = VA_ARG (Args, VOID *); + + // + // If this is Sfs protocol then save interface into global state + // + if (CompareGuid (Protocol, &gEfiSimpleFileSystemProtocolGuid)) { + mEfiSfsInterface = Interface; + } + } + + VA_END (Args); + + return Status; +} + VOID FreeAll ( IN CHAR16 *FileName, @@ -246,32 +292,72 @@ FuzzReadDisk ( return EFI_SUCCESS; } +STATIC +VOID +ConfigureMemoryAllocations ( + IN CONST UINT8 *Data, + IN UINTN Size + ) +{ + UINT32 Off; + + mPoolAllocationIndex = 0; + mPageAllocationIndex = 0; + + // + // Limit single pool allocation size to 3GB + // + SetPoolAllocationSizeLimit (BASE_1GB | BASE_2GB); + + Off = sizeof (UINT64); + if (Size >= Off) { + CopyMem (&mPoolAllocationMask, &Data[Size - Off], sizeof (UINT64)); + } else { + mPoolAllocationMask = MAX_UINT64; + } + + Off += sizeof (UINT64); + if (Size >= Off) { + CopyMem (&mPageAllocationMask, &Data[Size - Off], sizeof (UINT64)); + } else { + mPageAllocationMask = MAX_UINT64; + } +} + +STATIC INT32 -LLVMFuzzerTestOneInput ( +TestExt4Dxe ( CONST UINT8 *FuzzData, UINTN FuzzSize ) { - EFI_STATUS Status; - EXT4_PARTITION *Part; - EXT4_FILE *File; - EFI_FILE_PROTOCOL *This; - UINTN BufferSize; - VOID *Buffer; - EFI_FILE_PROTOCOL *NewHandle; - CHAR16 *FileName; - VOID *Info; - UINTN Len; - UINT64 Position; - UINT64 FileSize; - - mFuzzOffset = 0; - mFuzzPointer = FuzzData; - mFuzzSize = FuzzSize; + EFI_STATUS Status; + EXT4_PARTITION *Part; + EXT4_FILE *File; + EFI_FILE_PROTOCOL *This; + EFI_DISK_IO_PROTOCOL *DiskIo; + EFI_BLOCK_IO_PROTOCOL *BlockIo; + EFI_HANDLE DeviceHandle; + UINTN BufferSize; + VOID *Buffer; + EFI_FILE_PROTOCOL *NewHandle; + CHAR16 *FileName; + VOID *Info; + UINTN Len; + UINT64 Position; + UINT64 FileSize; + UINTN Index; Part = NULL; BufferSize = 100; + mFuzzOffset = 0; + mFuzzSize = FuzzSize; + mFuzzPointer = FuzzData; + mEfiSfsInterface = NULL; + + DeviceHandle = (EFI_HANDLE)0xDEADBEAFULL; + // // Construct file name // @@ -283,7 +369,7 @@ LLVMFuzzerTestOneInput ( ASAN_CHECK_MEMORY_REGION (FileName, BufferSize); if ((mFuzzSize - mFuzzOffset) < BufferSize) { - FreeAll (FileName, Part); + FreePool (FileName); return 0; } @@ -292,118 +378,72 @@ LLVMFuzzerTestOneInput ( mFuzzOffset += BufferSize - 2; // - // Construct File System + // Construct BlockIo and DiskIo interfaces // - Part = AllocateZeroPool (sizeof (EXT4_PARTITION)); - if (Part == NULL) { - FreeAll (FileName, Part); + DiskIo = AllocateZeroPool (sizeof (EFI_DISK_IO_PROTOCOL)); + if (DiskIo == NULL) { + FreePool (FileName); return 0; } - ASAN_CHECK_MEMORY_REGION (Part, sizeof (EXT4_PARTITION)); + ASAN_CHECK_MEMORY_REGION (DiskIo, sizeof (EFI_DISK_IO_PROTOCOL)); - InitializeListHead (&Part->OpenFiles); + DiskIo->ReadDisk = FuzzReadDisk; - Part->DiskIo = AllocateZeroPool (sizeof (EFI_DISK_IO_PROTOCOL)); - if (Part->DiskIo == NULL) { - FreeAll (FileName, Part); + BlockIo = AllocateZeroPool (sizeof (EFI_BLOCK_IO_PROTOCOL)); + if (BlockIo == NULL) { + FreePool (FileName); + FreePool (DiskIo); return 0; } - ASAN_CHECK_MEMORY_REGION (Part->DiskIo, sizeof (EFI_DISK_IO_PROTOCOL)); + ASAN_CHECK_MEMORY_REGION (BlockIo, sizeof (EFI_BLOCK_IO_PROTOCOL)); - Part->DiskIo->ReadDisk = FuzzReadDisk; - - Part->BlockIo = AllocateZeroPool (sizeof (EFI_BLOCK_IO_PROTOCOL)); - if (Part->BlockIo == NULL) { - FreeAll (FileName, Part); + BlockIo->Media = AllocateZeroPool (sizeof (EFI_BLOCK_IO_MEDIA)); + if (BlockIo->Media == NULL) { + FreePool (FileName); + FreePool (DiskIo); + FreePool (BlockIo); return 0; } - ASAN_CHECK_MEMORY_REGION (Part->BlockIo, sizeof (EFI_BLOCK_IO_PROTOCOL)); + ASAN_CHECK_MEMORY_REGION (BlockIo->Media, sizeof (EFI_BLOCK_IO_MEDIA)); - Part->BlockIo->Media = AllocateZeroPool (sizeof (EFI_BLOCK_IO_MEDIA)); - if (Part->BlockIo->Media == NULL) { - FreeAll (FileName, Part); - return 0; + // + // Check Ext4 SuperBlock magic like it done + // in Ext4IsBindingSupported routine + // + if (!Ext4SuperblockCheckMagic (DiskIo, BlockIo)) { + // Don't halt on bad magic, just keep going + DEBUG ((DEBUG_WARN, "[ext4] Superblock contains bad magic \n")); } - ASAN_CHECK_MEMORY_REGION (Part->BlockIo->Media, sizeof (EFI_BLOCK_IO_MEDIA)); + // + // Open partition + // + Status = Ext4OpenPartition (DeviceHandle, DiskIo, NULL, BlockIo); - Status = Ext4OpenSuperblock (Part); if (EFI_ERROR (Status)) { - FreeAll (FileName, Part); + DEBUG ((DEBUG_ERROR, "[ext4] Error mounting: %r\n", Status)); + FreePool (FileName); + FreePool (BlockIo->Media); + FreePool (BlockIo); + FreePool (DiskIo); return 0; } - Part->Interface.Revision = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION; - Part->Interface.OpenVolume = Ext4OpenVolume; + Part = (EXT4_PARTITION *)mEfiSfsInterface; + + ASAN_CHECK_MEMORY_REGION (Part, sizeof (EXT4_PARTITION)); This = (EFI_FILE_PROTOCOL *)Part->Root; // // Test Ext4Dxe driver // - Status = Ext4Open (This, &NewHandle, FileName, EFI_FILE_MODE_READ, 0); - if (Status == EFI_SUCCESS) { - Buffer = NULL; - BufferSize = 0; - Status = Ext4ReadFile (NewHandle, &BufferSize, Buffer); - if (Status == EFI_BUFFER_TOO_SMALL) { - Buffer = AllocateZeroPool (BufferSize); - if (Buffer == NULL) { - FreeAll (FileName, Part); - return 0; - } - - ASAN_CHECK_MEMORY_REGION (Buffer, BufferSize); - - Ext4ReadFile (NewHandle, &BufferSize, Buffer); - - Ext4WriteFile (NewHandle, &BufferSize, Buffer); - - FreePool (Buffer); - } - - Len = 0; - Info = NULL; - Status = Ext4GetInfo (NewHandle, &gEfiFileInfoGuid, &Len, Info); - if (Status == EFI_BUFFER_TOO_SMALL) { - Info = AllocateZeroPool (Len); - Ext4GetInfo (NewHandle, &gEfiFileInfoGuid, &Len, Info); - FreePool (Info); - } - - Len = 0; - Status = Ext4GetInfo (NewHandle, &gEfiFileSystemInfoGuid, &Len, Info); - if (Status == EFI_BUFFER_TOO_SMALL) { - Info = AllocateZeroPool (Len); - Ext4GetInfo (NewHandle, &gEfiFileSystemInfoGuid, &Len, Info); - FreePool (Info); - } - - Len = 0; - Status = Ext4GetInfo (NewHandle, &gEfiFileSystemVolumeLabelInfoIdGuid, &Len, Info); - if (Status == EFI_BUFFER_TOO_SMALL) { - Info = AllocateZeroPool (Len); - Ext4GetInfo (NewHandle, &gEfiFileSystemVolumeLabelInfoIdGuid, &Len, Info); - FreePool (Info); - } - - Ext4SetInfo (NewHandle, &gEfiFileSystemVolumeLabelInfoIdGuid, Len, Info); - - // - // Test position functions - // - Ext4GetPosition (NewHandle, &Position); - Ext4SetPosition (NewHandle, Position); - - // - // Trying to reach the end of file and read/write it - // - Position = (UINT64)-1; - Status = Ext4SetPosition (NewHandle, Position); - if (!EFI_ERROR (Status)) { + for (Index = 0; Index < OPEN_FILE_MODES_COUNT; Index++) { + Status = Ext4Open (This, &NewHandle, FileName, mOpenFileModes[Index], 0); + if (Status == EFI_SUCCESS) { Buffer = NULL; BufferSize = 0; Status = Ext4ReadFile (NewHandle, &BufferSize, Buffer); @@ -422,19 +462,100 @@ LLVMFuzzerTestOneInput ( FreePool (Buffer); } - } - // - // Trying to reach out of bound of FileSize - // - File = EXT4_FILE_FROM_THIS (NewHandle); - FileSize = EXT4_INODE_SIZE (File->Inode); - if (FileSize < (UINT64)-1 - 1) { - Position = FileSize + 1; + Len = 0; + Info = NULL; + Status = Ext4GetInfo (NewHandle, &gEfiFileInfoGuid, &Len, Info); + if (Status == EFI_BUFFER_TOO_SMALL) { + Info = AllocateZeroPool (Len); + if (Info == NULL) { + FreeAll (FileName, Part); + return 0; + } + + Ext4GetInfo (NewHandle, &gEfiFileInfoGuid, &Len, Info); + FreePool (Info); + } + + Len = 0; + Status = Ext4GetInfo (NewHandle, &gEfiFileSystemInfoGuid, &Len, Info); + if (Status == EFI_BUFFER_TOO_SMALL) { + Info = AllocateZeroPool (Len); + if (Info == NULL) { + FreeAll (FileName, Part); + return 0; + } + + Ext4GetInfo (NewHandle, &gEfiFileSystemInfoGuid, &Len, Info); + FreePool (Info); + } + + Len = 0; + Status = Ext4GetInfo (NewHandle, &gEfiFileSystemVolumeLabelInfoIdGuid, &Len, Info); + if (Status == EFI_BUFFER_TOO_SMALL) { + Info = AllocateZeroPool (Len); + if (Info == NULL) { + FreeAll (FileName, Part); + return 0; + } + + Ext4GetInfo (NewHandle, &gEfiFileSystemVolumeLabelInfoIdGuid, &Len, Info); + FreePool (Info); + } + + Ext4SetInfo (NewHandle, &gEfiFileSystemVolumeLabelInfoIdGuid, Len, Info); + + // + // Test position functions + // + Ext4GetPosition (NewHandle, &Position); Ext4SetPosition (NewHandle, Position); - } - Ext4Delete (NewHandle); + // + // Trying to reach the end of file and read/write it + // + Position = (UINT64)-1; + Status = Ext4SetPosition (NewHandle, Position); + if (!EFI_ERROR (Status)) { + Buffer = NULL; + BufferSize = 0; + Status = Ext4ReadFile (NewHandle, &BufferSize, Buffer); + if (Status == EFI_BUFFER_TOO_SMALL) { + Buffer = AllocateZeroPool (BufferSize); + if (Buffer == NULL) { + FreeAll (FileName, Part); + return 0; + } + + ASAN_CHECK_MEMORY_REGION (Buffer, BufferSize); + + Ext4ReadFile (NewHandle, &BufferSize, Buffer); + + Ext4WriteFile (NewHandle, &BufferSize, Buffer); + + FreePool (Buffer); + } + } + + // + // Trying to reach out of bound of FileSize + // + File = EXT4_FILE_FROM_THIS (NewHandle); + FileSize = EXT4_INODE_SIZE (File->Inode); + if (FileSize < (UINT64)-1 - 1) { + Position = FileSize + 1; + Status = Ext4SetPosition (NewHandle, Position); + if (!EFI_ERROR (Status)) { + Buffer = NULL; + BufferSize = 0; + Status = Ext4ReadFile (NewHandle, &BufferSize, Buffer); + + ASSERT (Status == EFI_DEVICE_ERROR); + } + } + + Ext4Delete (NewHandle); + } } FreeAll (FileName, Part); @@ -442,6 +563,42 @@ LLVMFuzzerTestOneInput ( return 0; } +INT32 +LLVMFuzzerTestOneInput ( + CONST UINT8 *FuzzData, + UINTN FuzzSize + ) +{ + VOID *NewData; + + if (FuzzSize == 0) { + return 0; + } + + // + // Override InstallMultipleProtocolInterfaces with custom wrapper + // + gBS->InstallMultipleProtocolInterfaces = WrapInstallMultipleProtocolInterfaces; + + ConfigureMemoryAllocations (FuzzData, FuzzSize); + + NewData = AllocatePool (FuzzSize); + if (NewData != NULL) { + CopyMem (NewData, FuzzData, FuzzSize); + TestExt4Dxe (NewData, FuzzSize); + FreePool (NewData); + } + + DEBUG (( + DEBUG_POOL | DEBUG_PAGE, + "UMEM: Allocated %u pools %u pages\n", + (UINT32)mPoolAllocations, + (UINT32)mPageAllocations + )); + + return 0; +} + int ENTRY_POINT ( int argc,