Compare commits

..

2 commits

Author SHA1 Message Date
SkewedZeppelin
1d1c4ce83d
Merge 849055d0b7 into 4fe9018b6f 2025-03-22 09:01:15 +00:00
Tavi
849055d0b7
perform size checks on memcpy/memmove/memset
- memset is disabled for now as it causes hangs
- underlying functions were copied from isoalloc, licensed Apache-2.0
	- credit Chris Rohlf for memcpy/memset
	- credit David Carlier for memmove
- use the fast path as some programs crash otherwise

Signed-off-by: Tavi <tavi@divested.dev>
2025-03-22 05:01:09 -04:00
15 changed files with 17 additions and 117 deletions

View file

@ -1875,7 +1875,7 @@ EXPORT size_t h_malloc_object_size_fast(const void *p) {
}
#if CONFIG_BLOCK_OPS_CHECK_SIZE
inline void *h_memcpy_real(void *dst, const void *src, size_t len) {
void *h_memcpy_real(void *dst, const void *src, size_t len) {
char *p_dst = (char *)dst;
char const *p_src = (char const *)src;
@ -1897,7 +1897,7 @@ EXPORT void *h_memcpy(void *dst, const void *src, size_t len) {
return h_memcpy_real(dst, src, len);
}
inline void *h_memmove_real(void *dst, const void *src, size_t len) {
void *h_memmove_real(void *dst, const void *src, size_t len) {
char *p_dst = (char *)dst;
char const *p_src = (char const *)src;
@ -1929,7 +1929,7 @@ EXPORT void *h_memmove(void *dst, const void *src, size_t len) {
return h_memmove_real(dst, src, len);
}
inline void *h_memset_real(void *dst, int value, size_t len) {
void *h_memset_real(void *dst, int value, size_t len) {
char *p_dst = (char *)dst;
while(len--) {

9
test/.gitignore vendored
View file

@ -43,13 +43,8 @@ uninitialized_read_small
realloc_init
memcpy_buffer_overflow
memcpy_read_overflow
memcpy_valid_same
memcpy_valid_mismatched
memcpy_valid
memmove_buffer_overflow
memmove_read_overflow
memmove_valid_same
memmove_valid_mismatched
memset_buffer_overflow
memset_valid_same
memset_valid_mismatched
memmove_valid
__pycache__/

View file

@ -70,15 +70,10 @@ EXECUTABLES := \
realloc_init \
memcpy_buffer_overflow \
memcpy_read_overflow \
memcpy_valid_same \
memcpy_valid_mismatched \
memcpy_valid \
memmove_buffer_overflow \
memmove_read_overflow \
memmove_valid_same \
memmove_valid_mismatched \
memset_buffer_overflow \
memset_valid_same \
memset_valid_mismatched
memmove_valid
all: $(EXECUTABLES)

View file

@ -1,3 +1,4 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

View file

@ -1,3 +1,4 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

View file

@ -1,3 +1,4 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

View file

@ -1,15 +0,0 @@
#include <stdlib.h>
#include <string.h>
#include "test_util.h"
OPTNONE int main(void) {
char *firstbuffer = malloc(16);
char *secondbuffer = malloc(8);
if (!firstbuffer && !secondbuffer) {
return 1;
}
memset(secondbuffer, 'a', 8);
memcpy(firstbuffer, secondbuffer, 8);
return 0;
}

View file

@ -1,3 +1,4 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

View file

@ -1,3 +1,4 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

View file

@ -1,3 +1,4 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

View file

@ -1,15 +0,0 @@
#include <stdlib.h>
#include <string.h>
#include "test_util.h"
OPTNONE int main(void) {
char *firstbuffer = malloc(16);
char *secondbuffer = malloc(8);
if (!firstbuffer && !secondbuffer) {
return 1;
}
memset(secondbuffer, 'a', 8);
memmove(firstbuffer, secondbuffer, 8);
return 0;
}

View file

@ -1,13 +0,0 @@
#include <stdlib.h>
#include <string.h>
#include "test_util.h"
OPTNONE int main(void) {
char *buffer = malloc(16);
if (!buffer) {
return 1;
}
memset(buffer, 'a', 32);
return 1;
}

View file

@ -1,13 +0,0 @@
#include <stdlib.h>
#include <string.h>
#include "test_util.h"
OPTNONE int main(void) {
char *buffer = malloc(16);
if (!buffer) {
return 1;
}
memset(buffer, 'a', 8);
return 0;
}

View file

@ -1,13 +0,0 @@
#include <stdlib.h>
#include <string.h>
#include "test_util.h"
OPTNONE int main(void) {
char *buffer = malloc(16);
if (!buffer) {
return 1;
}
memset(buffer, 'a', 16);
return 0;
}

View file

@ -252,14 +252,9 @@ class TestSimpleMemoryCorruption(unittest.TestCase):
# self.assertEqual(stderr.decode(
# "utf-8"), "fatal allocator error: memcpy read overflow\n")
def test_memcpy_valid_same(self):
def test_memcpy_valid(self):
_stdout, _stderr, returncode = self.run_test(
"memcpy_valid_same")
self.assertEqual(returncode, 0)
def test_memcpy_valid_mismatched(self):
_stdout, _stderr, returncode = self.run_test(
"memcpy_valid_mismatched")
"memcpy_valid")
self.assertEqual(returncode, 0)
#def test_memmove_buffer_overflow(self):
@ -276,31 +271,9 @@ class TestSimpleMemoryCorruption(unittest.TestCase):
# self.assertEqual(stderr.decode(
# "utf-8"), "fatal allocator error: memmove read overflow\n")
def test_memmove_valid_same(self):
def test_memmove_valid(self):
_stdout, _stderr, returncode = self.run_test(
"memmove_valid_same")
self.assertEqual(returncode, 0)
def test_memmove_valid_mismatched(self):
_stdout, _stderr, returncode = self.run_test(
"memmove_valid_mismatched")
self.assertEqual(returncode, 0)
#def test_memset_buffer_overflow(self):
# _stdout, stderr, returncode = self.run_test(
# "memset_buffer_overflow")
# self.assertEqual(returncode, -6)
# self.assertEqual(stderr.decode(
# "utf-8"), "fatal allocator error: memset buffer overflow\n")
def test_memset_valid_same(self):
_stdout, _stderr, returncode = self.run_test(
"memset_valid_same")
self.assertEqual(returncode, 0)
def test_memset_valid_mismatched(self):
_stdout, _stderr, returncode = self.run_test(
"memset_valid_mismatched")
"memmove_valid")
self.assertEqual(returncode, 0)
if __name__ == '__main__':