summaryrefslogtreecommitdiff
path: root/regress/unittests/test_helper
diff options
context:
space:
mode:
Diffstat (limited to 'regress/unittests/test_helper')
-rw-r--r--regress/unittests/test_helper/Makefile5
-rw-r--r--regress/unittests/test_helper/fuzz.c102
-rw-r--r--regress/unittests/test_helper/test_helper.c67
-rw-r--r--regress/unittests/test_helper/test_helper.h13
4 files changed, 158 insertions, 29 deletions
diff --git a/regress/unittests/test_helper/Makefile b/regress/unittests/test_helper/Makefile
index 3e90903ef..5b3894cbf 100644
--- a/regress/unittests/test_helper/Makefile
+++ b/regress/unittests/test_helper/Makefile
@@ -1,4 +1,4 @@
1# $OpenBSD: Makefile,v 1.1 2014/04/30 05:32:00 djm Exp $ 1# $OpenBSD: Makefile,v 1.2 2015/01/20 22:58:57 djm Exp $
2 2
3LIB= test_helper 3LIB= test_helper
4SRCS= test_helper.c fuzz.c 4SRCS= test_helper.c fuzz.c
@@ -7,6 +7,9 @@ DEBUGLIBS= no
7NOPROFILE= yes 7NOPROFILE= yes
8NOPIC= yes 8NOPIC= yes
9 9
10# Hack to allow building with SUBDIR in ../../Makefile
11regress: all
12
10install: 13install:
11 @echo -n 14 @echo -n
12 15
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
99void 102static int
100fuzz_dump(struct fuzz *fuzz) 103fuzz_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
157static void
158dump(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
183void
184fuzz_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
200static struct fuzz *last_fuzz;
201
202static void
203siginfo(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
174struct fuzz * 216struct fuzz *
175fuzz_begin(u_int strategies, const void *p, size_t l) 217fuzz_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
197fuzz_cleanup(struct fuzz *fuzz) 245fuzz_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
328int 380int
381fuzz_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
388int
329fuzz_done(struct fuzz *fuzz) 389fuzz_done(struct fuzz *fuzz)
330{ 390{
331 FUZZ_DBG(("fuzz = %p, strategies = 0x%lx", fuzz, 391 FUZZ_DBG(("fuzz = %p, strategies = 0x%lx", fuzz,
diff --git a/regress/unittests/test_helper/test_helper.c b/regress/unittests/test_helper/test_helper.c
index d0bc67833..26ca26b5e 100644
--- a/regress/unittests/test_helper/test_helper.c
+++ b/regress/unittests/test_helper/test_helper.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: test_helper.c,v 1.2 2014/05/02 09:41:32 andre Exp $ */ 1/* $OpenBSD: test_helper.c,v 1.6 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 *
@@ -21,6 +21,7 @@
21 21
22#include <sys/types.h> 22#include <sys/types.h>
23#include <sys/param.h> 23#include <sys/param.h>
24#include <sys/uio.h>
24 25
25#include <fcntl.h> 26#include <fcntl.h>
26#include <stdio.h> 27#include <stdio.h>
@@ -31,6 +32,7 @@
31#include <string.h> 32#include <string.h>
32#include <assert.h> 33#include <assert.h>
33#include <unistd.h> 34#include <unistd.h>
35#include <signal.h>
34 36
35#include <openssl/bn.h> 37#include <openssl/bn.h>
36 38
@@ -39,6 +41,7 @@
39#endif 41#endif
40 42
41#include "test_helper.h" 43#include "test_helper.h"
44#include "atomicio.h"
42 45
43#define TEST_CHECK_INT(r, pred) do { \ 46#define TEST_CHECK_INT(r, pred) do { \
44 switch (pred) { \ 47 switch (pred) { \
@@ -111,6 +114,7 @@ static u_int test_number = 0;
111static test_onerror_func_t *test_onerror = NULL; 114static test_onerror_func_t *test_onerror = NULL;
112static void *onerror_ctx = NULL; 115static void *onerror_ctx = NULL;
113static const char *data_dir = NULL; 116static const char *data_dir = NULL;
117static char subtest_info[512];
114 118
115int 119int
116main(int argc, char **argv) 120main(int argc, char **argv)
@@ -180,13 +184,36 @@ test_data_file(const char *name)
180} 184}
181 185
182void 186void
187test_info(char *s, size_t len)
188{
189 snprintf(s, len, "In test %u: \"%s\"%s%s\n", test_number,
190 active_test_name == NULL ? "<none>" : active_test_name,
191 *subtest_info != '\0' ? " - " : "", subtest_info);
192}
193
194#ifdef SIGINFO
195static void
196siginfo(int unused __attribute__((__unused__)))
197{
198 char buf[256];
199
200 test_info(buf, sizeof(buf));
201 atomicio(vwrite, STDERR_FILENO, buf, strlen(buf));
202}
203#endif
204
205void
183test_start(const char *n) 206test_start(const char *n)
184{ 207{
185 assert(active_test_name == NULL); 208 assert(active_test_name == NULL);
186 assert((active_test_name = strdup(n)) != NULL); 209 assert((active_test_name = strdup(n)) != NULL);
210 *subtest_info = '\0';
187 if (verbose_mode) 211 if (verbose_mode)
188 printf("test %u - \"%s\": ", test_number, active_test_name); 212 printf("test %u - \"%s\": ", test_number, active_test_name);
189 test_number++; 213 test_number++;
214#ifdef SIGINFO
215 signal(SIGINFO, siginfo);
216#endif
190} 217}
191 218
192void 219void
@@ -199,6 +226,7 @@ set_onerror_func(test_onerror_func_t *f, void *ctx)
199void 226void
200test_done(void) 227test_done(void)
201{ 228{
229 *subtest_info = '\0';
202 assert(active_test_name != NULL); 230 assert(active_test_name != NULL);
203 free(active_test_name); 231 free(active_test_name);
204 active_test_name = NULL; 232 active_test_name = NULL;
@@ -211,6 +239,16 @@ test_done(void)
211} 239}
212 240
213void 241void
242test_subtest_info(const char *fmt, ...)
243{
244 va_list ap;
245
246 va_start(ap, fmt);
247 vsnprintf(subtest_info, sizeof(subtest_info), fmt, ap);
248 va_end(ap);
249}
250
251void
214ssl_err_check(const char *file, int line) 252ssl_err_check(const char *file, int line)
215{ 253{
216 long openssl_error = ERR_get_error(); 254 long openssl_error = ERR_get_error();
@@ -256,8 +294,9 @@ static void
256test_header(const char *file, int line, const char *a1, const char *a2, 294test_header(const char *file, int line, const char *a1, const char *a2,
257 const char *name, enum test_predicate pred) 295 const char *name, enum test_predicate pred)
258{ 296{
259 fprintf(stderr, "\n%s:%d test #%u \"%s\"\n", 297 fprintf(stderr, "\n%s:%d test #%u \"%s\"%s%s\n",
260 file, line, test_number, active_test_name); 298 file, line, test_number, active_test_name,
299 *subtest_info != '\0' ? " - " : "", subtest_info);
261 fprintf(stderr, "ASSERT_%s_%s(%s%s%s) failed:\n", 300 fprintf(stderr, "ASSERT_%s_%s(%s%s%s) failed:\n",
262 name, pred_name(pred), a1, 301 name, pred_name(pred), a1,
263 a2 != NULL ? ", " : "", a2 != NULL ? a2 : ""); 302 a2 != NULL ? ", " : "", a2 != NULL ? a2 : "");
@@ -280,8 +319,13 @@ void
280assert_string(const char *file, int line, const char *a1, const char *a2, 319assert_string(const char *file, int line, const char *a1, const char *a2,
281 const char *aa1, const char *aa2, enum test_predicate pred) 320 const char *aa1, const char *aa2, enum test_predicate pred)
282{ 321{
283 int r = strcmp(aa1, aa2); 322 int r;
284 323
324 /* Verify pointers are not NULL */
325 assert_ptr(file, line, a1, "NULL", aa1, NULL, TEST_NE);
326 assert_ptr(file, line, a2, "NULL", aa2, NULL, TEST_NE);
327
328 r = strcmp(aa1, aa2);
285 TEST_CHECK_INT(r, pred); 329 TEST_CHECK_INT(r, pred);
286 test_header(file, line, a1, a2, "STRING", pred); 330 test_header(file, line, a1, a2, "STRING", pred);
287 fprintf(stderr, "%12s = %s (len %zu)\n", a1, aa1, strlen(aa1)); 331 fprintf(stderr, "%12s = %s (len %zu)\n", a1, aa1, strlen(aa1));
@@ -310,8 +354,15 @@ void
310assert_mem(const char *file, int line, const char *a1, const char *a2, 354assert_mem(const char *file, int line, const char *a1, const char *a2,
311 const void *aa1, const void *aa2, size_t l, enum test_predicate pred) 355 const void *aa1, const void *aa2, size_t l, enum test_predicate pred)
312{ 356{
313 int r = memcmp(aa1, aa2, l); 357 int r;
314 358
359 if (l == 0)
360 return;
361 /* If length is >0, then verify pointers are not NULL */
362 assert_ptr(file, line, a1, "NULL", aa1, NULL, TEST_NE);
363 assert_ptr(file, line, a2, "NULL", aa2, NULL, TEST_NE);
364
365 r = memcmp(aa1, aa2, l);
315 TEST_CHECK_INT(r, pred); 366 TEST_CHECK_INT(r, pred);
316 test_header(file, line, a1, a2, "STRING", pred); 367 test_header(file, line, a1, a2, "STRING", pred);
317 fprintf(stderr, "%12s = %s (len %zu)\n", a1, tohex(aa1, MIN(l, 256)), l); 368 fprintf(stderr, "%12s = %s (len %zu)\n", a1, tohex(aa1, MIN(l, 256)), l);
@@ -338,11 +389,15 @@ assert_mem_filled(const char *file, int line, const char *a1,
338 const void *aa1, u_char v, size_t l, enum test_predicate pred) 389 const void *aa1, u_char v, size_t l, enum test_predicate pred)
339{ 390{
340 size_t where = -1; 391 size_t where = -1;
341 int r = memvalcmp(aa1, v, l, &where); 392 int r;
342 char tmp[64]; 393 char tmp[64];
343 394
344 if (l == 0) 395 if (l == 0)
345 return; 396 return;
397 /* If length is >0, then verify the pointer is not NULL */
398 assert_ptr(file, line, a1, "NULL", aa1, NULL, TEST_NE);
399
400 r = memvalcmp(aa1, v, l, &where);
346 TEST_CHECK_INT(r, pred); 401 TEST_CHECK_INT(r, pred);
347 test_header(file, line, a1, NULL, "MEM_ZERO", pred); 402 test_header(file, line, a1, NULL, "MEM_ZERO", pred);
348 fprintf(stderr, "%20s = %s%s (len %zu)\n", a1, 403 fprintf(stderr, "%20s = %s%s (len %zu)\n", a1,
diff --git a/regress/unittests/test_helper/test_helper.h b/regress/unittests/test_helper/test_helper.h
index a398c615f..1d9c66986 100644
--- a/regress/unittests/test_helper/test_helper.h
+++ b/regress/unittests/test_helper/test_helper.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: test_helper.h,v 1.3 2014/05/02 09:41:32 andre Exp $ */ 1/* $OpenBSD: test_helper.h,v 1.6 2015/01/18 19:52:44 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2011 Damien Miller <djm@mindrot.org> 3 * Copyright (c) 2011 Damien Miller <djm@mindrot.org>
4 * 4 *
@@ -40,8 +40,11 @@ void tests(void);
40 40
41const char *test_data_file(const char *name); 41const char *test_data_file(const char *name);
42void test_start(const char *n); 42void test_start(const char *n);
43void test_info(char *s, size_t len);
43void set_onerror_func(test_onerror_func_t *f, void *ctx); 44void set_onerror_func(test_onerror_func_t *f, void *ctx);
44void test_done(void); 45void test_done(void);
46void test_subtest_info(const char *fmt, ...)
47 __attribute__((format(printf, 1, 2)));
45void ssl_err_check(const char *file, int line); 48void ssl_err_check(const char *file, int line);
46void assert_bignum(const char *file, int line, 49void assert_bignum(const char *file, int line,
47 const char *a1, const char *a2, 50 const char *a1, const char *a2,
@@ -280,6 +283,13 @@ void fuzz_cleanup(struct fuzz *fuzz);
280/* Prepare the next fuzz case in the series */ 283/* Prepare the next fuzz case in the series */
281void fuzz_next(struct fuzz *fuzz); 284void fuzz_next(struct fuzz *fuzz);
282 285
286/*
287 * Check whether this fuzz case is identical to the original
288 * This is slow, but useful if the caller needs to ensure that all tests
289 * generated change the input (e.g. when fuzzing signatures).
290 */
291int fuzz_matches_original(struct fuzz *fuzz);
292
283/* Determine whether the current fuzz sequence is exhausted (nonzero = yes) */ 293/* Determine whether the current fuzz sequence is exhausted (nonzero = yes) */
284int fuzz_done(struct fuzz *fuzz); 294int fuzz_done(struct fuzz *fuzz);
285 295
@@ -289,4 +299,5 @@ u_char *fuzz_ptr(struct fuzz *fuzz);
289 299
290/* Dump the current fuzz case to stderr */ 300/* Dump the current fuzz case to stderr */
291void fuzz_dump(struct fuzz *fuzz); 301void fuzz_dump(struct fuzz *fuzz);
302
292#endif /* _TEST_HELPER_H */ 303#endif /* _TEST_HELPER_H */