Path: blob/main/contrib/libder/tests/make_corpus.c
39478 views
/*-1* Copyright (c) 2024 Kyle Evans <[email protected]>2*3* SPDX-License-Identifier: BSD-2-Clause4*/56#include <sys/param.h>78#undef NDEBUG9#include <assert.h>10#include <err.h>11#include <fcntl.h>12#include <stdbool.h>13#include <stdio.h>14#include <stdlib.h>15#include <string.h>16#include <unistd.h>1718#include <libder.h>1920#include "fuzzers.h"2122#define LARGE_SIZE (1024 * 64)2324static const uint8_t empty_seq[] = { BT_SEQUENCE, 0x00 };25static const uint8_t long_size[21] = { BT_OCTETSTRING, 0x83, 0x00, 0x00, 0x10 };2627/* 64k */28#define LARGE_SIZE_ENCODING 0x83, 0x01, 0x00, 0x0029static const uint8_t large_octet[LARGE_SIZE + 5] = { BT_OCTETSTRING, LARGE_SIZE_ENCODING };3031#define VARLEN_SEQ BT_OCTETSTRING, 0x04, 0x01, 0x02, 0x03, 0x0432#define VARLEN_CHILDREN VARLEN_SEQ, VARLEN_SEQ, VARLEN_SEQ33static const uint8_t varlen[] = { BT_SEQUENCE, 0x80,34VARLEN_CHILDREN, 0x00, 0x00 };3536#define BITSTRING1 BT_BITSTRING, 0x04, 0x03, 0xc0, 0xc0, 0xcc37#define BITSTRING2 BT_BITSTRING, 0x04, 0x05, 0xdd, 0xdd, 0xff38static const uint8_t constructed_bitstring[] = { 0x20 | BT_BITSTRING,392 * 6, BITSTRING1, BITSTRING2 };4041#define FUZZER_SEED(seq) { #seq, sizeof(seq), seq }42static const struct seed {43const char *seed_name;44size_t seed_seqsz;45const uint8_t *seed_seq;46} seeds[] = {47FUZZER_SEED(empty_seq),48FUZZER_SEED(long_size),49FUZZER_SEED(large_octet),50FUZZER_SEED(varlen),51FUZZER_SEED(constructed_bitstring),52};5354static void55usage(void)56{57fprintf(stderr, "usage: %s [-H] <corpus-dir>\n", getprogname());58exit(1);59}6061static void62write_one(const struct fuzz_params *params, const struct seed *seed, int dirfd,63bool striphdr)64{65char *name;66int fd = -1;6768assert(asprintf(&name, "base_%d_%d_%d_%s", params->type,69params->buftype, params->strict, seed->seed_name) != -1);7071fd = openat(dirfd, name, O_RDWR | O_TRUNC | O_CREAT, 0644);72assert(fd != -1);7374/*75* Write our params + seed; if we're stripping the header we won't have76* the full params, but we'll still have our signal byte for strict77* mode.78*/79if (!striphdr)80assert(write(fd, ¶ms, sizeof(params)) == sizeof(params));81else82assert(write(fd, ¶ms->strict, sizeof(params->strict)) == sizeof(params->strict));8384assert(write(fd, seed->seed_seq, seed->seed_seqsz) == seed->seed_seqsz);8586free(name);87close(fd);88}8990int91main(int argc, char *argv[])92{93struct fuzz_params params;94const struct seed *seed;95const char *seed_dir;96int dirfd = -1;97bool striphdr = false;9899if (argc < 2 || argc > 3)100usage();101102if (argc == 3 && strcmp(argv[1], "-H") != 0)103usage();104105striphdr = argc == 3;106seed_dir = argv[argc - 1];107108dirfd = open(seed_dir, O_SEARCH);109if (dirfd == -1)110err(1, "%s: open", seed_dir);111112memset(¶ms, 0, sizeof(params));113114for (int type = 0; type < STREAM_END; type++) {115params.type = type;116117for (int buffered = 0; buffered < BUFFER_END; buffered++) {118params.buftype = buffered;119120for (uint8_t strict = 0; strict < 2; strict++) {121params.strict = strict;122123for (size_t i = 0; i < nitems(seeds); i++) {124seed = &seeds[i];125126write_one(¶ms, seed, dirfd, striphdr);127}128}129130if (type != STREAM_FILE)131break;132}133}134135close(dirfd);136}137138139