diff options
Diffstat (limited to 'regress/unittests/test_helper/fuzz.c')
-rw-r--r-- | regress/unittests/test_helper/fuzz.c | 102 |
1 files changed, 81 insertions, 21 deletions
diff --git a/regress/unittests/test_helper/fuzz.c b/regress/unittests/test_helper/fuzz.c index 77c6e7cad..99f1d036c 100644 --- a/regress/unittests/test_helper/fuzz.c +++ b/regress/unittests/test_helper/fuzz.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: fuzz.c,v 1.3 2014/05/02 09:41:32 andre Exp $ */ | 1 | /* $OpenBSD: fuzz.c,v 1.8 2015/03/03 20:42:49 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2011 Damien Miller <djm@mindrot.org> | 3 | * Copyright (c) 2011 Damien Miller <djm@mindrot.org> |
4 | * | 4 | * |
@@ -20,6 +20,7 @@ | |||
20 | #include "includes.h" | 20 | #include "includes.h" |
21 | 21 | ||
22 | #include <sys/types.h> | 22 | #include <sys/types.h> |
23 | #include <sys/uio.h> | ||
23 | 24 | ||
24 | #include <assert.h> | 25 | #include <assert.h> |
25 | #include <ctype.h> | 26 | #include <ctype.h> |
@@ -29,9 +30,11 @@ | |||
29 | #endif | 30 | #endif |
30 | #include <stdlib.h> | 31 | #include <stdlib.h> |
31 | #include <string.h> | 32 | #include <string.h> |
32 | #include <assert.h> | 33 | #include <signal.h> |
34 | #include <unistd.h> | ||
33 | 35 | ||
34 | #include "test_helper.h" | 36 | #include "test_helper.h" |
37 | #include "atomicio.h" | ||
35 | 38 | ||
36 | /* #define FUZZ_DEBUG */ | 39 | /* #define FUZZ_DEBUG */ |
37 | 40 | ||
@@ -96,60 +99,66 @@ fuzz_ntop(u_int n) | |||
96 | } | 99 | } |
97 | } | 100 | } |
98 | 101 | ||
99 | void | 102 | static int |
100 | fuzz_dump(struct fuzz *fuzz) | 103 | fuzz_fmt(struct fuzz *fuzz, char *s, size_t n) |
101 | { | 104 | { |
102 | u_char *p = fuzz_ptr(fuzz); | 105 | if (fuzz == NULL) |
103 | size_t i, j, len = fuzz_len(fuzz); | 106 | return -1; |
104 | 107 | ||
105 | switch (fuzz->strategy) { | 108 | switch (fuzz->strategy) { |
106 | case FUZZ_1_BIT_FLIP: | 109 | case FUZZ_1_BIT_FLIP: |
107 | fprintf(stderr, "%s case %zu of %zu (bit: %zu)\n", | 110 | snprintf(s, n, "%s case %zu of %zu (bit: %zu)\n", |
108 | fuzz_ntop(fuzz->strategy), | 111 | fuzz_ntop(fuzz->strategy), |
109 | fuzz->o1, fuzz->slen * 8, fuzz->o1); | 112 | fuzz->o1, fuzz->slen * 8, fuzz->o1); |
110 | break; | 113 | return 0; |
111 | case FUZZ_2_BIT_FLIP: | 114 | case FUZZ_2_BIT_FLIP: |
112 | fprintf(stderr, "%s case %llu of %llu (bits: %zu, %zu)\n", | 115 | snprintf(s, n, "%s case %llu of %llu (bits: %zu, %zu)\n", |
113 | fuzz_ntop(fuzz->strategy), | 116 | fuzz_ntop(fuzz->strategy), |
114 | (((fuzz_ullong)fuzz->o2) * fuzz->slen * 8) + fuzz->o1, | 117 | (((fuzz_ullong)fuzz->o2) * fuzz->slen * 8) + fuzz->o1, |
115 | ((fuzz_ullong)fuzz->slen * 8) * fuzz->slen * 8, | 118 | ((fuzz_ullong)fuzz->slen * 8) * fuzz->slen * 8, |
116 | fuzz->o1, fuzz->o2); | 119 | fuzz->o1, fuzz->o2); |
117 | break; | 120 | return 0; |
118 | case FUZZ_1_BYTE_FLIP: | 121 | case FUZZ_1_BYTE_FLIP: |
119 | fprintf(stderr, "%s case %zu of %zu (byte: %zu)\n", | 122 | snprintf(s, n, "%s case %zu of %zu (byte: %zu)\n", |
120 | fuzz_ntop(fuzz->strategy), | 123 | fuzz_ntop(fuzz->strategy), |
121 | fuzz->o1, fuzz->slen, fuzz->o1); | 124 | fuzz->o1, fuzz->slen, fuzz->o1); |
122 | break; | 125 | return 0; |
123 | case FUZZ_2_BYTE_FLIP: | 126 | case FUZZ_2_BYTE_FLIP: |
124 | fprintf(stderr, "%s case %llu of %llu (bytes: %zu, %zu)\n", | 127 | snprintf(s, n, "%s case %llu of %llu (bytes: %zu, %zu)\n", |
125 | fuzz_ntop(fuzz->strategy), | 128 | fuzz_ntop(fuzz->strategy), |
126 | (((fuzz_ullong)fuzz->o2) * fuzz->slen) + fuzz->o1, | 129 | (((fuzz_ullong)fuzz->o2) * fuzz->slen) + fuzz->o1, |
127 | ((fuzz_ullong)fuzz->slen) * fuzz->slen, | 130 | ((fuzz_ullong)fuzz->slen) * fuzz->slen, |
128 | fuzz->o1, fuzz->o2); | 131 | fuzz->o1, fuzz->o2); |
129 | break; | 132 | return 0; |
130 | case FUZZ_TRUNCATE_START: | 133 | case FUZZ_TRUNCATE_START: |
131 | fprintf(stderr, "%s case %zu of %zu (offset: %zu)\n", | 134 | snprintf(s, n, "%s case %zu of %zu (offset: %zu)\n", |
132 | fuzz_ntop(fuzz->strategy), | 135 | fuzz_ntop(fuzz->strategy), |
133 | fuzz->o1, fuzz->slen, fuzz->o1); | 136 | fuzz->o1, fuzz->slen, fuzz->o1); |
134 | break; | 137 | return 0; |
135 | case FUZZ_TRUNCATE_END: | 138 | case FUZZ_TRUNCATE_END: |
136 | fprintf(stderr, "%s case %zu of %zu (offset: %zu)\n", | 139 | snprintf(s, n, "%s case %zu of %zu (offset: %zu)\n", |
137 | fuzz_ntop(fuzz->strategy), | 140 | fuzz_ntop(fuzz->strategy), |
138 | fuzz->o1, fuzz->slen, fuzz->o1); | 141 | fuzz->o1, fuzz->slen, fuzz->o1); |
139 | break; | 142 | return 0; |
140 | case FUZZ_BASE64: | 143 | case FUZZ_BASE64: |
141 | assert(fuzz->o2 < sizeof(fuzz_b64chars) - 1); | 144 | assert(fuzz->o2 < sizeof(fuzz_b64chars) - 1); |
142 | fprintf(stderr, "%s case %llu of %llu (offset: %zu char: %c)\n", | 145 | snprintf(s, n, "%s case %llu of %llu (offset: %zu char: %c)\n", |
143 | fuzz_ntop(fuzz->strategy), | 146 | fuzz_ntop(fuzz->strategy), |
144 | (fuzz->o1 * (fuzz_ullong)64) + fuzz->o2, | 147 | (fuzz->o1 * (fuzz_ullong)64) + fuzz->o2, |
145 | fuzz->slen * (fuzz_ullong)64, fuzz->o1, | 148 | fuzz->slen * (fuzz_ullong)64, fuzz->o1, |
146 | fuzz_b64chars[fuzz->o2]); | 149 | fuzz_b64chars[fuzz->o2]); |
147 | break; | 150 | return 0; |
148 | default: | 151 | default: |
152 | return -1; | ||
149 | abort(); | 153 | abort(); |
150 | } | 154 | } |
155 | } | ||
156 | |||
157 | static void | ||
158 | dump(u_char *p, size_t len) | ||
159 | { | ||
160 | size_t i, j; | ||
151 | 161 | ||
152 | fprintf(stderr, "fuzz context %p len = %zu\n", fuzz, len); | ||
153 | for (i = 0; i < len; i += 16) { | 162 | for (i = 0; i < len; i += 16) { |
154 | fprintf(stderr, "%.4zd: ", i); | 163 | fprintf(stderr, "%.4zd: ", i); |
155 | for (j = i; j < i + 16; j++) { | 164 | for (j = i; j < i + 16; j++) { |
@@ -171,6 +180,39 @@ fuzz_dump(struct fuzz *fuzz) | |||
171 | } | 180 | } |
172 | } | 181 | } |
173 | 182 | ||
183 | void | ||
184 | fuzz_dump(struct fuzz *fuzz) | ||
185 | { | ||
186 | char buf[256]; | ||
187 | |||
188 | if (fuzz_fmt(fuzz, buf, sizeof(buf)) != 0) { | ||
189 | fprintf(stderr, "%s: fuzz invalid\n", __func__); | ||
190 | abort(); | ||
191 | } | ||
192 | fputs(buf, stderr); | ||
193 | fprintf(stderr, "fuzz original %p len = %zu\n", fuzz->seed, fuzz->slen); | ||
194 | dump(fuzz->seed, fuzz->slen); | ||
195 | fprintf(stderr, "fuzz context %p len = %zu\n", fuzz, fuzz_len(fuzz)); | ||
196 | dump(fuzz_ptr(fuzz), fuzz_len(fuzz)); | ||
197 | } | ||
198 | |||
199 | #ifdef SIGINFO | ||
200 | static struct fuzz *last_fuzz; | ||
201 | |||
202 | static void | ||
203 | siginfo(int unused __attribute__((__unused__))) | ||
204 | { | ||
205 | char buf[256]; | ||
206 | |||
207 | test_info(buf, sizeof(buf)); | ||
208 | atomicio(vwrite, STDERR_FILENO, buf, strlen(buf)); | ||
209 | if (last_fuzz != NULL) { | ||
210 | fuzz_fmt(last_fuzz, buf, sizeof(buf)); | ||
211 | atomicio(vwrite, STDERR_FILENO, buf, strlen(buf)); | ||
212 | } | ||
213 | } | ||
214 | #endif | ||
215 | |||
174 | struct fuzz * | 216 | struct fuzz * |
175 | fuzz_begin(u_int strategies, const void *p, size_t l) | 217 | fuzz_begin(u_int strategies, const void *p, size_t l) |
176 | { | 218 | { |
@@ -190,6 +232,12 @@ fuzz_begin(u_int strategies, const void *p, size_t l) | |||
190 | FUZZ_DBG(("begin, ret = %p", ret)); | 232 | FUZZ_DBG(("begin, ret = %p", ret)); |
191 | 233 | ||
192 | fuzz_next(ret); | 234 | fuzz_next(ret); |
235 | |||
236 | #ifdef SIGINFO | ||
237 | last_fuzz = ret; | ||
238 | signal(SIGINFO, siginfo); | ||
239 | #endif | ||
240 | |||
193 | return ret; | 241 | return ret; |
194 | } | 242 | } |
195 | 243 | ||
@@ -197,6 +245,10 @@ void | |||
197 | fuzz_cleanup(struct fuzz *fuzz) | 245 | fuzz_cleanup(struct fuzz *fuzz) |
198 | { | 246 | { |
199 | FUZZ_DBG(("cleanup, fuzz = %p", fuzz)); | 247 | FUZZ_DBG(("cleanup, fuzz = %p", fuzz)); |
248 | #ifdef SIGINFO | ||
249 | last_fuzz = NULL; | ||
250 | signal(SIGINFO, SIG_DFL); | ||
251 | #endif | ||
200 | assert(fuzz != NULL); | 252 | assert(fuzz != NULL); |
201 | assert(fuzz->seed != NULL); | 253 | assert(fuzz->seed != NULL); |
202 | assert(fuzz->fuzzed != NULL); | 254 | assert(fuzz->fuzzed != NULL); |
@@ -326,6 +378,14 @@ fuzz_next(struct fuzz *fuzz) | |||
326 | } | 378 | } |
327 | 379 | ||
328 | int | 380 | int |
381 | fuzz_matches_original(struct fuzz *fuzz) | ||
382 | { | ||
383 | if (fuzz_len(fuzz) != fuzz->slen) | ||
384 | return 0; | ||
385 | return memcmp(fuzz_ptr(fuzz), fuzz->seed, fuzz->slen) == 0; | ||
386 | } | ||
387 | |||
388 | int | ||
329 | fuzz_done(struct fuzz *fuzz) | 389 | fuzz_done(struct fuzz *fuzz) |
330 | { | 390 | { |
331 | FUZZ_DBG(("fuzz = %p, strategies = 0x%lx", fuzz, | 391 | FUZZ_DBG(("fuzz = %p, strategies = 0x%lx", fuzz, |