diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2014-12-03 18:25:19 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2014-12-03 18:25:19 +0000 |
commit | 68f5f5e537a5f1a8d9405d43f3fec9bea799e88d (patch) | |
tree | 5aa7ec84878f8f5755bd3907c6f685d8e8660c1e | |
parent | 8b064abc892c565ad86df42cc916614670e3a134 (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.c | 95 | ||||
-rw-r--r-- | regress/lib/libc/strlcpy/strlcpytest.c | 93 |
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; } |