xref: /freebsd/contrib/libder/tests/fuzz_write.c (revision 35c0a8c449fd2b7f75029ebed5e10852240f0865)
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
LLVMFuzzerTestOneInput(const uint8_t * data,size_t sz)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