summaryrefslogtreecommitdiff
path: root/regress/lib/libc
diff options
context:
space:
mode:
authorMatthew Dempsky <matthew@cvs.openbsd.org>2014-07-11 00:38:18 +0000
committerMatthew Dempsky <matthew@cvs.openbsd.org>2014-07-11 00:38:18 +0000
commit87ea289bee17e12e1e19def0dd97d482c0fb4a30 (patch)
tree532806dd9399dc379ddf4c40350cce26f506d52f /regress/lib/libc
parentf86827934c054782609d01918af089178490f90a (diff)
Fix explicit_bzero regress for Solaris and OS X compatibility
Solaris and OS X clobber the signal stack when returning to the main stack, which caused the original testing strategy (inspecting the signal stack once we're back on the main stack) to fail. To be compatible with this behavior, the regress test now inspects the signal stack space while we're still executing on it. This is a bit iffy because we might clobber it ourselves while inspecting it, but we as long as its not completely clobbered we should be okay. thx bcook for the Solaris test account
Diffstat (limited to 'regress/lib/libc')
-rw-r--r--regress/lib/libc/explicit_bzero/explicit_bzero.c95
1 files changed, 68 insertions, 27 deletions
diff --git a/regress/lib/libc/explicit_bzero/explicit_bzero.c b/regress/lib/libc/explicit_bzero/explicit_bzero.c
index d1e4d1494e4..c2b677ca6a6 100644
--- a/regress/lib/libc/explicit_bzero/explicit_bzero.c
+++ b/regress/lib/libc/explicit_bzero/explicit_bzero.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: explicit_bzero.c,v 1.4 2014/07/09 23:54:00 matthew Exp $ */
+/* $OpenBSD: explicit_bzero.c,v 1.5 2014/07/11 00:38:17 matthew Exp $ */
/*
* Copyright (c) 2014 Google Inc.
*
@@ -25,7 +25,18 @@
#define ASSERT_NE(a, b) assert((a) != (b))
#define ASSERT_GE(a, b) assert((a) >= (b))
-static char altstack[SIGSTKSZ];
+/* 128 bits of random data. */
+static const char secret[16] = {
+ 0xa0, 0x6c, 0x0c, 0x81, 0xba, 0xd8, 0x5b, 0x0c,
+ 0xb0, 0xd6, 0xd4, 0xe3, 0xeb, 0x52, 0x5f, 0x96,
+};
+
+enum {
+ SECRETCOUNT = 64,
+ SECRETBYTES = SECRETCOUNT * sizeof(secret)
+};
+
+static char altstack[SIGSTKSZ + SECRETBYTES];
static void
setup_stack(void)
@@ -85,17 +96,6 @@ call_on_stack(void (*fn)(int))
ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &oldsigset, NULL));
}
-/* 128 bits of random data. */
-static const char secret[16] = {
- 0xa0, 0x6c, 0x0c, 0x81, 0xba, 0xd8, 0x5b, 0x0c,
- 0xb0, 0xd6, 0xd4, 0xe3, 0xeb, 0x52, 0x5f, 0x96,
-};
-
-enum {
- SECRETCOUNT = 16,
- SECRETBYTES = SECRETCOUNT * sizeof(secret)
-};
-
static void
populate_secret(char *buf, size_t len)
{
@@ -110,23 +110,54 @@ populate_secret(char *buf, size_t len)
ASSERT_EQ(0, close(fds[0]));
}
-static void
-test_without_bzero(int signo)
+static int
+count_secrets(const char *buf)
+{
+ int res = 0;
+ size_t i;
+ for (i = 0; i < SECRETCOUNT; i++) {
+ if (memcmp(buf + i * sizeof(secret), secret,
+ sizeof(secret)) == 0)
+ res += 1;
+ }
+ return (res);
+}
+
+static char *
+test_without_bzero()
{
char buf[SECRETBYTES];
assert_on_stack();
populate_secret(buf, sizeof(buf));
- ASSERT_NE(NULL, memmem(altstack, sizeof(altstack), buf, sizeof(buf)));
+ char *res = memmem(altstack, sizeof(altstack), buf, sizeof(buf));
+ ASSERT_NE(NULL, res);
+ return (res);
}
-static void
-test_with_bzero(int signo)
+static char *
+test_with_bzero()
{
char buf[SECRETBYTES];
assert_on_stack();
populate_secret(buf, sizeof(buf));
- ASSERT_NE(NULL, memmem(altstack, sizeof(altstack), buf, sizeof(buf)));
+ char *res = memmem(altstack, sizeof(altstack), buf, sizeof(buf));
+ ASSERT_NE(NULL, res);
explicit_bzero(buf, sizeof(buf));
+ return (res);
+}
+
+static void
+do_test_without_bzero(int signo)
+{
+ char *buf = test_without_bzero();
+ ASSERT_GE(count_secrets(buf), 1);
+}
+
+static void
+do_test_with_bzero(int signo)
+{
+ char *buf = test_without_bzero();
+ ASSERT_GE(count_secrets(buf), 0);
}
int
@@ -135,22 +166,32 @@ main()
setup_stack();
/*
+ * Solaris and OS X clobber the signal stack after returning to the
+ * normal stack, so we need to inspect altstack while we're still
+ * running on it. Unfortunately, this means we risk clobbering the
+ * buffer ourselves.
+ *
+ * To minimize this risk, test_with{,out}_bzero() are responsible for
+ * locating the offset of their buf variable within altstack, and
+ * and returning that address. Then we can simply memcmp() repeatedly
+ * to count how many instances of secret we found.
+ */
+
+ /*
* First, test that if we *don't* call explicit_bzero, that we
- * *are* able to find the secret data on the stack. This
- * sanity checks that call_on_stack() and populare_secret()
- * work as intended.
+ * *are* able to find at least one instance of the secret data still
+ * on the stack. This sanity checks that call_on_stack() and
+ * populate_secret() work as intended.
*/
memset(altstack, 0, sizeof(altstack));
- call_on_stack(test_without_bzero);
- ASSERT_NE(NULL, memmem(altstack, sizeof(altstack), secret, sizeof(secret)));
+ call_on_stack(do_test_without_bzero);
/*
* Now test with a call to explicit_bzero() and check that we
- * *don't* find the secret data.
+ * *don't* find any instances of the secret data.
*/
memset(altstack, 0, sizeof(altstack));
- call_on_stack(test_with_bzero);
- ASSERT_EQ(NULL, memmem(altstack, sizeof(altstack), secret, sizeof(secret)));
+ call_on_stack(do_test_with_bzero);
return (0);
}