diff options
author | Matthew Dempsky <matthew@cvs.openbsd.org> | 2014-07-11 00:38:18 +0000 |
---|---|---|
committer | Matthew Dempsky <matthew@cvs.openbsd.org> | 2014-07-11 00:38:18 +0000 |
commit | 87ea289bee17e12e1e19def0dd97d482c0fb4a30 (patch) | |
tree | 532806dd9399dc379ddf4c40350cce26f506d52f /regress/lib/libc | |
parent | f86827934c054782609d01918af089178490f90a (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.c | 95 |
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); } |