From 189085d03ad7e9aaab427b344ac2888d328292f4 Mon Sep 17 00:00:00 2001 From: jsalling Date: Fri, 5 Feb 2016 18:56:44 -0600 Subject: [PATCH 1/2] Check for writes to guard space on malloc'd buffers in Fixture There was already some space reserved as a guard, added check for writes before the beginning of the buffer. Did not change the 'overrun' message. Underrun buffer writes are likely to be a more rare case. --- extras/fixture/src/unity_fixture.c | 5 ++- extras/fixture/test/unity_fixture_Test.c | 41 +++++++++++++++++++ .../fixture/test/unity_fixture_TestRunner.c | 2 + 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/extras/fixture/src/unity_fixture.c b/extras/fixture/src/unity_fixture.c index c8275f4..b20657d 100644 --- a/extras/fixture/src/unity_fixture.c +++ b/extras/fixture/src/unity_fixture.c @@ -166,7 +166,7 @@ static unsigned int heap_index; typedef struct GuardBytes { size_t size; - char guard_space[4]; + size_t guard_space; } Guard; @@ -202,6 +202,7 @@ void* unity_malloc(size_t size) if (guard == NULL) return NULL; malloc_count++; guard->size = size; + guard->guard_space = 0; mem = (char*)&(guard[1]); memcpy(&mem[size], end, sizeof(end)); @@ -214,7 +215,7 @@ static int isOverrun(void* mem) char* memAsChar = (char*)mem; guard--; - return strcmp(&memAsChar[guard->size], end) != 0; + return guard->guard_space != 0 || strcmp(&memAsChar[guard->size], end) != 0; } static void release_memory(void* mem) diff --git a/extras/fixture/test/unity_fixture_Test.c b/extras/fixture/test/unity_fixture_Test.c index 9ca3bfd..f1df378 100644 --- a/extras/fixture/test/unity_fixture_Test.c +++ b/extras/fixture/test/unity_fixture_Test.c @@ -381,6 +381,47 @@ TEST(LeakDetection, BufferOverrunFoundDuringRealloc) #endif } +TEST(LeakDetection, BufferGuardWriteFoundDuringFree) +{ +#ifndef USING_OUTPUT_SPY + UNITY_PRINT_EOL(); + TEST_IGNORE(); +#else + void* m = malloc(10); + TEST_ASSERT_NOT_NULL(m); + char* s = (char*)m; + s[-1] = (char)0x00; // Will not detect 0 + s[-2] = (char)0x01; + UnityOutputCharSpy_Enable(1); + EXPECT_ABORT_BEGIN + free(m); + EXPECT_ABORT_END + UnityOutputCharSpy_Enable(0); + Unity.CurrentTestFailed = 0; + CHECK(strstr(UnityOutputCharSpy_Get(), "Buffer overrun detected during free()")); +#endif +} + +TEST(LeakDetection, BufferGuardWriteFoundDuringRealloc) +{ +#ifndef USING_OUTPUT_SPY + UNITY_PRINT_EOL(); + TEST_IGNORE(); +#else + void* m = malloc(10); + TEST_ASSERT_NOT_NULL(m); + char* s = (char*)m; + s[-1] = (char)0x0A; + UnityOutputCharSpy_Enable(1); + EXPECT_ABORT_BEGIN + m = realloc(m, 100); + EXPECT_ABORT_END + UnityOutputCharSpy_Enable(0); + Unity.CurrentTestFailed = 0; + CHECK(strstr(UnityOutputCharSpy_Get(), "Buffer overrun detected during realloc()")); +#endif +} + TEST_GROUP(InternalMalloc); TEST_SETUP(InternalMalloc) { } diff --git a/extras/fixture/test/unity_fixture_TestRunner.c b/extras/fixture/test/unity_fixture_TestRunner.c index 4f5eefc..bc0bf5a 100644 --- a/extras/fixture/test/unity_fixture_TestRunner.c +++ b/extras/fixture/test/unity_fixture_TestRunner.c @@ -40,6 +40,8 @@ TEST_GROUP_RUNNER(LeakDetection) RUN_TEST_CASE(LeakDetection, DetectsLeak); RUN_TEST_CASE(LeakDetection, BufferOverrunFoundDuringFree); RUN_TEST_CASE(LeakDetection, BufferOverrunFoundDuringRealloc); + RUN_TEST_CASE(LeakDetection, BufferGuardWriteFoundDuringFree); + RUN_TEST_CASE(LeakDetection, BufferGuardWriteFoundDuringRealloc); } TEST_GROUP_RUNNER(InternalMalloc) From 4c384658e549f55de56da6f262abf408c50a0d21 Mon Sep 17 00:00:00 2001 From: jsalling Date: Fri, 5 Feb 2016 21:48:23 -0600 Subject: [PATCH 2/2] Move makefile output to build/ dir for Fixture testing --- extras/fixture/test/Makefile | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/extras/fixture/test/Makefile b/extras/fixture/test/Makefile index 8888d6f..8f9a324 100644 --- a/extras/fixture/test/Makefile +++ b/extras/fixture/test/Makefile @@ -12,24 +12,27 @@ SRC = ../src/unity_fixture.c \ main/AllTests.c INC_DIR = -I../src -I../../../src/ -TARGET = fixture_tests.exe +TARGET = ../build/fixture_tests.exe all: default noStdlibMalloc 32bits -default: +default: ../build/ $(CC) $(CFLAGS) $(DEFINES) $(SRC) $(INC_DIR) -o $(TARGET) @ echo "default build" ./$(TARGET) -32bits: +32bits: ../build/ $(CC) $(CFLAGS) $(DEFINES) $(SRC) $(INC_DIR) -o $(TARGET) -m32 @ echo "32bits build" ./$(TARGET) -noStdlibMalloc: +noStdlibMalloc: ../build/ $(CC) $(CFLAGS) $(DEFINES) $(SRC) $(INC_DIR) -o $(TARGET) -D UNITY_EXCLUDE_STDLIB_MALLOC @ echo "build with noStdlibMalloc" ./$(TARGET) clangEverything: $(CC) $(CFLAGS) $(DEFINES) $(SRC) $(INC_DIR) -o $(TARGET) -m64 -Weverything # || true #prevents make from failing + +../build : + mkdir -p ../build