diff options
-rw-r--r-- | src/regress/lib/libc/explicit_bzero/explicit_bzero.c | 95 |
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 | ||
28 | static char altstack[SIGSTKSZ]; | 28 | /* 128 bits of random data. */ |
29 | static const char secret[16] = { | ||
30 | 0xa0, 0x6c, 0x0c, 0x81, 0xba, 0xd8, 0x5b, 0x0c, | ||
31 | 0xb0, 0xd6, 0xd4, 0xe3, 0xeb, 0x52, 0x5f, 0x96, | ||
32 | }; | ||
33 | |||
34 | enum { | ||
35 | SECRETCOUNT = 64, | ||
36 | SECRETBYTES = SECRETCOUNT * sizeof(secret) | ||
37 | }; | ||
38 | |||
39 | static char altstack[SIGSTKSZ + SECRETBYTES]; | ||
29 | 40 | ||
30 | static void | 41 | static void |
31 | setup_stack(void) | 42 | setup_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. */ | ||
89 | static const char secret[16] = { | ||
90 | 0xa0, 0x6c, 0x0c, 0x81, 0xba, 0xd8, 0x5b, 0x0c, | ||
91 | 0xb0, 0xd6, 0xd4, 0xe3, 0xeb, 0x52, 0x5f, 0x96, | ||
92 | }; | ||
93 | |||
94 | enum { | ||
95 | SECRETCOUNT = 16, | ||
96 | SECRETBYTES = SECRETCOUNT * sizeof(secret) | ||
97 | }; | ||
98 | |||
99 | static void | 99 | static void |
100 | populate_secret(char *buf, size_t len) | 100 | populate_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 | ||
113 | static void | 113 | static int |
114 | test_without_bzero(int signo) | 114 | count_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 | |||
126 | static char * | ||
127 | test_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 | ||
122 | static void | 137 | static char * |
123 | test_with_bzero(int signo) | 138 | test_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 | |||
149 | static void | ||
150 | do_test_without_bzero(int signo) | ||
151 | { | ||
152 | char *buf = test_without_bzero(); | ||
153 | ASSERT_GE(count_secrets(buf), 1); | ||
154 | } | ||
155 | |||
156 | static void | ||
157 | do_test_with_bzero(int signo) | ||
158 | { | ||
159 | char *buf = test_without_bzero(); | ||
160 | ASSERT_GE(count_secrets(buf), 0); | ||
130 | } | 161 | } |
131 | 162 | ||
132 | int | 163 | int |
@@ -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 | } |