xref: /freebsd-src/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_fuzz.c (revision 1323ec571215a77ddd21294f0871979d5ad6b992)
1*1323ec57SEd Maste /* 	$OpenBSD: test_sshbuf_fuzz.c,v 1.4 2021/12/18 06:53:59 anton Exp $ */
2a0ee8cc6SDag-Erling Smørgrav /*
3a0ee8cc6SDag-Erling Smørgrav  * Regress test for sshbuf.h buffer API
4a0ee8cc6SDag-Erling Smørgrav  *
5a0ee8cc6SDag-Erling Smørgrav  * Placed in the public domain
6a0ee8cc6SDag-Erling Smørgrav  */
7a0ee8cc6SDag-Erling Smørgrav 
8a0ee8cc6SDag-Erling Smørgrav #include "includes.h"
9a0ee8cc6SDag-Erling Smørgrav 
10a0ee8cc6SDag-Erling Smørgrav #include <sys/types.h>
11a0ee8cc6SDag-Erling Smørgrav #include <stdio.h>
12a0ee8cc6SDag-Erling Smørgrav #ifdef HAVE_STDINT_H
13a0ee8cc6SDag-Erling Smørgrav # include <stdint.h>
14a0ee8cc6SDag-Erling Smørgrav #endif
15a0ee8cc6SDag-Erling Smørgrav #include <stdlib.h>
16a0ee8cc6SDag-Erling Smørgrav #include <string.h>
17a0ee8cc6SDag-Erling Smørgrav 
18a0ee8cc6SDag-Erling Smørgrav #include "../test_helper/test_helper.h"
19a0ee8cc6SDag-Erling Smørgrav 
20a0ee8cc6SDag-Erling Smørgrav #include "ssherr.h"
21a0ee8cc6SDag-Erling Smørgrav #include "sshbuf.h"
22a0ee8cc6SDag-Erling Smørgrav 
23a0ee8cc6SDag-Erling Smørgrav #define NUM_FUZZ_TESTS (1 << 18)
24a0ee8cc6SDag-Erling Smørgrav 
25a0ee8cc6SDag-Erling Smørgrav void sshbuf_fuzz_tests(void);
26a0ee8cc6SDag-Erling Smørgrav 
27a0ee8cc6SDag-Erling Smørgrav void
sshbuf_fuzz_tests(void)28a0ee8cc6SDag-Erling Smørgrav sshbuf_fuzz_tests(void)
29a0ee8cc6SDag-Erling Smørgrav {
30a0ee8cc6SDag-Erling Smørgrav 	struct sshbuf *p1;
31a0ee8cc6SDag-Erling Smørgrav 	u_char *dp;
3219261079SEd Maste 	size_t sz, sz2, i, ntests = NUM_FUZZ_TESTS;
33a0ee8cc6SDag-Erling Smørgrav 	u_int32_t r;
34a0ee8cc6SDag-Erling Smørgrav 	int ret;
35a0ee8cc6SDag-Erling Smørgrav 
3619261079SEd Maste 	if (test_is_fast())
3719261079SEd Maste 		ntests >>= 2;
3819261079SEd Maste 	if (test_is_slow())
3919261079SEd Maste 		ntests <<= 2;
4019261079SEd Maste 
41a0ee8cc6SDag-Erling Smørgrav 	/* NB. uses sshbuf internals */
42a0ee8cc6SDag-Erling Smørgrav 	TEST_START("fuzz alloc/dealloc");
43a0ee8cc6SDag-Erling Smørgrav 	p1 = sshbuf_new();
44a0ee8cc6SDag-Erling Smørgrav 	ASSERT_INT_EQ(sshbuf_set_max_size(p1, 16 * 1024), 0);
45a0ee8cc6SDag-Erling Smørgrav 	ASSERT_PTR_NE(p1, NULL);
46a0ee8cc6SDag-Erling Smørgrav 	ASSERT_PTR_NE(sshbuf_ptr(p1), NULL);
47a0ee8cc6SDag-Erling Smørgrav 	ASSERT_MEM_ZERO_NE(sshbuf_ptr(p1), sshbuf_len(p1));
48*1323ec57SEd Maste 	for (i = 0; i < ntests; i++) {
49a0ee8cc6SDag-Erling Smørgrav 		r = arc4random_uniform(10);
50a0ee8cc6SDag-Erling Smørgrav 		if (r == 0) {
51a0ee8cc6SDag-Erling Smørgrav 			/* 10% chance: small reserve */
52a0ee8cc6SDag-Erling Smørgrav 			r = arc4random_uniform(10);
53a0ee8cc6SDag-Erling Smørgrav  fuzz_reserve:
54a0ee8cc6SDag-Erling Smørgrav 			sz = sshbuf_avail(p1);
55a0ee8cc6SDag-Erling Smørgrav 			sz2 = sshbuf_len(p1);
56a0ee8cc6SDag-Erling Smørgrav 			ret = sshbuf_reserve(p1, r, &dp);
57a0ee8cc6SDag-Erling Smørgrav 			if (ret < 0) {
58a0ee8cc6SDag-Erling Smørgrav 				ASSERT_PTR_EQ(dp, NULL);
59a0ee8cc6SDag-Erling Smørgrav 				ASSERT_SIZE_T_LT(sz, r);
60a0ee8cc6SDag-Erling Smørgrav 				ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz);
61a0ee8cc6SDag-Erling Smørgrav 				ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2);
62a0ee8cc6SDag-Erling Smørgrav 			} else {
63a0ee8cc6SDag-Erling Smørgrav 				ASSERT_PTR_NE(dp, NULL);
64a0ee8cc6SDag-Erling Smørgrav 				ASSERT_SIZE_T_GE(sz, r);
65a0ee8cc6SDag-Erling Smørgrav 				ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz - r);
66a0ee8cc6SDag-Erling Smørgrav 				ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2 + r);
67a0ee8cc6SDag-Erling Smørgrav 				memset(dp, arc4random_uniform(255) + 1, r);
68a0ee8cc6SDag-Erling Smørgrav 			}
69a0ee8cc6SDag-Erling Smørgrav 		} else if (r < 3) {
70a0ee8cc6SDag-Erling Smørgrav 			/* 20% chance: big reserve */
71a0ee8cc6SDag-Erling Smørgrav 			r = arc4random_uniform(8 * 1024);
72a0ee8cc6SDag-Erling Smørgrav 			goto fuzz_reserve;
73a0ee8cc6SDag-Erling Smørgrav 		} else if (r == 3) {
74a0ee8cc6SDag-Erling Smørgrav 			/* 10% chance: small consume */
75a0ee8cc6SDag-Erling Smørgrav 			r = arc4random_uniform(10);
76a0ee8cc6SDag-Erling Smørgrav  fuzz_consume:
77a0ee8cc6SDag-Erling Smørgrav 			sz = sshbuf_avail(p1);
78a0ee8cc6SDag-Erling Smørgrav 			sz2 = sshbuf_len(p1);
79a0ee8cc6SDag-Erling Smørgrav 			/* 50% change consume from end, otherwise start */
80a0ee8cc6SDag-Erling Smørgrav 			ret = ((arc4random() & 1) ?
81a0ee8cc6SDag-Erling Smørgrav 			    sshbuf_consume : sshbuf_consume_end)(p1, r);
82a0ee8cc6SDag-Erling Smørgrav 			if (ret < 0) {
83a0ee8cc6SDag-Erling Smørgrav 				ASSERT_SIZE_T_LT(sz2, r);
84a0ee8cc6SDag-Erling Smørgrav 				ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz);
85a0ee8cc6SDag-Erling Smørgrav 				ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2);
86a0ee8cc6SDag-Erling Smørgrav 			} else {
87a0ee8cc6SDag-Erling Smørgrav 				ASSERT_SIZE_T_GE(sz2, r);
88a0ee8cc6SDag-Erling Smørgrav 				ASSERT_SIZE_T_EQ(sshbuf_avail(p1), sz + r);
89a0ee8cc6SDag-Erling Smørgrav 				ASSERT_SIZE_T_EQ(sshbuf_len(p1), sz2 - r);
90a0ee8cc6SDag-Erling Smørgrav 			}
91a0ee8cc6SDag-Erling Smørgrav 		} else if (r < 8) {
92a0ee8cc6SDag-Erling Smørgrav 			/* 40% chance: big consume */
93a0ee8cc6SDag-Erling Smørgrav 			r = arc4random_uniform(2 * 1024);
94a0ee8cc6SDag-Erling Smørgrav 			goto fuzz_consume;
95a0ee8cc6SDag-Erling Smørgrav 		} else if (r == 8) {
96a0ee8cc6SDag-Erling Smørgrav 			/* 10% chance: reset max size */
97a0ee8cc6SDag-Erling Smørgrav 			r = arc4random_uniform(16 * 1024);
98a0ee8cc6SDag-Erling Smørgrav 			sz = sshbuf_max_size(p1);
99a0ee8cc6SDag-Erling Smørgrav 			if (sshbuf_set_max_size(p1, r) < 0)
100a0ee8cc6SDag-Erling Smørgrav 				ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), sz);
101a0ee8cc6SDag-Erling Smørgrav 			else
102a0ee8cc6SDag-Erling Smørgrav 				ASSERT_SIZE_T_EQ(sshbuf_max_size(p1), r);
103a0ee8cc6SDag-Erling Smørgrav 		} else {
104a0ee8cc6SDag-Erling Smørgrav 			if (arc4random_uniform(8192) == 0) {
105a0ee8cc6SDag-Erling Smørgrav 				/* tiny chance: new buffer */
106a0ee8cc6SDag-Erling Smørgrav 				ASSERT_PTR_NE(sshbuf_ptr(p1), NULL);
107a0ee8cc6SDag-Erling Smørgrav 				ASSERT_MEM_ZERO_NE(sshbuf_ptr(p1), sshbuf_len(p1));
108a0ee8cc6SDag-Erling Smørgrav 				sshbuf_free(p1);
109a0ee8cc6SDag-Erling Smørgrav 				p1 = sshbuf_new();
110a0ee8cc6SDag-Erling Smørgrav 				ASSERT_PTR_NE(p1, NULL);
111a0ee8cc6SDag-Erling Smørgrav 				ASSERT_INT_EQ(sshbuf_set_max_size(p1,
112a0ee8cc6SDag-Erling Smørgrav 				    16 * 1024), 0);
113a0ee8cc6SDag-Erling Smørgrav 			} else {
114a0ee8cc6SDag-Erling Smørgrav 				/* Almost 10%: giant reserve */
115a0ee8cc6SDag-Erling Smørgrav 				/* use arc4random_buf for r > 2^32 on 64 bit */
116a0ee8cc6SDag-Erling Smørgrav 				arc4random_buf(&r, sizeof(r));
117a0ee8cc6SDag-Erling Smørgrav 				while (r < SSHBUF_SIZE_MAX / 2) {
118a0ee8cc6SDag-Erling Smørgrav 					r <<= 1;
119a0ee8cc6SDag-Erling Smørgrav 					r |= arc4random() & 1;
120a0ee8cc6SDag-Erling Smørgrav 				}
121a0ee8cc6SDag-Erling Smørgrav 				goto fuzz_reserve;
122a0ee8cc6SDag-Erling Smørgrav 			}
123a0ee8cc6SDag-Erling Smørgrav 		}
124a0ee8cc6SDag-Erling Smørgrav 		ASSERT_PTR_NE(sshbuf_ptr(p1), NULL);
125a0ee8cc6SDag-Erling Smørgrav 		ASSERT_SIZE_T_LE(sshbuf_max_size(p1), 16 * 1024);
126a0ee8cc6SDag-Erling Smørgrav 	}
127a0ee8cc6SDag-Erling Smørgrav 	ASSERT_PTR_NE(sshbuf_ptr(p1), NULL);
128a0ee8cc6SDag-Erling Smørgrav 	ASSERT_MEM_ZERO_NE(sshbuf_ptr(p1), sshbuf_len(p1));
129a0ee8cc6SDag-Erling Smørgrav 	sshbuf_free(p1);
130a0ee8cc6SDag-Erling Smørgrav 	TEST_DONE();
131a0ee8cc6SDag-Erling Smørgrav }
132