git: 61ed5748e4e9 - main - lib/libc/tests/string: improve memccpy "bounds" unit test
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 14 Sep 2024 18:42:59 UTC
The branch main has been updated by fuz:
URL: https://cgit.FreeBSD.org/src/commit/?id=61ed5748e4e9c7397fcb2638b442f46ac5c9e7c5
commit 61ed5748e4e9c7397fcb2638b442f46ac5c9e7c5
Author: Robert Clausecker <fuz@FreeBSD.org>
AuthorDate: 2024-07-19 20:50:28 +0000
Commit: Robert Clausecker <fuz@FreeBSD.org>
CommitDate: 2024-09-14 18:42:19 +0000
lib/libc/tests/string: improve memccpy "bounds" unit test
The purpose of the "bounds" test is to check that the function does not
overread the array bounds. The old unit test, copied from the strlcpy()
one, always ensured that we see the character c memccpy() is looking for
in the source array before the array ends. While this is correct for
strlcpy(), memccpy()'s specification does not guarantee that c is
present within the given size limit.
The updated test handles this case better, ensuring that the source
array ends early if c is not supposed to be present.
Reported by: getz
Approved by: emaste
See also: D46052
Event: GSoC 2024
Differential Revision: https://reviews.freebsd.org/D46051
---
lib/libc/tests/string/memccpy_test.c | 50 ++++++++++++++++++++++++++----------
1 file changed, 37 insertions(+), 13 deletions(-)
diff --git a/lib/libc/tests/string/memccpy_test.c b/lib/libc/tests/string/memccpy_test.c
index 82f4ef34af54..4784fee4ede5 100644
--- a/lib/libc/tests/string/memccpy_test.c
+++ b/lib/libc/tests/string/memccpy_test.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2009 David Schultz <das@FreeBSD.org>
- * Copyright (c) 2023 The FreeBSD Foundation
+ * Copyright (c) 2023, 2024 The FreeBSD Foundation
* All rights reserved.
*
* Portions of this software were developed by Robert Clausecker
@@ -54,34 +54,57 @@ makebuf(size_t len, int guard_at_end)
buf = mmap(NULL, alloc_size, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0);
assert(buf);
if (guard_at_end) {
- assert(munmap(buf + alloc_size - page_size, page_size) == 0);
+ assert(mprotect(buf + alloc_size - page_size, page_size, PROT_NONE) == 0);
return (buf + alloc_size - page_size - len);
} else {
- assert(munmap(buf, page_size) == 0);
+ assert(mprotect(buf, page_size, PROT_NONE) == 0);
return (buf + page_size);
}
}
static void
-test_memccpy(const char *s)
+freebuf(char * buf, size_t len, int guard_at_end)
+{
+ size_t alloc_size, page_size;
+
+ page_size = getpagesize();
+ alloc_size = roundup2(len, page_size) + page_size;
+
+ if (guard_at_end)
+ munmap(buf + len + page_size - alloc_size, alloc_size);
+ else
+ munmap(buf - page_size, alloc_size);
+}
+
+static void
+test_memccpy(const char *s, size_t size)
{
char *src, *dst, *expected;
- size_t size, bufsize, x;
+ size_t bufsize, x;
int i, j;
- size = strlen(s) + 1;
for (i = 0; i <= 1; i++) {
for (j = 0; j <= 1; j++) {
- for (bufsize = 0; bufsize <= size + 10; bufsize++) {
- src = makebuf(size, i);
- memcpy(src, s, size);
+ for (bufsize = 0; bufsize <= size + 32; bufsize++) {
dst = makebuf(bufsize, j);
+ if (bufsize < size) {
+ src = makebuf(bufsize, i);
+ memcpy(src, s, bufsize);
+ expected = NULL;
+ } else {
+ src = makebuf(size, i);
+ memcpy(src, s, size);
+ expected = dst + size;
+ }
+
memset(dst, 'X', bufsize);
- expected = bufsize >= size ? dst + size : NULL;
- assert(memccpy_fn(dst, src, src[size-1], bufsize) == expected);
- assert(bufsize == 0 || strncmp(src, dst, bufsize - 1) == 0);
+ assert(memccpy_fn(dst, src, s[size-1], bufsize) == expected);
+ assert(memcmp(src, dst, MIN(bufsize, size)) == 0);
for (x = size; x < bufsize; x++)
assert(dst[x] == 'X');
+
+ freebuf(dst, bufsize, j);
+ freebuf(src, bufsize < size ? bufsize : size, i);
}
}
}
@@ -168,7 +191,8 @@ ATF_TC_BODY(bounds, tc)
for (i = 0; i < sizeof(buf) - 1; i++) {
buf[i] = ' ' + i;
- test_memccpy(buf);
+ buf[i+1] = '\0';
+ test_memccpy(buf, i + 1);
}
}