1*35c0a8c4SKyle Evans /*- 2*35c0a8c4SKyle Evans * Copyright (c) 2024 Kyle Evans <kevans@FreeBSD.org> 3*35c0a8c4SKyle Evans * 4*35c0a8c4SKyle Evans * SPDX-License-Identifier: BSD-2-Clause 5*35c0a8c4SKyle Evans */ 6*35c0a8c4SKyle Evans 7*35c0a8c4SKyle Evans #include <sys/param.h> 8*35c0a8c4SKyle Evans #include <sys/socket.h> 9*35c0a8c4SKyle Evans 10*35c0a8c4SKyle Evans #include <assert.h> 11*35c0a8c4SKyle Evans #include <signal.h> 12*35c0a8c4SKyle Evans #include <stdbool.h> 13*35c0a8c4SKyle Evans #include <stdio.h> 14*35c0a8c4SKyle Evans #include <stdlib.h> 15*35c0a8c4SKyle Evans #include <unistd.h> 16*35c0a8c4SKyle Evans 17*35c0a8c4SKyle Evans #include <libder.h> 18*35c0a8c4SKyle Evans 19*35c0a8c4SKyle Evans #include "fuzzers.h" 20*35c0a8c4SKyle Evans 21*35c0a8c4SKyle Evans int 22*35c0a8c4SKyle Evans LLVMFuzzerTestOneInput(const uint8_t *data, size_t sz) 23*35c0a8c4SKyle Evans { 24*35c0a8c4SKyle Evans struct libder_ctx *ctx; 25*35c0a8c4SKyle Evans struct libder_object *obj; 26*35c0a8c4SKyle Evans size_t readsz; 27*35c0a8c4SKyle Evans int ret; 28*35c0a8c4SKyle Evans bool strict; 29*35c0a8c4SKyle Evans 30*35c0a8c4SKyle Evans if (sz < 2) 31*35c0a8c4SKyle Evans return (-1); 32*35c0a8c4SKyle Evans 33*35c0a8c4SKyle Evans /* 34*35c0a8c4SKyle Evans * I worked this in originally by just using the high bit of the first 35*35c0a8c4SKyle Evans * byte, but then I realized that encoding it that way would make it 36*35c0a8c4SKyle Evans * impossible to get strict validation of universal and application 37*35c0a8c4SKyle Evans * tags. The former is a bit more important than the latter. 38*35c0a8c4SKyle Evans */ 39*35c0a8c4SKyle Evans strict = !!data[0]; 40*35c0a8c4SKyle Evans data++; 41*35c0a8c4SKyle Evans sz--; 42*35c0a8c4SKyle Evans 43*35c0a8c4SKyle Evans ctx = libder_open(); 44*35c0a8c4SKyle Evans libder_set_strict(ctx, strict); 45*35c0a8c4SKyle Evans ret = -1; 46*35c0a8c4SKyle Evans readsz = sz; 47*35c0a8c4SKyle Evans obj = libder_read(ctx, data, &readsz); 48*35c0a8c4SKyle Evans if (obj == NULL || readsz != sz) 49*35c0a8c4SKyle Evans goto out; 50*35c0a8c4SKyle Evans 51*35c0a8c4SKyle Evans if (obj != NULL) { 52*35c0a8c4SKyle Evans uint8_t *buf = NULL; 53*35c0a8c4SKyle Evans size_t bufsz = 0; 54*35c0a8c4SKyle Evans 55*35c0a8c4SKyle Evans /* 56*35c0a8c4SKyle Evans * If we successfully read it, then it shouldn't 57*35c0a8c4SKyle Evans * overflow. We're letting libder allocate the buffer, 58*35c0a8c4SKyle Evans * so we shouldn't be able to hit the 'too small' bit. 59*35c0a8c4SKyle Evans * 60*35c0a8c4SKyle Evans * I can't imagine what other errors might happen, so 61*35c0a8c4SKyle Evans * we'll just assert on it. 62*35c0a8c4SKyle Evans */ 63*35c0a8c4SKyle Evans buf = libder_write(ctx, obj, buf, &bufsz); 64*35c0a8c4SKyle Evans if (buf == NULL) 65*35c0a8c4SKyle Evans goto out; 66*35c0a8c4SKyle Evans 67*35c0a8c4SKyle Evans assert(bufsz != 0); 68*35c0a8c4SKyle Evans 69*35c0a8c4SKyle Evans free(buf); 70*35c0a8c4SKyle Evans } 71*35c0a8c4SKyle Evans 72*35c0a8c4SKyle Evans ret = 0; 73*35c0a8c4SKyle Evans 74*35c0a8c4SKyle Evans out: 75*35c0a8c4SKyle Evans libder_obj_free(obj); 76*35c0a8c4SKyle Evans libder_close(ctx); 77*35c0a8c4SKyle Evans 78*35c0a8c4SKyle Evans return (ret); 79*35c0a8c4SKyle Evans } 80