diff --git a/UnitTestFrameworkPkg/Test/GoogleTest/Sample/SampleGoogleTest/SampleGoogleTest.cpp b/UnitTestFrameworkPkg/Test/GoogleTest/Sample/SampleGoogleTest/SampleGoogleTest.cpp index 2c2765e1e5..9164f66da3 100644 --- a/UnitTestFrameworkPkg/Test/GoogleTest/Sample/SampleGoogleTest/SampleGoogleTest.cpp +++ b/UnitTestFrameworkPkg/Test/GoogleTest/Sample/SampleGoogleTest/SampleGoogleTest.cpp @@ -12,6 +12,7 @@ extern "C" { #include #include #include + #include } /** @@ -294,6 +295,144 @@ TEST (MacroTestsMessages, MacroTraceMessage) { ASSERT_TRUE (TRUE); } +/** + Sample unit test that performs double free +**/ +TEST (SanitizerTests, DoubleFreeDeathTest) { + UINT8 *Pointer; + + Pointer = (UINT8 *)AllocatePool (100); + ASSERT_NE (Pointer, (UINT8 *)NULL); + FreePool (Pointer); + // + // Second free that should be caught by address sanitizer, log details, and exit + // + EXPECT_DEATH (FreePool (Pointer), "ERROR: AddressSanitizer: heap-use-after-free"); +} + +/** + Sample unit test that performs read past end of allocated buffer +**/ +TEST (SanitizerTests, BufferOverflowReadDeathTest) { + UINT8 *Pointer; + UINT8 Value; + + Pointer = (UINT8 *)AllocatePool (100); + ASSERT_NE (Pointer, (UINT8 *)NULL); + + // + // Read past end of allocated buffer that should be caught by address sanitizer, log details, and exit + // + EXPECT_DEATH (Value = Pointer[110], "ERROR: AddressSanitizer: heap-buffer-overflow"); + ASSERT_EQ (Value, Value); + + FreePool (Pointer); +} + +/** + Sample unit test that performs write past end of allocated buffer +**/ +TEST (SanitizerTests, BufferOverflowWriteDeathTest) { + UINT8 *Pointer; + + Pointer = (UINT8 *)AllocatePool (100); + ASSERT_NE (Pointer, (UINT8 *)NULL); + + // + // Write past end of allocated buffer that should be caught by address sanitizer, log details, and exit + // + EXPECT_DEATH (Pointer[110] = 0, "ERROR: AddressSanitizer: heap-buffer-overflow"); + + FreePool (Pointer); +} + +/** + Sample unit test that performs read before beginning of allocated buffer +**/ +TEST (SanitizerTests, BufferUnderflowReadDeathTest) { + UINT8 *Pointer; + UINT8 Value; + + Pointer = (UINT8 *)AllocatePool (100); + ASSERT_NE (Pointer, (UINT8 *)NULL); + + // + // Read past end of allocated buffer that should be caught by address sanitizer, log details, and exit + // + EXPECT_DEATH (Value = Pointer[-10], "ERROR: AddressSanitizer: heap-buffer-overflow"); + ASSERT_EQ (Value, Value); + + FreePool (Pointer); +} + +/** + Sample unit test that performs read from address 0 (NULL) +**/ +TEST (SanitizerTests, NullPointerReadDeathTest) { + UINT8 Value; + + // + // Read from address 0 should be caught by address sanitizer, log details, and exit + // + EXPECT_DEATH (Value = *(volatile UINT8 *)(NULL), "ERROR: AddressSanitizer: "); + ASSERT_EQ (Value, Value); +} + +/** + Sample unit test that performs write to address 0 (NULL) +**/ +TEST (SanitizerTests, NullPointerWriteDeathTest) { + // + // Write to address 0 should be caught by address sanitizer, log details, and exit + // + EXPECT_DEATH (*(volatile UINT8 *)(NULL) = 0, "ERROR: AddressSanitizer: "); +} + +/** + Sample unit test that performs read from invalid address -1 +**/ +TEST (SanitizerTests, InvalidPointerReadDeathTest) { + UINT8 Value; + + // + // Read from address -1 should be caught by address sanitizer, log details, and exit + // + EXPECT_DEATH (Value = *(volatile UINT8 *)(-1), "ERROR: AddressSanitizer: "); + ASSERT_EQ (Value, Value); +} + +/** + Sample unit test that performs write to invalid address -1 +**/ +TEST (SanitizerTests, InvalidPointerWriteDeathTest) { + // + // Write to address -1 should be caught by address sanitizer, log details, and exit + // + EXPECT_DEATH (*(volatile UINT8 *)(-1) = 0, "ERROR: AddressSanitizer: "); +} + +UINTN +DivideWithNoParameterChecking ( + UINTN Dividend, + UINTN Divisor + ) +{ + // + // Perform integer division with no check for divide by zero + // + return (Dividend / Divisor); +} + +/** + Sample unit test that performs a divide by 0 +**/ +TEST (SanitizerTests, DivideByZeroDeathTest) { + // + // Divide by 0 should be caught by address sanitizer, log details, and exit + // + EXPECT_DEATH (DivideWithNoParameterChecking (10, 0), "ERROR: AddressSanitizer: "); +} + int main ( int argc, diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestBufferOverflow/SampleUnitTestBufferOverflow.c b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestBufferOverflow/SampleUnitTestBufferOverflow.c new file mode 100644 index 0000000000..1244854e41 --- /dev/null +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestBufferOverflow/SampleUnitTestBufferOverflow.c @@ -0,0 +1,117 @@ +/** @file + Sample UnitTest built for execution on a Host machine. + This test case generates a buffer overflow that is caught by a sanitizer. + + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include +#include +#include +#include +#include +#include +#include + +#define UNIT_TEST_NAME "Sample Unit Test Sanitize Buffer Overflow" +#define UNIT_TEST_VERSION "0.1" + +/** + Sample unit test the performs a buffer overflow + + @param[in] Context [Optional] An optional parameter that enables: + 1) test-case reuse with varied parameters and + 2) test-case re-entry for Target tests that need a + reboot. This parameter is a VOID* and it is the + responsibility of the test author to ensure that the + contents are well understood by all test cases that may + consume it. + + @retval UNIT_TEST_PASSED The Unit test has completed and the test + case was successful. + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. +**/ +UNIT_TEST_STATUS +EFIAPI +SanitizeBufferOverflow ( + IN UNIT_TEST_CONTEXT Context + ) +{ + UINT8 *Pointer; + + Pointer = (UINT8 *)AllocatePool (100); + UT_ASSERT_NOT_NULL (Pointer); + Pointer[110] = 0; + FreePool (Pointer); + + return UNIT_TEST_PASSED; +} + +/** + Initialize the unit test framework, suite, and unit tests for the + sample unit tests and run the unit tests. + + @retval EFI_SUCCESS All test cases were dispatched. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to + initialize the unit tests. +**/ +EFI_STATUS +EFIAPI +UefiTestMain ( + VOID + ) +{ + EFI_STATUS Status; + UNIT_TEST_FRAMEWORK_HANDLE Framework; + UNIT_TEST_SUITE_HANDLE SanitizeTests; + + Framework = NULL; + + DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_NAME, UNIT_TEST_VERSION)); + + // + // Start setting up the test framework for running the tests. + // + Status = InitUnitTestFramework (&Framework, UNIT_TEST_NAME, gEfiCallerBaseName, UNIT_TEST_VERSION); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", Status)); + goto EXIT; + } + + // + // Populate the Macro Tests with ASSERT() enabled + // + Status = CreateUnitTestSuite (&SanitizeTests, Framework, "Sanitize tests", "Sanitize tests", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for SanitizeTests\n")); + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + + AddTestCase (SanitizeTests, "Sanitize Buffer Overflow", "SanitizeBufferOverflow", SanitizeBufferOverflow, NULL, NULL, NULL); + + // + // Execute the tests. + // + Status = RunAllTestSuites (Framework); + +EXIT: + if (Framework) { + FreeUnitTestFramework (Framework); + } + + return Status; +} + +/** + Standard POSIX C entry point for host based unit test execution. +**/ +int +main ( + int argc, + char *argv[] + ) +{ + return UefiTestMain (); +} diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestBufferOverflow/SampleUnitTestBufferOverflow.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestBufferOverflow/SampleUnitTestBufferOverflow.inf new file mode 100644 index 0000000000..7f4c8aedf9 --- /dev/null +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestBufferOverflow/SampleUnitTestBufferOverflow.inf @@ -0,0 +1,32 @@ +## @file +# Sample UnitTest built for execution on a Host machine. +# This test case generates a buffer overflow that is caught by a sanitizer. +# +# Copyright (c) 2024, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SampleUnitTestBufferOverflow + FILE_GUID = 3772390C-CF33-4826-BB2F-A279C1AC12E0 + MODULE_TYPE = HOST_APPLICATION + VERSION_STRING = 1.0 + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + SampleUnitTestBufferOverflow.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + DebugLib + UnitTestLib + MemoryAllocationLib diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestBufferUnderflow/SampleUnitTestBufferUnderflow.c b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestBufferUnderflow/SampleUnitTestBufferUnderflow.c new file mode 100644 index 0000000000..3159af439e --- /dev/null +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestBufferUnderflow/SampleUnitTestBufferUnderflow.c @@ -0,0 +1,117 @@ +/** @file + Sample UnitTest built for execution on a Host machine. + This test case generates a buffer underflow that is caught by a sanitizer. + + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include +#include +#include +#include +#include +#include +#include + +#define UNIT_TEST_NAME "Sample Unit Test Sanitize Buffer Underflow" +#define UNIT_TEST_VERSION "0.1" + +/** + Sample unit test the performs a buffer underflow + + @param[in] Context [Optional] An optional parameter that enables: + 1) test-case reuse with varied parameters and + 2) test-case re-entry for Target tests that need a + reboot. This parameter is a VOID* and it is the + responsibility of the test author to ensure that the + contents are well understood by all test cases that may + consume it. + + @retval UNIT_TEST_PASSED The Unit test has completed and the test + case was successful. + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. +**/ +UNIT_TEST_STATUS +EFIAPI +SanitizeBufferUnderflow ( + IN UNIT_TEST_CONTEXT Context + ) +{ + UINT8 *Pointer; + + Pointer = (UINT8 *)AllocatePool (100); + UT_ASSERT_NOT_NULL (Pointer); + Pointer[-10] = 0; + FreePool (Pointer); + + return UNIT_TEST_PASSED; +} + +/** + Initialize the unit test framework, suite, and unit tests for the + sample unit tests and run the unit tests. + + @retval EFI_SUCCESS All test cases were dispatched. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to + initialize the unit tests. +**/ +EFI_STATUS +EFIAPI +UefiTestMain ( + VOID + ) +{ + EFI_STATUS Status; + UNIT_TEST_FRAMEWORK_HANDLE Framework; + UNIT_TEST_SUITE_HANDLE SanitizeTests; + + Framework = NULL; + + DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_NAME, UNIT_TEST_VERSION)); + + // + // Start setting up the test framework for running the tests. + // + Status = InitUnitTestFramework (&Framework, UNIT_TEST_NAME, gEfiCallerBaseName, UNIT_TEST_VERSION); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", Status)); + goto EXIT; + } + + // + // Populate the Macro Tests with ASSERT() enabled + // + Status = CreateUnitTestSuite (&SanitizeTests, Framework, "Sanitize tests", "Sanitize tests", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for SanitizeTests\n")); + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + + AddTestCase (SanitizeTests, "Sanitize Buffer Underflow", "SanitizeBufferUnderflow", SanitizeBufferUnderflow, NULL, NULL, NULL); + + // + // Execute the tests. + // + Status = RunAllTestSuites (Framework); + +EXIT: + if (Framework) { + FreeUnitTestFramework (Framework); + } + + return Status; +} + +/** + Standard POSIX C entry point for host based unit test execution. +**/ +int +main ( + int argc, + char *argv[] + ) +{ + return UefiTestMain (); +} diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestBufferUnderflow/SampleUnitTestBufferUnderflow.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestBufferUnderflow/SampleUnitTestBufferUnderflow.inf new file mode 100644 index 0000000000..eccff61dfd --- /dev/null +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestBufferUnderflow/SampleUnitTestBufferUnderflow.inf @@ -0,0 +1,32 @@ +## @file +# Sample UnitTest built for execution on a Host machine. +# This test case generates a buffer underflow that is caught by a sanitizer. +# +# Copyright (c) 2024, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SampleUnitTestBufferUnderflow + FILE_GUID = ECA331D2-D794-4798-B145-770A570F3309 + MODULE_TYPE = HOST_APPLICATION + VERSION_STRING = 1.0 + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + SampleUnitTestBufferUnderflow.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + DebugLib + UnitTestLib + MemoryAllocationLib diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestDoubleFree/SampleUnitTestDoubleFree.c b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestDoubleFree/SampleUnitTestDoubleFree.c new file mode 100644 index 0000000000..8c635e8a16 --- /dev/null +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestDoubleFree/SampleUnitTestDoubleFree.c @@ -0,0 +1,117 @@ +/** @file + Sample UnitTest built for execution on a Host machine. + This test case generates a double free that is caught by a sanitizer. + + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include +#include +#include +#include +#include +#include +#include + +#define UNIT_TEST_NAME "Sample Unit Test Sanitize Double Free" +#define UNIT_TEST_VERSION "0.1" + +/** + Sample unit test the performs a double free + + @param[in] Context [Optional] An optional parameter that enables: + 1) test-case reuse with varied parameters and + 2) test-case re-entry for Target tests that need a + reboot. This parameter is a VOID* and it is the + responsibility of the test author to ensure that the + contents are well understood by all test cases that may + consume it. + + @retval UNIT_TEST_PASSED The Unit test has completed and the test + case was successful. + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. +**/ +UNIT_TEST_STATUS +EFIAPI +SanitizeDoubleFree ( + IN UNIT_TEST_CONTEXT Context + ) +{ + UINT8 *Pointer; + + Pointer = (UINT8 *)AllocatePool (100); + UT_ASSERT_NOT_NULL (Pointer); + FreePool (Pointer); + FreePool (Pointer); + + return UNIT_TEST_PASSED; +} + +/** + Initialize the unit test framework, suite, and unit tests for the + sample unit tests and run the unit tests. + + @retval EFI_SUCCESS All test cases were dispatched. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to + initialize the unit tests. +**/ +EFI_STATUS +EFIAPI +UefiTestMain ( + VOID + ) +{ + EFI_STATUS Status; + UNIT_TEST_FRAMEWORK_HANDLE Framework; + UNIT_TEST_SUITE_HANDLE SanitizeTests; + + Framework = NULL; + + DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_NAME, UNIT_TEST_VERSION)); + + // + // Start setting up the test framework for running the tests. + // + Status = InitUnitTestFramework (&Framework, UNIT_TEST_NAME, gEfiCallerBaseName, UNIT_TEST_VERSION); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", Status)); + goto EXIT; + } + + // + // Populate the Macro Tests with ASSERT() enabled + // + Status = CreateUnitTestSuite (&SanitizeTests, Framework, "Sanitize tests", "Sanitize tests", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for SanitizeTests\n")); + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + + AddTestCase (SanitizeTests, "Sanitize Double Free", "SanitizeDoubleFree", SanitizeDoubleFree, NULL, NULL, NULL); + + // + // Execute the tests. + // + Status = RunAllTestSuites (Framework); + +EXIT: + if (Framework) { + FreeUnitTestFramework (Framework); + } + + return Status; +} + +/** + Standard POSIX C entry point for host based unit test execution. +**/ +int +main ( + int argc, + char *argv[] + ) +{ + return UefiTestMain (); +} diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestDoubleFree/SampleUnitTestDoubleFree.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestDoubleFree/SampleUnitTestDoubleFree.inf new file mode 100644 index 0000000000..9903a82886 --- /dev/null +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestDoubleFree/SampleUnitTestDoubleFree.inf @@ -0,0 +1,32 @@ +## @file +# Sample UnitTest built for execution on a Host machine. +# This test case generates a double free that is caught by a sanitizer. +# +# Copyright (c) 2024, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SampleUnitTestDoubleFree + FILE_GUID = B40BBE1C-90AB-4DE9-9B49-E734666FF9A7 + MODULE_TYPE = HOST_APPLICATION + VERSION_STRING = 1.0 + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + SampleUnitTestDoubleFree.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + DebugLib + UnitTestLib + MemoryAllocationLib diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestInvalidAddress/SampleUnitTestInvalidAddress.c b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestInvalidAddress/SampleUnitTestInvalidAddress.c new file mode 100644 index 0000000000..bb4e5bcd2f --- /dev/null +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestInvalidAddress/SampleUnitTestInvalidAddress.c @@ -0,0 +1,110 @@ +/** @file + Sample UnitTest built for execution on a Host machine. + This test case accesses an invalid address that is caught by a sanitizer. + + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include +#include +#include +#include +#include +#include + +#define UNIT_TEST_NAME "Sample Unit Test Sanitize Invalid Address" +#define UNIT_TEST_VERSION "0.1" + +/** + Sample unit test that accesses an invalid address + + @param[in] Context [Optional] An optional parameter that enables: + 1) test-case reuse with varied parameters and + 2) test-case re-entry for Target tests that need a + reboot. This parameter is a VOID* and it is the + responsibility of the test author to ensure that the + contents are well understood by all test cases that may + consume it. + + @retval UNIT_TEST_PASSED The Unit test has completed and the test + case was successful. + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. +**/ +UNIT_TEST_STATUS +EFIAPI +SanitizeInvalidAddress ( + IN UNIT_TEST_CONTEXT Context + ) +{ + *(volatile UINT8 *)(-1) = 0; + return UNIT_TEST_PASSED; +} + +/** + Initialize the unit test framework, suite, and unit tests for the + sample unit tests and run the unit tests. + + @retval EFI_SUCCESS All test cases were dispatched. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to + initialize the unit tests. +**/ +EFI_STATUS +EFIAPI +UefiTestMain ( + VOID + ) +{ + EFI_STATUS Status; + UNIT_TEST_FRAMEWORK_HANDLE Framework; + UNIT_TEST_SUITE_HANDLE SanitizeTests; + + Framework = NULL; + + DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_NAME, UNIT_TEST_VERSION)); + + // + // Start setting up the test framework for running the tests. + // + Status = InitUnitTestFramework (&Framework, UNIT_TEST_NAME, gEfiCallerBaseName, UNIT_TEST_VERSION); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", Status)); + goto EXIT; + } + + // + // Populate the Macro Tests with ASSERT() enabled + // + Status = CreateUnitTestSuite (&SanitizeTests, Framework, "Sanitize tests", "Sanitize tests", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for SanitizeTests\n")); + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + + AddTestCase (SanitizeTests, "Sanitize Invalid Address", "SanitizeInvalidAddress", SanitizeInvalidAddress, NULL, NULL, NULL); + + // + // Execute the tests. + // + Status = RunAllTestSuites (Framework); + +EXIT: + if (Framework) { + FreeUnitTestFramework (Framework); + } + + return Status; +} + +/** + Standard POSIX C entry point for host based unit test execution. +**/ +int +main ( + int argc, + char *argv[] + ) +{ + return UefiTestMain (); +} diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestInvalidAddress/SampleUnitTestInvalidAddress.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestInvalidAddress/SampleUnitTestInvalidAddress.inf new file mode 100644 index 0000000000..1804f28641 --- /dev/null +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestInvalidAddress/SampleUnitTestInvalidAddress.inf @@ -0,0 +1,31 @@ +## @file +# Sample UnitTest built for execution on a Host machine. +# This test case accesses an invalid address that is caught by a sanitizer. +# +# Copyright (c) 2024, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SampleUnitTestInvalidAddress + FILE_GUID = 60CED393-1342-45E9-9D8B-589F02255674 + MODULE_TYPE = HOST_APPLICATION + VERSION_STRING = 1.0 + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + SampleUnitTestInvalidAddress.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + DebugLib + UnitTestLib diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestNullAddress/SampleUnitTestNullAddress.c b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestNullAddress/SampleUnitTestNullAddress.c new file mode 100644 index 0000000000..c7e9028aaa --- /dev/null +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestNullAddress/SampleUnitTestNullAddress.c @@ -0,0 +1,110 @@ +/** @file + Sample UnitTest built for execution on a Host machine. + This test case dereferences a NULL pointer that is caught by a sanitizer. + + Copyright (c) 2024, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include +#include +#include +#include +#include +#include + +#define UNIT_TEST_NAME "Sample Unit Test Sanitize NULL Pointer" +#define UNIT_TEST_VERSION "0.1" + +/** + Sample unit test that dereferences a NULL pointer. + + @param[in] Context [Optional] An optional parameter that enables: + 1) test-case reuse with varied parameters and + 2) test-case re-entry for Target tests that need a + reboot. This parameter is a VOID* and it is the + responsibility of the test author to ensure that the + contents are well understood by all test cases that may + consume it. + + @retval UNIT_TEST_PASSED The Unit test has completed and the test + case was successful. + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed. +**/ +UNIT_TEST_STATUS +EFIAPI +SanitizeNullAddress ( + IN UNIT_TEST_CONTEXT Context + ) +{ + *(volatile UINT8 *)(NULL) = 0; + return UNIT_TEST_PASSED; +} + +/** + Initialize the unit test framework, suite, and unit tests for the + sample unit tests and run the unit tests. + + @retval EFI_SUCCESS All test cases were dispatched. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to + initialize the unit tests. +**/ +EFI_STATUS +EFIAPI +UefiTestMain ( + VOID + ) +{ + EFI_STATUS Status; + UNIT_TEST_FRAMEWORK_HANDLE Framework; + UNIT_TEST_SUITE_HANDLE SanitizeTests; + + Framework = NULL; + + DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_NAME, UNIT_TEST_VERSION)); + + // + // Start setting up the test framework for running the tests. + // + Status = InitUnitTestFramework (&Framework, UNIT_TEST_NAME, gEfiCallerBaseName, UNIT_TEST_VERSION); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", Status)); + goto EXIT; + } + + // + // Populate the Macro Tests with ASSERT() enabled + // + Status = CreateUnitTestSuite (&SanitizeTests, Framework, "Sanitize tests", "Sanitize tests", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for SanitizeTests\n")); + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + + AddTestCase (SanitizeTests, "Sanitize NULL Address", "SanitizeNullAddress", SanitizeNullAddress, NULL, NULL, NULL); + + // + // Execute the tests. + // + Status = RunAllTestSuites (Framework); + +EXIT: + if (Framework) { + FreeUnitTestFramework (Framework); + } + + return Status; +} + +/** + Standard POSIX C entry point for host based unit test execution. +**/ +int +main ( + int argc, + char *argv[] + ) +{ + return UefiTestMain (); +} diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestNullAddress/SampleUnitTestNullAddress.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestNullAddress/SampleUnitTestNullAddress.inf new file mode 100644 index 0000000000..0b7e8af3ce --- /dev/null +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestNullAddress/SampleUnitTestNullAddress.inf @@ -0,0 +1,31 @@ +## @file +# Sample UnitTest built for execution on a Host machine. +# This test case dereferences a NULL pointer that is caught by a sanitizer. +# +# Copyright (c) 2024, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SampleUnitTestNullAddress + FILE_GUID = FDD2EFA0-74BE-4628-A860-A60EF81B9023 + MODULE_TYPE = HOST_APPLICATION + VERSION_STRING = 1.0 + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + SampleUnitTestNullAddress.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + DebugLib + UnitTestLib diff --git a/UnitTestFrameworkPkg/Test/UnitTestFrameworkPkgHostTestExpectFail.dsc b/UnitTestFrameworkPkg/Test/UnitTestFrameworkPkgHostTestExpectFail.dsc index face95d6c2..73b4cb1b92 100644 --- a/UnitTestFrameworkPkg/Test/UnitTestFrameworkPkgHostTestExpectFail.dsc +++ b/UnitTestFrameworkPkg/Test/UnitTestFrameworkPkgHostTestExpectFail.dsc @@ -1,8 +1,13 @@ ## @file -# UnitTestFrameworkPkg DSC file used to build host-based unit tests that archive +# UnitTestFrameworkPkg DSC file used to build host-based unit tests that are # always expected to fail to demonstrate the format of the log file and reports # when failures occur. # +# For Google Test based unit tests, in order to see full log of errors from the +# sanitizer, the Google Test handling of exceptions must be disabled by either +# setting the environment variable GTEST_CATCH_EXCEPTIONS=0 or passing +# --gtest-catch-exceptions=0 on the command line when executing unit tests. +# # Copyright (c) 2024, Intel Corporation. All rights reserved.
# SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -42,3 +47,12 @@ MSFT:*_*_*_CC_FLAGS = /wd4723 } + + # + # Unit tests that perform illegal actions that are caught by a sanitizer + # + UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestDoubleFree/SampleUnitTestDoubleFree.inf + UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestBufferOverflow/SampleUnitTestBufferOverflow.inf + UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestBufferUnderflow/SampleUnitTestBufferUnderflow.inf + UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestNullAddress/SampleUnitTestNullAddress.inf + UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestInvalidAddress/SampleUnitTestInvalidAddress.inf diff --git a/UnitTestFrameworkPkg/UnitTestFrameworkPkg.ci.yaml b/UnitTestFrameworkPkg/UnitTestFrameworkPkg.ci.yaml index c6a412c960..cf51b21e00 100644 --- a/UnitTestFrameworkPkg/UnitTestFrameworkPkg.ci.yaml +++ b/UnitTestFrameworkPkg/UnitTestFrameworkPkg.ci.yaml @@ -66,7 +66,12 @@ "UnitTestFrameworkPkg/Test/GoogleTest/Sample/SampleGoogleTestExpectFail/SampleGoogleTestHostExpectFail.inf", "UnitTestFrameworkPkg/Test/GoogleTest/Sample/SampleGoogleTestGenerateException/SampleGoogleTestHostGenerateException.inf", "UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestHostExpectFail.inf", - "UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestHostGenerateException.inf" + "UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestHostGenerateException.inf", + "UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestDoubleFree/SampleUnitTestDoubleFree.inf", + "UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestBufferOverflow/SampleUnitTestBufferOverflow.inf", + "UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestBufferUnderflow/SampleUnitTestBufferUnderflow.inf", + "UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestNullAddress/SampleUnitTestNullAddress.inf", + "UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestInvalidAddress/SampleUnitTestInvalidAddress.inf" ], "DscPath": "Test/UnitTestFrameworkPkgHostTest.dsc" },