Skip to content

Commit 5f7e7da

Browse files
committed
Abort on C23 UB zero sized realloc
1 parent 1d7fc7f commit 5f7e7da

File tree

5 files changed

+30
-1
lines changed

5 files changed

+30
-1
lines changed

h_malloc.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1513,6 +1513,11 @@ EXPORT void *h_calloc(size_t nmemb, size_t size) {
15131513
}
15141514

15151515
EXPORT void *h_realloc(void *old, size_t size) {
1516+
// deprecated in C17, UB since C23
1517+
if (unlikely(old != NULL && size == 0)) {
1518+
fatal_error("invalid zero sized realloc");
1519+
}
1520+
15161521
size = adjust_size_for_canary(size);
15171522
if (old == NULL) {
15181523
return alloc(size);

test/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,5 @@ overflow_small_8_byte
4141
uninitialized_read_large
4242
uninitialized_read_small
4343
realloc_init
44+
realloc_c23_undefined_behaviour
4445
__pycache__/

test/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ EXECUTABLES := \
6767
invalid_malloc_object_size_small \
6868
invalid_malloc_object_size_small_quarantine \
6969
impossibly_large_malloc \
70-
realloc_init
70+
realloc_init \
71+
realloc_c23_undefined_behaviour
7172

7273
all: $(EXECUTABLES)
7374

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#include <stdlib.h>
2+
3+
#include "test_util.h"
4+
5+
OPTNONE int main(void) {
6+
void *p, *q;
7+
8+
p = malloc(16);
9+
if (!p) {
10+
return -1;
11+
}
12+
13+
q = realloc(p, 0);
14+
15+
return 0;
16+
}

test/test_smc.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,12 @@ def test_uninitialized_realloc(self):
169169
self.assertEqual(stderr.decode("utf-8"),
170170
"fatal allocator error: invalid realloc\n")
171171

172+
def test_realloc_c23_undefined_behaviour(self):
173+
_stdout, stderr, returncode = self.run_test("realloc_c23_undefined_behaviour")
174+
self.assertEqual(returncode, -6)
175+
self.assertEqual(stderr.decode("utf-8"),
176+
"fatal allocator error: invalid zero sized realloc\n")
177+
172178
def test_write_after_free_large_reuse(self):
173179
_stdout, _stderr, returncode = self.run_test(
174180
"write_after_free_large_reuse")

0 commit comments

Comments
 (0)