Skip to content

Commit 5c5c19a

Browse files
authored
Merge pull request libgit2#5951 from libgit2/ethomson/strict_alloc
Optional stricter allocation checking (for `malloc(0)` cases)
2 parents 6a7f040 + b0980dc commit 5c5c19a

File tree

7 files changed

+68
-22
lines changed

7 files changed

+68
-22
lines changed

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ jobs:
8686
env:
8787
CC: gcc
8888
CMAKE_GENERATOR: Ninja
89-
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DREGEX_BACKEND=builtin -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON
89+
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL -DREGEX_BACKEND=builtin -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON -DDEBUG_STRICT_ALLOC=ON
9090
os: ubuntu-latest
9191
- # Xenial, GCC, mbedTLS
9292
container:

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ OPTION(USE_GSSAPI "Link with libgssapi for SPNEGO auth" OFF)
4949
OPTION(USE_STANDALONE_FUZZERS "Enable standalone fuzzers (compatible with gcc)" OFF)
5050
OPTION(USE_LEAK_CHECKER "Run tests with leak checker" OFF)
5151
OPTION(DEBUG_POOL "Enable debug pool allocator" OFF)
52+
OPTION(DEBUG_STRICT_ALLOC "Enable strict allocator behavior" OFF)
5253
OPTION(ENABLE_WERROR "Enable compilation with -Werror" OFF)
5354
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)
5455
SET(USE_HTTP_PARSER "" CACHE STRING "Specifies the HTTP Parser implementation; either system or builtin.")

src/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ IF(DEBUG_POOL)
66
ENDIF()
77
ADD_FEATURE_INFO(debugpool GIT_DEBUG_POOL "debug pool allocator")
88

9+
IF(DEBUG_STRICT_ALLOC)
10+
SET(GIT_DEBUG_STRICT_ALLOC 1)
11+
ENDIF()
12+
ADD_FEATURE_INFO(debugalloc GIT_DEBUG_STRICT_ALLOC "debug strict allocators")
13+
914
INCLUDE(PkgBuildConfig)
1015
INCLUDE(SanitizeBool)
1116

src/allocators/stdalloc.c

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,34 +9,56 @@
99

1010
static void *stdalloc__malloc(size_t len, const char *file, int line)
1111
{
12-
void *ptr = malloc(len);
12+
void *ptr;
1313

1414
GIT_UNUSED(file);
1515
GIT_UNUSED(line);
1616

17-
if (!ptr) git_error_set_oom();
17+
#ifdef GIT_DEBUG_STRICT_ALLOC
18+
if (!len)
19+
return NULL;
20+
#endif
21+
22+
ptr = malloc(len);
23+
24+
if (!ptr)
25+
git_error_set_oom();
26+
1827
return ptr;
1928
}
2029

2130
static void *stdalloc__calloc(size_t nelem, size_t elsize, const char *file, int line)
2231
{
23-
void *ptr = calloc(nelem, elsize);
32+
void *ptr;
2433

2534
GIT_UNUSED(file);
2635
GIT_UNUSED(line);
2736

28-
if (!ptr) git_error_set_oom();
37+
#ifdef GIT_DEBUG_STRICT_ALLOC
38+
if (!elsize || !nelem)
39+
return NULL;
40+
#endif
41+
42+
ptr = calloc(nelem, elsize);
43+
44+
if (!ptr)
45+
git_error_set_oom();
46+
2947
return ptr;
3048
}
3149

3250
static char *stdalloc__strdup(const char *str, const char *file, int line)
3351
{
34-
char *ptr = strdup(str);
52+
char *ptr;
3553

3654
GIT_UNUSED(file);
3755
GIT_UNUSED(line);
3856

39-
if (!ptr) git_error_set_oom();
57+
ptr = strdup(str);
58+
59+
if (!ptr)
60+
git_error_set_oom();
61+
4062
return ptr;
4163
}
4264

@@ -48,7 +70,7 @@ static char *stdalloc__strndup(const char *str, size_t n, const char *file, int
4870
length = p_strnlen(str, n);
4971

5072
if (GIT_ADD_SIZET_OVERFLOW(&alloclength, length, 1) ||
51-
!(ptr = stdalloc__malloc(alloclength, file, line)))
73+
!(ptr = stdalloc__malloc(alloclength, file, line)))
5274
return NULL;
5375

