1*6bcae15aSdjm /* $OpenBSD: fuzz.c,v 1.8 2015/03/03 20:42:49 djm Exp $ */
229518ea0Sdjm /*
329518ea0Sdjm * Copyright (c) 2011 Damien Miller <djm@mindrot.org>
429518ea0Sdjm *
529518ea0Sdjm * Permission to use, copy, modify, and distribute this software for any
629518ea0Sdjm * purpose with or without fee is hereby granted, provided that the above
729518ea0Sdjm * copyright notice and this permission notice appear in all copies.
829518ea0Sdjm *
929518ea0Sdjm * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1029518ea0Sdjm * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1129518ea0Sdjm * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1229518ea0Sdjm * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1329518ea0Sdjm * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1429518ea0Sdjm * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1529518ea0Sdjm * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1629518ea0Sdjm */
1729518ea0Sdjm
1829518ea0Sdjm /* Utility functions/framework for fuzz tests */
1929518ea0Sdjm
2029518ea0Sdjm #include <sys/types.h>
21d531405cSdjm #include <sys/uio.h>
2229518ea0Sdjm
2329518ea0Sdjm #include <assert.h>
2429518ea0Sdjm #include <ctype.h>
2529518ea0Sdjm #include <stdio.h>
2629518ea0Sdjm #include <stdint.h>
2729518ea0Sdjm #include <stdlib.h>
2829518ea0Sdjm #include <string.h>
29d531405cSdjm #include <signal.h>
30d531405cSdjm #include <unistd.h>
3129518ea0Sdjm
3229518ea0Sdjm #include "test_helper.h"
33d531405cSdjm #include "atomicio.h"
3429518ea0Sdjm
3529518ea0Sdjm /* #define FUZZ_DEBUG */
3629518ea0Sdjm
3729518ea0Sdjm #ifdef FUZZ_DEBUG
3829518ea0Sdjm # define FUZZ_DBG(x) do { \
3929518ea0Sdjm printf("%s:%d %s: ", __FILE__, __LINE__, __func__); \
4029518ea0Sdjm printf x; \
4129518ea0Sdjm printf("\n"); \
4229518ea0Sdjm fflush(stdout); \
4329518ea0Sdjm } while (0)
4429518ea0Sdjm #else
4529518ea0Sdjm # define FUZZ_DBG(x)
4629518ea0Sdjm #endif
4729518ea0Sdjm
4829518ea0Sdjm /* For brevity later */
4929518ea0Sdjm typedef unsigned long long fuzz_ullong;
5029518ea0Sdjm
5129518ea0Sdjm /* For base-64 fuzzing */
5229518ea0Sdjm static const char fuzz_b64chars[] =
5329518ea0Sdjm "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
5429518ea0Sdjm
5529518ea0Sdjm struct fuzz {
5629518ea0Sdjm /* Fuzz method currently in use */
5729518ea0Sdjm int strategy;
5829518ea0Sdjm
5929518ea0Sdjm /* Fuzz methods remaining */
6029518ea0Sdjm int strategies;
6129518ea0Sdjm
6229518ea0Sdjm /* Original seed data blob */
6329518ea0Sdjm void *seed;
6429518ea0Sdjm size_t slen;
6529518ea0Sdjm
6629518ea0Sdjm /* Current working copy of seed with fuzz mutations applied */
6729518ea0Sdjm u_char *fuzzed;
6829518ea0Sdjm
6929518ea0Sdjm /* Used by fuzz methods */
7029518ea0Sdjm size_t o1, o2;
7129518ea0Sdjm };
7229518ea0Sdjm
7329518ea0Sdjm static const char *
fuzz_ntop(u_int n)7429518ea0Sdjm fuzz_ntop(u_int n)
7529518ea0Sdjm {
7629518ea0Sdjm switch (n) {
7729518ea0Sdjm case 0:
7829518ea0Sdjm return "NONE";
7929518ea0Sdjm case FUZZ_1_BIT_FLIP:
8029518ea0Sdjm return "FUZZ_1_BIT_FLIP";
8129518ea0Sdjm case FUZZ_2_BIT_FLIP:
8229518ea0Sdjm return "FUZZ_2_BIT_FLIP";
8329518ea0Sdjm case FUZZ_1_BYTE_FLIP:
8429518ea0Sdjm return "FUZZ_1_BYTE_FLIP";
8529518ea0Sdjm case FUZZ_2_BYTE_FLIP:
8629518ea0Sdjm return "FUZZ_2_BYTE_FLIP";
8729518ea0Sdjm case FUZZ_TRUNCATE_START:
8829518ea0Sdjm return "FUZZ_TRUNCATE_START";
8929518ea0Sdjm case FUZZ_TRUNCATE_END:
9029518ea0Sdjm return "FUZZ_TRUNCATE_END";
9129518ea0Sdjm case FUZZ_BASE64:
9229518ea0Sdjm return "FUZZ_BASE64";
9329518ea0Sdjm default:
9429518ea0Sdjm abort();
9529518ea0Sdjm }
9629518ea0Sdjm }
9729518ea0Sdjm
98d531405cSdjm static int
fuzz_fmt(struct fuzz * fuzz,char * s,size_t n)99d531405cSdjm fuzz_fmt(struct fuzz *fuzz, char *s, size_t n)
100d531405cSdjm {
101d531405cSdjm if (fuzz == NULL)
102d531405cSdjm return -1;
103d531405cSdjm
104d531405cSdjm switch (fuzz->strategy) {
105d531405cSdjm case FUZZ_1_BIT_FLIP:
106d531405cSdjm snprintf(s, n, "%s case %zu of %zu (bit: %zu)\n",
107d531405cSdjm fuzz_ntop(fuzz->strategy),
108d531405cSdjm fuzz->o1, fuzz->slen * 8, fuzz->o1);
109d531405cSdjm return 0;
110d531405cSdjm case FUZZ_2_BIT_FLIP:
111d531405cSdjm snprintf(s, n, "%s case %llu of %llu (bits: %zu, %zu)\n",
112d531405cSdjm fuzz_ntop(fuzz->strategy),
113d531405cSdjm (((fuzz_ullong)fuzz->o2) * fuzz->slen * 8) + fuzz->o1,
114d531405cSdjm ((fuzz_ullong)fuzz->slen * 8) * fuzz->slen * 8,
115d531405cSdjm fuzz->o1, fuzz->o2);
116d531405cSdjm return 0;
117d531405cSdjm case FUZZ_1_BYTE_FLIP:
118d531405cSdjm snprintf(s, n, "%s case %zu of %zu (byte: %zu)\n",
119d531405cSdjm fuzz_ntop(fuzz->strategy),
120d531405cSdjm fuzz->o1, fuzz->slen, fuzz->o1);
121d531405cSdjm return 0;
122d531405cSdjm case FUZZ_2_BYTE_FLIP:
123d531405cSdjm snprintf(s, n, "%s case %llu of %llu (bytes: %zu, %zu)\n",
124d531405cSdjm fuzz_ntop(fuzz->strategy),
125d531405cSdjm (((fuzz_ullong)fuzz->o2) * fuzz->slen) + fuzz->o1,
126d531405cSdjm ((fuzz_ullong)fuzz->slen) * fuzz->slen,
127d531405cSdjm fuzz->o1, fuzz->o2);
128d531405cSdjm return 0;
129d531405cSdjm case FUZZ_TRUNCATE_START:
130d531405cSdjm snprintf(s, n, "%s case %zu of %zu (offset: %zu)\n",
131d531405cSdjm fuzz_ntop(fuzz->strategy),
132d531405cSdjm fuzz->o1, fuzz->slen, fuzz->o1);
133d531405cSdjm return 0;
134d531405cSdjm case FUZZ_TRUNCATE_END:
135d531405cSdjm snprintf(s, n, "%s case %zu of %zu (offset: %zu)\n",
136d531405cSdjm fuzz_ntop(fuzz->strategy),
137d531405cSdjm fuzz->o1, fuzz->slen, fuzz->o1);
138d531405cSdjm return 0;
139d531405cSdjm case FUZZ_BASE64:
140d531405cSdjm assert(fuzz->o2 < sizeof(fuzz_b64chars) - 1);
141d531405cSdjm snprintf(s, n, "%s case %llu of %llu (offset: %zu char: %c)\n",
142d531405cSdjm fuzz_ntop(fuzz->strategy),
143d531405cSdjm (fuzz->o1 * (fuzz_ullong)64) + fuzz->o2,
144d531405cSdjm fuzz->slen * (fuzz_ullong)64, fuzz->o1,
145d531405cSdjm fuzz_b64chars[fuzz->o2]);
146d531405cSdjm return 0;
147d531405cSdjm default:
148d531405cSdjm return -1;
149d531405cSdjm abort();
150d531405cSdjm }
151d531405cSdjm }
152d531405cSdjm
15387cf98b2Sdjm static void
dump(u_char * p,size_t len)15487cf98b2Sdjm dump(u_char *p, size_t len)
15529518ea0Sdjm {
15687cf98b2Sdjm size_t i, j;
15729518ea0Sdjm
15829518ea0Sdjm for (i = 0; i < len; i += 16) {
15929518ea0Sdjm fprintf(stderr, "%.4zd: ", i);
16029518ea0Sdjm for (j = i; j < i + 16; j++) {
16129518ea0Sdjm if (j < len)
16229518ea0Sdjm fprintf(stderr, "%02x ", p[j]);
16329518ea0Sdjm else
16429518ea0Sdjm fprintf(stderr, " ");
16529518ea0Sdjm }
16629518ea0Sdjm fprintf(stderr, " ");
16729518ea0Sdjm for (j = i; j < i + 16; j++) {
16829518ea0Sdjm if (j < len) {
16929518ea0Sdjm if (isascii(p[j]) && isprint(p[j]))
17029518ea0Sdjm fprintf(stderr, "%c", p[j]);
17129518ea0Sdjm else
17229518ea0Sdjm fprintf(stderr, ".");
17329518ea0Sdjm }
17429518ea0Sdjm }
17529518ea0Sdjm fprintf(stderr, "\n");
17629518ea0Sdjm }
17729518ea0Sdjm }
17829518ea0Sdjm
17987cf98b2Sdjm void
fuzz_dump(struct fuzz * fuzz)18087cf98b2Sdjm fuzz_dump(struct fuzz *fuzz)
18187cf98b2Sdjm {
18287cf98b2Sdjm char buf[256];
18387cf98b2Sdjm
18487cf98b2Sdjm if (fuzz_fmt(fuzz, buf, sizeof(buf)) != 0) {
18587cf98b2Sdjm fprintf(stderr, "%s: fuzz invalid\n", __func__);
18687cf98b2Sdjm abort();
18787cf98b2Sdjm }
18887cf98b2Sdjm fputs(buf, stderr);
18987cf98b2Sdjm fprintf(stderr, "fuzz original %p len = %zu\n", fuzz->seed, fuzz->slen);
19087cf98b2Sdjm dump(fuzz->seed, fuzz->slen);
19187cf98b2Sdjm fprintf(stderr, "fuzz context %p len = %zu\n", fuzz, fuzz_len(fuzz));
19287cf98b2Sdjm dump(fuzz_ptr(fuzz), fuzz_len(fuzz));
19387cf98b2Sdjm }
19487cf98b2Sdjm
195d531405cSdjm #ifdef SIGINFO
196d531405cSdjm static struct fuzz *last_fuzz;
197d531405cSdjm
198d531405cSdjm static void
siginfo(int unused)199*6bcae15aSdjm siginfo(int unused __attribute__((__unused__)))
200d531405cSdjm {
201d531405cSdjm char buf[256];
202d531405cSdjm
203d531405cSdjm test_info(buf, sizeof(buf));
204d531405cSdjm atomicio(vwrite, STDERR_FILENO, buf, strlen(buf));
205d531405cSdjm if (last_fuzz != NULL) {
206d531405cSdjm fuzz_fmt(last_fuzz, buf, sizeof(buf));
207d531405cSdjm atomicio(vwrite, STDERR_FILENO, buf, strlen(buf));
208d531405cSdjm }
209d531405cSdjm }
210d531405cSdjm #endif
211d531405cSdjm
21229518ea0Sdjm struct fuzz *
fuzz_begin(u_int strategies,const void * p,size_t l)21393107337Sdjm fuzz_begin(u_int strategies, const void *p, size_t l)
21429518ea0Sdjm {
21529518ea0Sdjm struct fuzz *ret = calloc(sizeof(*ret), 1);
21629518ea0Sdjm
21729518ea0Sdjm assert(p != NULL);
21829518ea0Sdjm assert(ret != NULL);
21929518ea0Sdjm ret->seed = malloc(l);
22029518ea0Sdjm assert(ret->seed != NULL);
22129518ea0Sdjm memcpy(ret->seed, p, l);
22229518ea0Sdjm ret->slen = l;
22329518ea0Sdjm ret->strategies = strategies;
22429518ea0Sdjm
22529518ea0Sdjm assert(ret->slen < SIZE_MAX / 8);
22629518ea0Sdjm assert(ret->strategies <= (FUZZ_MAX|(FUZZ_MAX-1)));
22729518ea0Sdjm
22829518ea0Sdjm FUZZ_DBG(("begin, ret = %p", ret));
22929518ea0Sdjm
23029518ea0Sdjm fuzz_next(ret);
231d531405cSdjm
232d531405cSdjm #ifdef SIGINFO
233d531405cSdjm last_fuzz = ret;
234d531405cSdjm signal(SIGINFO, siginfo);
235d531405cSdjm #endif
236d531405cSdjm
23729518ea0Sdjm return ret;
23829518ea0Sdjm }
23929518ea0Sdjm
24029518ea0Sdjm void
fuzz_cleanup(struct fuzz * fuzz)24129518ea0Sdjm fuzz_cleanup(struct fuzz *fuzz)
24229518ea0Sdjm {
24329518ea0Sdjm FUZZ_DBG(("cleanup, fuzz = %p", fuzz));
244d531405cSdjm #ifdef SIGINFO
245d531405cSdjm last_fuzz = NULL;
246d531405cSdjm signal(SIGINFO, SIG_DFL);
247d531405cSdjm #endif
24829518ea0Sdjm assert(fuzz != NULL);
24929518ea0Sdjm assert(fuzz->seed != NULL);
25029518ea0Sdjm assert(fuzz->fuzzed != NULL);
25129518ea0Sdjm free(fuzz->seed);
25229518ea0Sdjm free(fuzz->fuzzed);
25329518ea0Sdjm free(fuzz);
25429518ea0Sdjm }
25529518ea0Sdjm
25629518ea0Sdjm static int
fuzz_strategy_done(struct fuzz * fuzz)25729518ea0Sdjm fuzz_strategy_done(struct fuzz *fuzz)
25829518ea0Sdjm {
25929518ea0Sdjm FUZZ_DBG(("fuzz = %p, strategy = %s, o1 = %zu, o2 = %zu, slen = %zu",
26029518ea0Sdjm fuzz, fuzz_ntop(fuzz->strategy), fuzz->o1, fuzz->o2, fuzz->slen));
26129518ea0Sdjm
26229518ea0Sdjm switch (fuzz->strategy) {
26329518ea0Sdjm case FUZZ_1_BIT_FLIP:
26429518ea0Sdjm return fuzz->o1 >= fuzz->slen * 8;
26529518ea0Sdjm case FUZZ_2_BIT_FLIP:
26629518ea0Sdjm return fuzz->o2 >= fuzz->slen * 8;
26729518ea0Sdjm case FUZZ_2_BYTE_FLIP:
26829518ea0Sdjm return fuzz->o2 >= fuzz->slen;
26929518ea0Sdjm case FUZZ_1_BYTE_FLIP:
27029518ea0Sdjm case FUZZ_TRUNCATE_START:
27129518ea0Sdjm case FUZZ_TRUNCATE_END:
27229518ea0Sdjm case FUZZ_BASE64:
27329518ea0Sdjm return fuzz->o1 >= fuzz->slen;
27429518ea0Sdjm default:
27529518ea0Sdjm abort();
27629518ea0Sdjm }
27729518ea0Sdjm }
27829518ea0Sdjm
27929518ea0Sdjm void
fuzz_next(struct fuzz * fuzz)28029518ea0Sdjm fuzz_next(struct fuzz *fuzz)
28129518ea0Sdjm {
28229518ea0Sdjm u_int i;
28329518ea0Sdjm
28429518ea0Sdjm FUZZ_DBG(("start, fuzz = %p, strategy = %s, strategies = 0x%lx, "
28529518ea0Sdjm "o1 = %zu, o2 = %zu, slen = %zu", fuzz, fuzz_ntop(fuzz->strategy),
28629518ea0Sdjm (u_long)fuzz->strategies, fuzz->o1, fuzz->o2, fuzz->slen));
28729518ea0Sdjm
28829518ea0Sdjm if (fuzz->strategy == 0 || fuzz_strategy_done(fuzz)) {
28929518ea0Sdjm /* If we are just starting out, we need to allocate too */
29029518ea0Sdjm if (fuzz->fuzzed == NULL) {
29129518ea0Sdjm FUZZ_DBG(("alloc"));
29229518ea0Sdjm fuzz->fuzzed = calloc(fuzz->slen, 1);
29329518ea0Sdjm }
29429518ea0Sdjm /* Pick next strategy */
29529518ea0Sdjm FUZZ_DBG(("advance"));
29629518ea0Sdjm for (i = 1; i <= FUZZ_MAX; i <<= 1) {
29729518ea0Sdjm if ((fuzz->strategies & i) != 0) {
29829518ea0Sdjm fuzz->strategy = i;
29929518ea0Sdjm break;
30029518ea0Sdjm }
30129518ea0Sdjm }
30229518ea0Sdjm FUZZ_DBG(("selected = %u", fuzz->strategy));
30329518ea0Sdjm if (fuzz->strategy == 0) {
30429518ea0Sdjm FUZZ_DBG(("done, no more strategies"));
30529518ea0Sdjm return;
30629518ea0Sdjm }
30729518ea0Sdjm fuzz->strategies &= ~(fuzz->strategy);
30829518ea0Sdjm fuzz->o1 = fuzz->o2 = 0;
30929518ea0Sdjm }
31029518ea0Sdjm
31129518ea0Sdjm assert(fuzz->fuzzed != NULL);
31229518ea0Sdjm
31329518ea0Sdjm switch (fuzz->strategy) {
31429518ea0Sdjm case FUZZ_1_BIT_FLIP:
31529518ea0Sdjm assert(fuzz->o1 / 8 < fuzz->slen);
31629518ea0Sdjm memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen);
31729518ea0Sdjm fuzz->fuzzed[fuzz->o1 / 8] ^= 1 << (fuzz->o1 % 8);
31829518ea0Sdjm fuzz->o1++;
31929518ea0Sdjm break;
32029518ea0Sdjm case FUZZ_2_BIT_FLIP:
32129518ea0Sdjm assert(fuzz->o1 / 8 < fuzz->slen);
32229518ea0Sdjm assert(fuzz->o2 / 8 < fuzz->slen);
32329518ea0Sdjm memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen);
32429518ea0Sdjm fuzz->fuzzed[fuzz->o1 / 8] ^= 1 << (fuzz->o1 % 8);
32529518ea0Sdjm fuzz->fuzzed[fuzz->o2 / 8] ^= 1 << (fuzz->o2 % 8);
32629518ea0Sdjm fuzz->o1++;
32729518ea0Sdjm if (fuzz->o1 >= fuzz->slen * 8) {
32829518ea0Sdjm fuzz->o1 = 0;
32929518ea0Sdjm fuzz->o2++;
33029518ea0Sdjm }
33129518ea0Sdjm break;
33229518ea0Sdjm case FUZZ_1_BYTE_FLIP:
33329518ea0Sdjm assert(fuzz->o1 < fuzz->slen);
33429518ea0Sdjm memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen);
33529518ea0Sdjm fuzz->fuzzed[fuzz->o1] ^= 0xff;
33629518ea0Sdjm fuzz->o1++;
33729518ea0Sdjm break;
33829518ea0Sdjm case FUZZ_2_BYTE_FLIP:
33929518ea0Sdjm assert(fuzz->o1 < fuzz->slen);
34029518ea0Sdjm assert(fuzz->o2 < fuzz->slen);
34129518ea0Sdjm memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen);
34229518ea0Sdjm fuzz->fuzzed[fuzz->o1] ^= 0xff;
34329518ea0Sdjm fuzz->fuzzed[fuzz->o2] ^= 0xff;
34429518ea0Sdjm fuzz->o1++;
34529518ea0Sdjm if (fuzz->o1 >= fuzz->slen) {
34629518ea0Sdjm fuzz->o1 = 0;
34729518ea0Sdjm fuzz->o2++;
34829518ea0Sdjm }
34929518ea0Sdjm break;
35029518ea0Sdjm case FUZZ_TRUNCATE_START:
35129518ea0Sdjm case FUZZ_TRUNCATE_END:
35229518ea0Sdjm assert(fuzz->o1 < fuzz->slen);
35329518ea0Sdjm memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen);
35429518ea0Sdjm fuzz->o1++;
35529518ea0Sdjm break;
35629518ea0Sdjm case FUZZ_BASE64:
35729518ea0Sdjm assert(fuzz->o1 < fuzz->slen);
35829518ea0Sdjm assert(fuzz->o2 < sizeof(fuzz_b64chars) - 1);
35929518ea0Sdjm memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen);
36029518ea0Sdjm fuzz->fuzzed[fuzz->o1] = fuzz_b64chars[fuzz->o2];
36129518ea0Sdjm fuzz->o2++;
36229518ea0Sdjm if (fuzz->o2 >= sizeof(fuzz_b64chars) - 1) {
36329518ea0Sdjm fuzz->o2 = 0;
36429518ea0Sdjm fuzz->o1++;
36529518ea0Sdjm }
36629518ea0Sdjm break;
36729518ea0Sdjm default:
36829518ea0Sdjm abort();
36929518ea0Sdjm }
37029518ea0Sdjm
37129518ea0Sdjm FUZZ_DBG(("done, fuzz = %p, strategy = %s, strategies = 0x%lx, "
37229518ea0Sdjm "o1 = %zu, o2 = %zu, slen = %zu", fuzz, fuzz_ntop(fuzz->strategy),
37329518ea0Sdjm (u_long)fuzz->strategies, fuzz->o1, fuzz->o2, fuzz->slen));
37429518ea0Sdjm }
37529518ea0Sdjm
37629518ea0Sdjm int
fuzz_matches_original(struct fuzz * fuzz)37760d08003Sdjm fuzz_matches_original(struct fuzz *fuzz)
37860d08003Sdjm {
37960d08003Sdjm if (fuzz_len(fuzz) != fuzz->slen)
38060d08003Sdjm return 0;
38160d08003Sdjm return memcmp(fuzz_ptr(fuzz), fuzz->seed, fuzz->slen) == 0;
38260d08003Sdjm }
38360d08003Sdjm
38460d08003Sdjm int
fuzz_done(struct fuzz * fuzz)38529518ea0Sdjm fuzz_done(struct fuzz *fuzz)
38629518ea0Sdjm {
38729518ea0Sdjm FUZZ_DBG(("fuzz = %p, strategies = 0x%lx", fuzz,
38829518ea0Sdjm (u_long)fuzz->strategies));
38929518ea0Sdjm
39029518ea0Sdjm return fuzz_strategy_done(fuzz) && fuzz->strategies == 0;
39129518ea0Sdjm }
39229518ea0Sdjm
39329518ea0Sdjm size_t
fuzz_len(struct fuzz * fuzz)39429518ea0Sdjm fuzz_len(struct fuzz *fuzz)
39529518ea0Sdjm {
39629518ea0Sdjm assert(fuzz->fuzzed != NULL);
39729518ea0Sdjm switch (fuzz->strategy) {
39829518ea0Sdjm case FUZZ_1_BIT_FLIP:
39929518ea0Sdjm case FUZZ_2_BIT_FLIP:
40029518ea0Sdjm case FUZZ_1_BYTE_FLIP:
40129518ea0Sdjm case FUZZ_2_BYTE_FLIP:
40229518ea0Sdjm case FUZZ_BASE64:
40329518ea0Sdjm return fuzz->slen;
40429518ea0Sdjm case FUZZ_TRUNCATE_START:
40529518ea0Sdjm case FUZZ_TRUNCATE_END:
40629518ea0Sdjm assert(fuzz->o1 <= fuzz->slen);
40729518ea0Sdjm return fuzz->slen - fuzz->o1;
40829518ea0Sdjm default:
40929518ea0Sdjm abort();
41029518ea0Sdjm }
41129518ea0Sdjm }
41229518ea0Sdjm
41329518ea0Sdjm u_char *
fuzz_ptr(struct fuzz * fuzz)41429518ea0Sdjm fuzz_ptr(struct fuzz *fuzz)
41529518ea0Sdjm {
41629518ea0Sdjm assert(fuzz->fuzzed != NULL);
41729518ea0Sdjm switch (fuzz->strategy) {
41829518ea0Sdjm case FUZZ_1_BIT_FLIP:
41929518ea0Sdjm case FUZZ_2_BIT_FLIP:
42029518ea0Sdjm case FUZZ_1_BYTE_FLIP:
42129518ea0Sdjm case FUZZ_2_BYTE_FLIP:
42229518ea0Sdjm case FUZZ_BASE64:
42329518ea0Sdjm return fuzz->fuzzed;
42429518ea0Sdjm case FUZZ_TRUNCATE_START:
42529518ea0Sdjm assert(fuzz->o1 <= fuzz->slen);
42629518ea0Sdjm return fuzz->fuzzed + fuzz->o1;
42729518ea0Sdjm case FUZZ_TRUNCATE_END:
42829518ea0Sdjm assert(fuzz->o1 <= fuzz->slen);
42929518ea0Sdjm return fuzz->fuzzed;
43029518ea0Sdjm default:
43129518ea0Sdjm abort();
43229518ea0Sdjm }
43329518ea0Sdjm }
43429518ea0Sdjm
435