summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2014-12-03 18:25:19 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2014-12-03 18:25:19 +0000
commit68f5f5e537a5f1a8d9405d43f3fec9bea799e88d (patch)
tree5aa7ec84878f8f5755bd3907c6f685d8e8660c1e
parent8b064abc892c565ad86df42cc916614670e3a134 (diff)
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.
-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;
}