5476
if (length)
@@ -65,7 +87,7 @@ static char *stdalloc__substrdup(const char *start, size_t n, const char *file,
6587
size_t alloclen;
6688

6789
if (GIT_ADD_SIZET_OVERFLOW(&alloclen, n, 1) ||
68-
!(ptr = stdalloc__malloc(alloclen, file, line)))
90+
!(ptr = stdalloc__malloc(alloclen, file, line)))
6991
return NULL;
7092

7193
memcpy(ptr, start, n);
@@ -75,12 +97,21 @@ static char *stdalloc__substrdup(const char *start, size_t n, const char *file,
7597

7698
static void *stdalloc__realloc(void *ptr, size_t size, const char *file, int line)
7799
{
78-
void *new_ptr = realloc(ptr, size);
100+
void *new_ptr;
79101

80102
GIT_UNUSED(file);
81103
GIT_UNUSED(line);
82104

83-
if (!new_ptr) git_error_set_oom();
105+
#ifdef GIT_DEBUG_STRICT_ALLOC
106+
if (!size)
107+
return NULL;
108+
#endif
109+
110+
new_ptr = realloc(ptr, size);
111+
112+
if (!new_ptr)
113+
git_error_set_oom();
114+
84115
return new_ptr;
85116
}
86117

src/features.h.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
#define INCLUDE_features_h__
33

44
#cmakedefine GIT_DEBUG_POOL 1
5+
#cmakedefine GIT_DEBUG_STRICT_ALLOC 1
6+
57
#cmakedefine GIT_TRACE 1
68
#cmakedefine GIT_THREADS 1
79
#cmakedefine GIT_WIN32_LEAKCHECK 1

src/merge.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1535,7 +1535,8 @@ int git_merge_diff_list__find_renames(
15351535
GIT_ASSERT_ARG(diff_list);
15361536
GIT_ASSERT_ARG(opts);
15371537

1538-
if ((opts->flags & GIT_MERGE_FIND_RENAMES) == 0)
1538+
if ((opts->flags & GIT_MERGE_FIND_RENAMES) == 0 ||
1539+
!diff_list->conflicts.length)
15391540
return 0;
15401541

15411542
similarity_ours = git__calloc(diff_list->conflicts.length,

src/pack-objects.c

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -517,13 +517,18 @@ static int cb_tag_foreach(const char *name, git_oid *oid, void *data)
517517
return 0;
518518
}
519519

520-
static git_pobject **compute_write_order(git_packbuilder *pb)
520+
static int compute_write_order(git_pobject ***out, git_packbuilder *pb)
521521
{
522522
size_t i, wo_end, last_untagged;
523523
git_pobject **wo;
524524

525+
*out = NULL;
526+
527+
if (!pb->nr_objects)
528+
return 0;
529+
525530
if ((wo = git__mallocarray(pb->nr_objects, sizeof(*wo))) == NULL)
526-
return NULL;
531+
return -1;
527532

528533
for (i = 0; i < pb->nr_objects; i++) {
529534
git_pobject *po = pb->object_list + i;
@@ -552,7 +557,7 @@ static git_pobject **compute_write_order(git_packbuilder *pb)
552557
*/
553558
if (git_tag_foreach(pb->repo, &cb_tag_foreach, pb) < 0) {
554559
git__free(wo);
555-
return NULL;
560+
return -1;
556561
}
557562

558563
/*
@@ -609,10 +614,11 @@ static git_pobject **compute_write_order(git_packbuilder *pb)
609614
if (wo_end != pb->nr_objects) {
610615
git__free(wo);
611616
git_error_set(GIT_ERROR_INVALID, "invalid write order");
612-
return NULL;
617+
return -1;
613618
}
614619

615-
return wo;
620+
*out = wo;
621+
return 0;
616622
}
617623

618624
static int write_pack(git_packbuilder *pb,
@@ -625,15 +631,15 @@ static int write_pack(git_packbuilder *pb,
625631
struct git_pack_header ph;
626632
git_oid entry_oid;
627633
size_t i = 0;
628-
int error = 0;
634+
int error;
629635

630-
write_order = compute_write_order(pb);
631-
if (write_order == NULL)
632-
return -1;
636+
if ((error = compute_write_order(&write_order, pb)) < 0)
637+
return error;
633638

634639
if (!git__is_uint32(pb->nr_objects)) {
635640
git_error_set(GIT_ERROR_INVALID, "too many objects");
636-
return -1;
641+
error = -1;
642+
goto done;
637643
}
638644

639645
/* Write pack header */

0 commit comments

Comments
 (0)