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