/** @file Copyright (c) 2020-2021, Ubsefor & koralexa. All rights reserved. SPDX-License-Identifier: BSD-3-Clause **/ #include #include #include #include #include #include #include #include #include #include #include #include /** Prints description of error occured in the perser. @param[in] Status Error occured in the parser. **/ STATIC VOID PrintParserError ( IN EFI_STATUS Status ) { switch (Status) { case EFI_SUCCESS: break; case EFI_INVALID_PARAMETER: DEBUG ((DEBUG_ERROR, "EXIT: Invalid parameter!\n")); break; case EFI_DEVICE_ERROR: DEBUG ((DEBUG_ERROR, "EXIT: ACPI table is incorrect or not supported by parser!\n")); break; case EFI_NOT_FOUND: DEBUG ((DEBUG_ERROR, "EXIT: No entry found in the table.\n")); break; case EFI_OUT_OF_RESOURCES: DEBUG ((DEBUG_ERROR, "EXIT: ACPI table has too much nesting!\n")); break; case EFI_LOAD_ERROR: DEBUG ((DEBUG_ERROR, "EXIT: File error in table file!\n")); break; default: DEBUG ((DEBUG_ERROR, "EXIT: Unknown error!\n")); break; } } /** Finds offset of required entry in ACPI table in case it exists. @param[in] FileName Path to file containing ACPI table. @param[in] PathString Path to entry which must be found. @param[in] Entry Number of entry which must be found. @param[out] Offset Offset of the entry if it was found. @retval EFI_SUCCESS Required entry was found. @retval EFI_NOT_FOUND Required entry was not found. @retval EFI_DEVICE_ERROR Error occured during parsing ACPI table. @retval EFI_OUT_OF_RESOURCES Nesting limit has been reached. @retval EFI_INVALID_PARAMETER Got wrong path to the entry. @retval EFI_LOAD_ERROR Wrong path to the file or the file can't be opened. **/ STATIC EFI_STATUS AcpiFindEntryInFile ( IN CONST CHAR8 *FileName, IN CONST CHAR8 *PathString, IN UINT8 Entry, OUT UINT32 *Offset ) { UINT8 *TableStart; EFI_STATUS Status; UINT32 TableLength; TableStart = UserReadFile (FileName, &TableLength); if (TableStart == NULL) { DEBUG ((DEBUG_INFO, "No file %a\n", FileName)); return EFI_LOAD_ERROR; } Status = AcpiFindEntryInMemory (TableStart, PathString, Entry, Offset, TableLength); FreePool (TableStart); return Status; } // -[f|a] , CHAR8 ** memory_location , CHAR8 ** path , UINT8 occurance /** Finds sought entry in ACPI table. Usage: ./ACPIe -f FileName Path [Entry] @param[in] FileName Path to file with ACPI table. @param[in] Path Path to required entry. @param[in] Entry Number of required entry. **/ int ENTRY_POINT ( int argc, char *argv[] ) { UINT32 ReturnedOffset; EFI_STATUS Status; #if defined (VERBOSE) && !defined (FUZZING_TEST) PcdGet32 (PcdFixedDebugPrintErrorLevel) |= DEBUG_VERBOSE | DEBUG_INFO; PcdGet32 (PcdDebugPrintErrorLevel) |= DEBUG_VERBOSE | DEBUG_INFO; #endif switch (argc) { case 5: if (((argv[1][0] == '-') && (argv[1][1] == 'f')) || ((argv[1][0] == '-') && (argv[1][1] == 'a'))) { ReturnedOffset = 0; if ((argv[1][0] == '-') && (argv[1][1] == 'f')) { DEBUG ((DEBUG_VERBOSE, "Entered main (file)\n")); Status = AcpiFindEntryInFile ( argv[2], argv[3], atoi (argv[4]), &ReturnedOffset ); if (!EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "Returned offset: %d\n", ReturnedOffset)); } else { PrintParserError (Status); } return 0; } DEBUG ((DEBUG_VERBOSE, "Entered main (address)\n")); Status = AcpiFindEntryInFile ( argv[2], argv[3], atoi (argv[4]), &ReturnedOffset ); if (!EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "Returned offset: %d\n", ReturnedOffset)); } else { PrintParserError (Status); } return 0; } DEBUG ((DEBUG_ERROR, "Usage: ACPIe -f *file* *search path* [number of occurance]\n")); return 2; break; case 4: if (((argv[1][0] == '-') && (argv[1][1] == 'f')) || ((argv[1][0] == '-') && (argv[1][1] == 'a'))) { if ((argv[1][0] == '-') && (argv[1][1] == 'f')) { DEBUG ((DEBUG_VERBOSE, "Entered main (file)\n")); Status = AcpiFindEntryInFile ( argv[2], argv[3], 1, &ReturnedOffset ); if (!EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "Returned offset: %d\n", ReturnedOffset)); } else { PrintParserError (Status); } return 0; } DEBUG ((DEBUG_VERBOSE, "Entered main (address)\n")); Status = AcpiFindEntryInFile ( argv[2], argv[3], 1, &ReturnedOffset ); if (!EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "Returned offset: %d\n", ReturnedOffset)); } else { PrintParserError (Status); } return 0; } DEBUG ((DEBUG_ERROR, "Usage: ACPIe -f *file* *search path* [number of occurance]\n")); return 2; break; default: DEBUG ((DEBUG_ERROR, "Usage: ACPIe -f *file* *search path* [number of occurance]\n")); return 0; break; } return 0; } int LLVMFuzzerTestOneInput ( const uint8_t *Data, size_t Size ) { if (Size > 0) { UINT32 offset = 0; AcpiFindEntryInMemory ( (UINT8 *)Data, "_SB.PCI0.GFX0", 1, &offset, (UINT32)Size ); } return 0; }