summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2021-07-19 15:41:44 -0400
committerEdward Thomson <ethomson@edwardthomson.com>2021-07-19 15:41:44 -0400
commit48e6b02be9b0639fdc25e17514f11d7ef141dfbc (patch)
tree227f303f7bccc8b5d5dad21dcbc36f888729823e
parent6a7f04030e124855c3e617a21c814074a2585753 (diff)
downloadlibgit2-48e6b02be9b0639fdc25e17514f11d7ef141dfbc.tar.gz
alloc: add GIT_DEBUG_STRICT_ALLOC
Add `GIT_DEBUG_STRICT_ALLOC` to help identify problematic callers of allocation code that pass a `0` size to the allocators and then expect a non-`NULL` return. When given a 0-size allocation, `malloc` _may_ return either a `NULL` _or_ a pointer that is not writeable. Most systems return a non-`NULL` pointer; AIX is an outlier. We should be able to cope with this AIXy behavior, so this adds an option to emulate it.
-rw-r--r--CMakeLists.txt1
-rw-r--r--src/CMakeLists.txt5
-rw-r--r--src/allocators/stdalloc.c51
-rw-r--r--src/features.h.in2
4 files changed, 49 insertions, 10 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 655697979..58214fd0e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -49,6 +49,7 @@ OPTION(USE_GSSAPI "Link with libgssapi for SPNEGO auth" OFF)
OPTION(USE_STANDALONE_FUZZERS "Enable standalone fuzzers (compatible with gcc)" OFF)
OPTION(USE_LEAK_CHECKER "Run tests with leak checker" OFF)
OPTION(DEBUG_POOL "Enable debug pool allocator" OFF)
+OPTION(DEBUG_STRICT_ALLOC "Enable strict allocator behavior" OFF)
OPTION(ENABLE_WERROR "Enable compilation with -Werror" OFF)
OPTION(USE_BUNDLED_ZLIB "Use the bundled version of zlib. Can be set to one of Bundled(ON)/Chromium. The Chromium option requires a x86_64 processor with SSE4.2 and CLMUL" OFF)
SET(USE_HTTP_PARSER "" CACHE STRING "Specifies the HTTP Parser implementation; either system or builtin.")
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 4fde16d8a..8d1559551 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -6,6 +6,11 @@ IF(DEBUG_POOL)
ENDIF()
ADD_FEATURE_INFO(debugpool GIT_DEBUG_POOL "debug pool allocator")
+IF(DEBUG_STRICT_ALLOC)
+ SET(GIT_DEBUG_STRICT_ALLOC 1)
+ENDIF()
+ADD_FEATURE_INFO(debugalloc GIT_DEBUG_STRICT_ALLOC "debug strict allocators")
+
INCLUDE(PkgBuildConfig)
INCLUDE(SanitizeBool)
diff --git a/src/allocators/stdalloc.c b/src/allocators/stdalloc.c
index c4938e32b..7215468b6 100644
--- a/src/allocators/stdalloc.c
+++ b/src/allocators/stdalloc.c
@@ -9,34 +9,56 @@
static void *stdalloc__malloc(size_t len, const char *file, int line)
{
- void *ptr = malloc(len);
+ void *ptr;
GIT_UNUSED(file);
GIT_UNUSED(line);
- if (!ptr) git_error_set_oom();
+#ifdef GIT_DEBUG_STRICT_ALLOC
+ if (!len)
+ return NULL;
+#endif
+
+ ptr = malloc(len);
+
+ if (!ptr)
+ git_error_set_oom();
+
return ptr;
}
static void *stdalloc__calloc(size_t nelem, size_t elsize, const char *file, int line)
{
- void *ptr = calloc(nelem, elsize);
+ void *ptr;
GIT_UNUSED(file);
GIT_UNUSED(line);
- if (!ptr) git_error_set_oom();
+#ifdef GIT_DEBUG_STRICT_ALLOC
+ if (!elsize)
+ return NULL;
+#endif
+
+ ptr = calloc(nelem, elsize);
+
+ if (!ptr)
+ git_error_set_oom();
+
return ptr;
}
static char *stdalloc__strdup(const char *str, const char *file, int line)
{
- char *ptr = strdup(str);
+ char *ptr;
GIT_UNUSED(file);
GIT_UNUSED(line);
- if (!ptr) git_error_set_oom();
+ ptr = strdup(str);
+
+ if (!ptr)
+ git_error_set_oom();
+
return ptr;
}
@@ -48,7 +70,7 @@ static char *stdalloc__strndup(const char *str, size_t n, const char *file, int
length = p_strnlen(str, n);
if (GIT_ADD_SIZET_OVERFLOW(&alloclength, length, 1) ||
- !(ptr = stdalloc__malloc(alloclength, file, line)))
+ !(ptr = stdalloc__malloc(alloclength, file, line)))
return NULL;
if (length)
@@ -65,7 +87,7 @@ static char *stdalloc__substrdup(const char *start, size_t n, const char *file,
size_t alloclen;
if (GIT_ADD_SIZET_OVERFLOW(&alloclen, n, 1) ||
- !(ptr = stdalloc__malloc(alloclen, file, line)))
+ !(ptr = stdalloc__malloc(alloclen, file, line)))
return NULL;
memcpy(ptr, start, n);
@@ -75,12 +97,21 @@ static char *stdalloc__substrdup(const char *start, size_t n, const char *file,
static void *stdalloc__realloc(void *ptr, size_t size, const char *file, int line)
{
- void *new_ptr = realloc(ptr, size);
+ void *new_ptr;
GIT_UNUSED(file);
GIT_UNUSED(line);
- if (!new_ptr) git_error_set_oom();
+#ifdef GIT_DEBUG_STRICT_ALLOC
+ if (!size)
+ return NULL;
+#endif
+
+ new_ptr = realloc(ptr, size);
+
+ if (!new_ptr)
+ git_error_set_oom();
+
return new_ptr;
}
diff --git a/src/features.h.in b/src/features.h.in
index c8d01804f..ab523f90b 100644
--- a/src/features.h.in
+++ b/src/features.h.in
@@ -2,6 +2,8 @@
#define INCLUDE_features_h__
#cmakedefine GIT_DEBUG_POOL 1
+#cmakedefine GIT_DEBUG_STRICT_ALLOC 1
+
#cmakedefine GIT_TRACE 1
#cmakedefine GIT_THREADS 1
#cmakedefine GIT_WIN32_LEAKCHECK 1