Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/pkg
Path: blob/main/external/libder/tests/make_corpus.c
2066 views
1
/*-
2
* Copyright (c) 2024 Kyle Evans <[email protected]>
3
*
4
* SPDX-License-Identifier: BSD-2-Clause
5
*/
6
7
#include <sys/param.h>
8
9
#undef NDEBUG
10
#include <assert.h>
11
#include <err.h>
12
#include <fcntl.h>
13
#include <stdbool.h>
14
#include <stdio.h>
15
#include <stdlib.h>
16
#include <string.h>
17
#include <unistd.h>
18
19
#include <libder.h>
20
21
#include "fuzzers.h"
22
23
#define LARGE_SIZE (1024 * 64)
24
25
static const uint8_t empty_seq[] = { BT_SEQUENCE, 0x00 };
26
static const uint8_t long_size[21] = { BT_OCTETSTRING, 0x83, 0x00, 0x00, 0x10 };
27
28
/* 64k */
29
#define LARGE_SIZE_ENCODING 0x83, 0x01, 0x00, 0x00
30
static const uint8_t large_octet[LARGE_SIZE + 5] = { BT_OCTETSTRING, LARGE_SIZE_ENCODING };
31
32
#define VARLEN_SEQ BT_OCTETSTRING, 0x04, 0x01, 0x02, 0x03, 0x04
33
#define VARLEN_CHILDREN VARLEN_SEQ, VARLEN_SEQ, VARLEN_SEQ
34
static const uint8_t varlen[] = { BT_SEQUENCE, 0x80,
35
VARLEN_CHILDREN, 0x00, 0x00 };
36
37
#define BITSTRING1 BT_BITSTRING, 0x04, 0x03, 0xc0, 0xc0, 0xcc
38
#define BITSTRING2 BT_BITSTRING, 0x04, 0x05, 0xdd, 0xdd, 0xff
39
static const uint8_t constructed_bitstring[] = { 0x20 | BT_BITSTRING,
40
2 * 6, BITSTRING1, BITSTRING2 };
41
42
#define FUZZER_SEED(seq) { #seq, sizeof(seq), seq }
43
static const struct seed {
44
const char *seed_name;
45
size_t seed_seqsz;
46
const uint8_t *seed_seq;
47
} seeds[] = {
48
FUZZER_SEED(empty_seq),
49
FUZZER_SEED(long_size),
50
FUZZER_SEED(large_octet),
51
FUZZER_SEED(varlen),
52
FUZZER_SEED(constructed_bitstring),
53
};
54
55
static void
56
usage(void)
57
{
58
fprintf(stderr, "usage: %s [-H] <corpus-dir>\n", getprogname());
59
exit(1);
60
}
61
62
static void
63
write_one(const struct fuzz_params *params, const struct seed *seed, int dirfd,
64
bool striphdr)
65
{
66
char *name;
67
int fd = -1;
68
69
assert(asprintf(&name, "base_%d_%d_%d_%s", params->type,
70
params->buftype, params->strict, seed->seed_name) != -1);
71
72
fd = openat(dirfd, name, O_RDWR | O_TRUNC | O_CREAT, 0644);
73
assert(fd != -1);
74
75
/*
76
* Write our params + seed; if we're stripping the header we won't have
77
* the full params, but we'll still have our signal byte for strict
78
* mode.
79
*/
80
if (!striphdr)
81
assert(write(fd, &params, sizeof(params)) == sizeof(params));
82
else
83
assert(write(fd, &params->strict, sizeof(params->strict)) == sizeof(params->strict));
84
85
assert(write(fd, seed->seed_seq, seed->seed_seqsz) == seed->seed_seqsz);
86
87
free(name);
88
close(fd);
89
}
90
91
int
92
main(int argc, char *argv[])
93
{
94
struct fuzz_params params;
95
const struct seed *seed;
96
const char *seed_dir;
97
int dirfd = -1;
98
bool striphdr = false;
99
100
if (argc < 2 || argc > 3)
101
usage();
102
103
if (argc == 3 && strcmp(argv[1], "-H") != 0)
104
usage();
105
106
striphdr = argc == 3;
107
seed_dir = argv[argc - 1];
108
109
dirfd = open(seed_dir, O_SEARCH);
110
if (dirfd == -1)
111
err(1, "%s: open", seed_dir);
112
113
memset(&params, 0, sizeof(params));
114
115
for (int type = 0; type < STREAM_END; type++) {
116
params.type = type;
117
118
for (int buffered = 0; buffered < BUFFER_END; buffered++) {
119
params.buftype = buffered;
120
121
for (uint8_t strict = 0; strict < 2; strict++) {
122
params.strict = strict;
123
124
for (size_t i = 0; i < nitems(seeds); i++) {
125
seed = &seeds[i];
126
127
write_one(&params, seed, dirfd, striphdr);
128
}
129
}
130
131
if (type != STREAM_FILE)
132
break;
133
}
134
}
135
136
close(dirfd);
137
}
138
139