summaryrefslogtreecommitdiffstats
path: root/regress/lib/libc
diff options
context:
space:
mode:
authormillert <millert@openbsd.org>2014-12-03 18:25:18 +0000
committermillert <millert@openbsd.org>2014-12-03 18:25:18 +0000
commitf191fa1fe4a3161a974e141a68a46aa2ff59ecbb (patch)
tree4a79ef270bb04711a5472146fcad2c95eb25c5db /regress/lib/libc
parentno md5 in the kernel? not even close to true (diff)
downloadwireguard-openbsd-f191fa1fe4a3161a974e141a68a46aa2ff59ecbb.tar.xz
wireguard-openbsd-f191fa1fe4a3161a974e141a68a46aa2ff59ecbb.zip
Fill the buffer with 'z' instead of 'a' since 'a' is part of the
string we are testing. Add tests to verify that we get SIGSEGV when passed a NULL src or dst. It is better to crash than for an implementation to check for NULL and try to recover.
Diffstat (limited to 'regress/lib/libc')
-rw-r--r--regress/lib/libc/strlcat/strlcattest.c95
-rw-r--r--regress/lib/libc/strlcpy/strlcpytest.c93
2 files changed, 150 insertions, 38 deletions
diff --git a/regress/lib/libc/strlcat/strlcattest.c b/regress/lib/libc/strlcat/strlcattest.c
index cb3624e5a44..155aa6f7273 100644
--- a/regress/lib/libc/strlcat/strlcattest.c
+++ b/regress/lib/libc/strlcat/strlcattest.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: strlcattest.c,v 1.1 2014/12/02 17:48:34 millert Exp $ */
+/* $OpenBSD: strlcattest.c,v 1.2 2014/12/03 18:25:18 millert Exp $ */
/*
* Copyright (c) 2014 Todd C. Miller <Todd.Miller@courtesan.com>
@@ -21,13 +21,27 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <setjmp.h>
+#include <signal.h>
#include <unistd.h>
-int main(int argc, char *argv[])
+volatile sig_atomic_t got_signal;
+sigjmp_buf jmpenv;
+
+void
+handler(int signo)
+{
+ got_signal = signo;
+ siglongjmp(jmpenv, 1);
+}
+
+int
+main(int argc, char *argv[])
{
char *buf, *cp, *ep;
- int failures = 0;
+ struct sigaction sa;
size_t len, bufsize;
+ int failures = 0;
/* Enable malloc security options. */
setenv("MALLOC_OPTIONS", "S", 0);
@@ -38,19 +52,21 @@ int main(int argc, char *argv[])
fprintf(stderr, "unable to allocate memory\n");
return 1;
}
- memset(buf, 'a', bufsize);
+ memset(buf, 'z', bufsize);
ep = buf + bufsize;
/* Test appending to an unterminated string. */
len = strlcat(buf, "abcd", bufsize);
if (len != 4 + bufsize) {
- fprintf(stderr, "strlcat: failed unterminated buffer test (1a)");
+ fprintf(stderr,
+ "strlcat: failed unterminated buffer test (1a)\n");
failures++;
}
/* Make sure we only wrote where expected. */
for (cp = buf; cp < ep; cp++) {
- if (*cp != 'a') {
- fprintf(stderr, "strlcat: failed unterminated buffer test (1b)");
+ if (*cp != 'z') {
+ fprintf(stderr,
+ "strlcat: failed unterminated buffer test (1b)\n");
failures++;
break;
}
@@ -60,34 +76,36 @@ int main(int argc, char *argv[])
ep[-1] = '\0';
len = strlcat(buf, "abcd", bufsize);
if (len != 4 + bufsize - 1) {
- fprintf(stderr, "strlcat: failed full buffer test (2a)");
+ fprintf(stderr, "strlcat: failed full buffer test (2a)\n");
failures++;
}
/* Make sure we only wrote where expected. */
for (cp = buf; cp < ep - 1; cp++) {
- if (*cp != 'a') {
- fprintf(stderr, "strlcat: failed full buffer test (2b)");
+ if (*cp != 'z') {
+ fprintf(stderr,
+ "strlcat: failed full buffer test (2b)\n");
failures++;
break;
}
}
/* Test appending to an empty string. */
- ep[-1] = 'a';
+ ep[-1] = 'z';
buf[0] = '\0';
len = strlcat(buf, "abcd", bufsize);
if (len != 4) {
- fprintf(stderr, "strlcat: failed empty buffer test (3a)");
+ fprintf(stderr, "strlcat: failed empty buffer test (3a)\n");
failures++;
}
/* Make sure we only wrote where expected. */
if (memcmp(buf, "abcd", sizeof("abcd")) != 0) {
- fprintf(stderr, "strlcat: failed empty buffer test (3b)");
+ fprintf(stderr, "strlcat: failed empty buffer test (3b)\n");
failures++;
}
for (cp = buf + len + 1; cp < ep; cp++) {
- if (*cp != 'a') {
- fprintf(stderr, "strlcat: failed empty buffer test (3c)");
+ if (*cp != 'z') {
+ fprintf(stderr,
+ "strlcat: failed empty buffer test (3c)\n");
failures++;
break;
}
@@ -97,21 +115,60 @@ int main(int argc, char *argv[])
memcpy(buf, "abcd", sizeof("abcd"));
len = strlcat(buf, "efgh", bufsize);
if (len != 8) {
- fprintf(stderr, "strlcat: failed empty buffer test (4a)");
+ fprintf(stderr, "strlcat: failed empty buffer test (4a)\n");
failures++;
}
/* Make sure we only wrote where expected. */
if (memcmp(buf, "abcdefgh", sizeof("abcdefgh")) != 0) {
- fprintf(stderr, "strlcat: failed empty buffer test (4b)");
+ fprintf(stderr, "strlcat: failed empty buffer test (4b)\n");
failures++;
}
for (cp = buf + len + 1; cp < ep; cp++) {
- if (*cp != 'a') {
- fprintf(stderr, "strlcat: failed empty buffer test (4c)");
+ if (*cp != 'z') {
+ fprintf(stderr,
+ "strlcat: failed empty buffer test (4c)\n");
failures++;
break;
}
}
+ /*
+ * The following tests should result in SIGSEGV, however some
+ * systems may erroneously report SIGBUS.
+ * These tests assume that strlcat() is signal-safe.
+ */
+ memset(&sa, 0, sizeof(sa));
+ sigemptyset(&sa.sa_mask);
+ sa.sa_handler = handler;
+ sigaction(SIGSEGV, &sa, NULL);
+ sigaction(SIGBUS, &sa, NULL);
+
+ /* Test copying to a NULL buffer with non-zero size. */
+ got_signal = 0;
+ if (sigsetjmp(jmpenv, 1) == 0) {
+ len = strlcat(NULL, "abcd", sizeof(buf));
+ fprintf(stderr, "strlcat: failed NULL dst test (5a), "
+ "expected signal %d, got len %zu\n", SIGSEGV, len);
+ failures++;
+ } else if (got_signal != SIGSEGV) {
+ fprintf(stderr, "strlcat: failed NULL dst test (5b), "
+ "expected signal %d, got %d\n", SIGSEGV, got_signal);
+ failures++;
+ }
+
+ /* Test copying from a NULL src. */
+ memcpy(buf, "abcd", sizeof("abcd"));
+ got_signal = 0;
+ if (sigsetjmp(jmpenv, 1) == 0) {
+ len = strlcat(buf, NULL, sizeof(buf));
+ fprintf(stderr, "strlcat: failed NULL src test (6a), "
+ "expected signal %d, got len %zu\n", SIGSEGV, len);
+ failures++;
+ } else if (got_signal != SIGSEGV) {
+ fprintf(stderr, "strlcat: failed NULL src test (6b), "
+ "expected signal %d, got %d\n", SIGSEGV, got_signal);
+ failures++;
+ }
+
return failures;
}
diff --git a/regress/lib/libc/strlcpy/strlcpytest.c b/regress/lib/libc/strlcpy/strlcpytest.c
index f2760c2f99f..df5d36366c0 100644
--- a/regress/lib/libc/strlcpy/strlcpytest.c
+++ b/regress/lib/libc/strlcpy/strlcpytest.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: strlcpytest.c,v 1.1 2014/12/02 20:23:05 millert Exp $ */
+/* $OpenBSD: strlcpytest.c,v 1.2 2014/12/03 18:25:18 millert Exp $ */
/*
* Copyright (c) 2014 Todd C. Miller <Todd.Miller@courtesan.com>
@@ -21,13 +21,27 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <signal.h>
+#include <setjmp.h>
#include <unistd.h>
-int main(int argc, char *argv[])
+volatile sig_atomic_t got_signal;
+sigjmp_buf jmpenv;
+
+void
+handler(int signo)
+{
+ got_signal = signo;
+ siglongjmp(jmpenv, 1);
+}
+
+int
+main(int argc, char *argv[])
{
char *buf, *buf2, *cp, *ep;
- int failures = 0;
+ struct sigaction sa;
size_t len, bufsize;
+ int failures = 0;
/* Enable malloc security options. */
setenv("MALLOC_OPTIONS", "S", 0);
@@ -39,77 +53,118 @@ int main(int argc, char *argv[])
fprintf(stderr, "unable to allocate memory\n");
return 1;
}
- memset(buf, 'a', bufsize);
+ memset(buf, 'z', bufsize);
ep = buf + bufsize;
/* Test copying to a zero-length NULL buffer. */
len = strlcpy(NULL, "abcd", 0);
if (len != 4) {
- fprintf(stderr, "strlcpy: failed NULL buffer test (1a)");
+ fprintf(stderr,
+ "strlcpy: failed zero-length buffer test (1a)\n");
failures++;
}
/* Test copying small string to a large buffer. */
len = strlcpy(buf, "abcd", bufsize);
if (len != 4) {
- fprintf(stderr, "strlcpy: failed large buffer test (2a)");
+ fprintf(stderr, "strlcpy: failed large buffer test (2a)\n");
failures++;
}
/* Make sure we only wrote where expected. */
if (memcmp(buf, "abcd", sizeof("abcd")) != 0) {
- fprintf(stderr, "strlcpy: failed large buffer test (2b)");
+ fprintf(stderr, "strlcpy: failed large buffer test (2b)\n");
failures++;
}
for (cp = buf + len + 1; cp < ep; cp++) {
- if (*cp != 'a') {
- fprintf(stderr, "strlcpy: failed large buffer test (2c)");
+ if (*cp != 'z') {
+ fprintf(stderr,
+ "strlcpy: failed large buffer test (2c)\n");
failures++;
break;
}
}
/* Test copying large string to a small buffer. */
- memset(buf, 'a', bufsize);
+ memset(buf, 'z', bufsize);
memset(buf2, 'x', bufsize - 1);
buf2[bufsize - 1] = '\0';
len = strlcpy(buf, buf2, bufsize / 2);
if (len != bufsize - 1) {
- fprintf(stderr, "strlcpy: failed small buffer test (3a)");
+ fprintf(stderr, "strlcpy: failed small buffer test (3a)\n");
failures++;
}
/* Make sure we only wrote where expected. */
len = (bufsize / 2) - 1;
if (memcmp(buf, buf2, len) != 0 || buf[len] != '\0') {
- fprintf(stderr, "strlcpy: failed small buffer test (3b)");
+ fprintf(stderr, "strlcpy: failed small buffer test (3b)\n");
failures++;
}
for (cp = buf + len + 1; cp < ep; cp++) {
- if (*cp != 'a') {
- fprintf(stderr, "strlcpy: failed small buffer test (3c)");
+ if (*cp != 'z') {
+ fprintf(stderr,
+ "strlcpy: failed small buffer test (3c)\n");
failures++;
break;
}
}
/* Test copying to a 1-byte buffer. */
- memset(buf, 'a', bufsize);
+ memset(buf, 'z', bufsize);
len = strlcpy(buf, "abcd", 1);
if (len != 4) {
- fprintf(stderr, "strlcpy: failed 1-byte buffer test (4a)");
+ fprintf(stderr, "strlcpy: failed 1-byte buffer test (4a)\n");
failures++;
}
/* Make sure we only wrote where expected. */
if (buf[0] != '\0') {
- fprintf(stderr, "strlcpy: failed 1-byte buffer test (4b)");
+ fprintf(stderr, "strlcpy: failed 1-byte buffer test (4b)\n");
failures++;
}
for (cp = buf + 1; cp < ep; cp++) {
- if (*cp != 'a') {
- fprintf(stderr, "strlcpy: failed 1-byte buffer test (4c)");
+ if (*cp != 'z') {
+ fprintf(stderr,
+ "strlcpy: failed 1-byte buffer test (4c)\n");
failures++;
break;
}
}
+ /*
+ * The following tests should result in SIGSEGV, however some
+ * systems may erroneously report SIGBUS.
+ * These tests assume that strlcpy() is signal-safe.
+ */
+ memset(&sa, 0, sizeof(sa));
+ sigemptyset(&sa.sa_mask);
+ sa.sa_handler = handler;
+ sigaction(SIGSEGV, &sa, NULL);
+ sigaction(SIGBUS, &sa, NULL);
+
+ /* Test copying to a NULL buffer with non-zero size. */
+ got_signal = 0;
+ if (sigsetjmp(jmpenv, 1) == 0) {
+ len = strlcpy(NULL, "abcd", sizeof(buf));
+ fprintf(stderr, "strlcpy: failed NULL dst test (5a), "
+ "expected signal %d, got len %zu\n", SIGSEGV, len);
+ failures++;
+ } else if (got_signal != SIGSEGV) {
+ fprintf(stderr, "strlcpy: failed NULL dst test (5b), "
+ "expected signal %d, got %d\n", SIGSEGV, got_signal);
+ failures++;
+ }
+
+ /* Test copying from a NULL src. */
+ got_signal = 0;
+ if (sigsetjmp(jmpenv, 1) == 0) {
+ len = strlcpy(buf, NULL, sizeof(buf));
+ fprintf(stderr, "strlcpy: failed NULL src test (6a), "
+ "expected signal %d, got len %zu\n", SIGSEGV, len);
+ failures++;
+ } else if (got_signal != SIGSEGV) {
+ fprintf(stderr, "strlcpy: failed NULL src test (6b), "
+ "expected signal %d, got %d\n", SIGSEGV, got_signal);
+ failures++;
+ }
+
return failures;
}