summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/regress/lib/libc/explicit_bzero/explicit_bzero.c95
1 files changed, 68 insertions, 27 deletions
diff --git a/src/regress/lib/libc/explicit_bzero/explicit_bzero.c b/src/regress/lib/libc/explicit_bzero/explicit_bzero.c
index d1e4d1494e..c2b677ca6a 100644
--- a/src/regress/lib/libc/explicit_bzero/explicit_bzero.c
+++ b/src/regress/lib/libc/explicit_bzero/explicit_bzero.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: explicit_bzero.c,v 1.4 2014/07/09 23:54:00 matthew Exp $ */ 1/* $OpenBSD: explicit_bzero.c,v 1.5 2014/07/11 00:38:17 matthew Exp $ */
2/* 2/*
3 * Copyright (c) 2014 Google Inc. 3 * Copyright (c) 2014 Google Inc.
4 * 4 *
@@ -25,7 +25,18 @@
25#define ASSERT_NE(a, b) assert((a) != (b)) 25#define ASSERT_NE(a, b) assert((a) != (b))
26#define ASSERT_GE(a, b) assert((a) >= (b)) 26#define ASSERT_GE(a, b) assert((a) >= (b))
27 27
28static char altstack[SIGSTKSZ]; 28/* 128 bits of random data. */
29static const char secret[16] = {
30 0xa0, 0x6c, 0x0c, 0x81, 0xba, 0xd8, 0x5b, 0x0c,
31 0xb0, 0xd6, 0xd4, 0xe3, 0xeb, 0x52, 0x5f, 0x96,
32};
33
34enum {
35 SECRETCOUNT = 64,
36 SECRETBYTES = SECRETCOUNT * sizeof(secret)
37};
38
39static char altstack[SIGSTKSZ + SECRETBYTES];
29 40
30static void 41static void
31setup_stack(void) 42setup_stack(void)
@@ -85,17 +96,6 @@ call_on_stack(void (*fn)(int))
85 ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &oldsigset, NULL)); 96 ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &oldsigset, NULL));
86} 97}
87 98
88/* 128 bits of random data. */
89static const char secret[16] = {
90 0xa0, 0x6c, 0x0c, 0x81, 0xba, 0xd8, 0x5b, 0x0c,
91 0xb0, 0xd6, 0xd4, 0xe3, 0xeb, 0x52, 0x5f, 0x96,
92};
93
94enum {
95 SECRETCOUNT = 16,
96 SECRETBYTES = SECRETCOUNT * sizeof(secret)
97};
98
99static void 99static void
100populate_secret(char *buf, size_t len) 100populate_secret(char *buf, size_t len)
101{ 101{
@@ -110,23 +110,54 @@ populate_secret(char *buf, size_t len)
110 ASSERT_EQ(0, close(fds[0])); 110 ASSERT_EQ(0, close(fds[0]));
111} 111}
112 112
113static void 113static int
114test_without_bzero(int signo) 114count_secrets(const char *buf)
115{
116 int res = 0;
117 size_t i;
118 for (i = 0; i < SECRETCOUNT; i++) {
119 if (memcmp(buf + i * sizeof(secret), secret,
120 sizeof(secret)) == 0)
121 res += 1;
122 }
123 return (res);
124}
125
126static char *
127test_without_bzero()
115{ 128{
116 char buf[SECRETBYTES]; 129 char buf[SECRETBYTES];
117 assert_on_stack(); 130 assert_on_stack();
118 populate_secret(buf, sizeof(buf)); 131 populate_secret(buf, sizeof(buf));
119 ASSERT_NE(NULL, memmem(altstack, sizeof(altstack), buf, sizeof(buf))); 132 char *res = memmem(altstack, sizeof(altstack), buf, sizeof(buf));
133 ASSERT_NE(NULL, res);
134 return (res);
120} 135}
121 136
122static void 137static char *
123test_with_bzero(int signo) 138test_with_bzero()
124{ 139{
125 char buf[SECRETBYTES]; 140 char buf[SECRETBYTES];
126 assert_on_stack(); 141 assert_on_stack();
127 populate_secret(buf, sizeof(buf)); 142 populate_secret(buf, sizeof(buf));
128 ASSERT_NE(NULL, memmem(altstack, sizeof(altstack), buf, sizeof(buf))); 143 char *res = memmem(altstack, sizeof(altstack), buf, sizeof(buf));
144 ASSERT_NE(NULL, res);
129 explicit_bzero(buf, sizeof(buf)); 145 explicit_bzero(buf, sizeof(buf));
146 return (res);
147}
148
149static void
150do_test_without_bzero(int signo)
151{
152 char *buf = test_without_bzero();
153 ASSERT_GE(count_secrets(buf), 1);
154}
155
156static void
157do_test_with_bzero(int signo)
158{
159 char *buf = test_without_bzero();
160 ASSERT_GE(count_secrets(buf), 0);
130} 161}
131 162
132int 163int
@@ -135,22 +166,32 @@ main()
135 setup_stack(); 166 setup_stack();
136 167
137 /* 168 /*
169 * Solaris and OS X clobber the signal stack after returning to the
170 * normal stack, so we need to inspect altstack while we're still
171 * running on it. Unfortunately, this means we risk clobbering the
172 * buffer ourselves.
173 *
174 * To minimize this risk, test_with{,out}_bzero() are responsible for
175 * locating the offset of their buf variable within altstack, and
176 * and returning that address. Then we can simply memcmp() repeatedly
177 * to count how many instances of secret we found.
178 */
179
180 /*
138 * First, test that if we *don't* call explicit_bzero, that we 181 * First, test that if we *don't* call explicit_bzero, that we
139 * *are* able to find the secret data on the stack. This 182 * *are* able to find at least one instance of the secret data still
140 * sanity checks that call_on_stack() and populare_secret() 183 * on the stack. This sanity checks that call_on_stack() and
141 * work as intended. 184 * populate_secret() work as intended.
142 */ 185 */
143 memset(altstack, 0, sizeof(altstack)); 186 memset(altstack, 0, sizeof(altstack));
144 call_on_stack(test_without_bzero); 187 call_on_stack(do_test_without_bzero);
145 ASSERT_NE(NULL, memmem(altstack, sizeof(altstack), secret, sizeof(secret)));
146 188
147 /* 189 /*
148 * Now test with a call to explicit_bzero() and check that we 190 * Now test with a call to explicit_bzero() and check that we
149 * *don't* find the secret data. 191 * *don't* find any instances of the secret data.
150 */ 192 */
151 memset(altstack, 0, sizeof(altstack)); 193 memset(altstack, 0, sizeof(altstack));
152 call_on_stack(test_with_bzero); 194 call_on_stack(do_test_with_bzero);
153 ASSERT_EQ(NULL, memmem(altstack, sizeof(altstack), secret, sizeof(secret)));
154 195
155 return (0); 196 return (0);
156} 197}