1 /* Copyright 2021 Google LLC
2 Licensed under the Apache License, Version 2.0 (the "License");
3 you may not use this file except in compliance with the License.
4 You may obtain a copy of the License at
5 http://www.apache.org/licenses/LICENSE-2.0
6 Unless required by applicable law or agreed to in writing, software
7 distributed under the License is distributed on an "AS IS" BASIS,
8 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9 See the License for the specific language governing permissions and
10 limitations under the License.
11 */
12
13 #include "config.h"
14 #include "syshead.h"
15 #include "init.h"
16 #include "proxy.h"
17 #include "interval.h"
18 #include "route.h"
19 #include "buffer.h"
20
21 #include "fuzz_randomizer.h"
22
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)23 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
24
25 fuzz_random_init(data, size);
26
27 gb_init();
28
29 struct route_option_list *opt;
30 struct route_list rl;
31
32 int route_list_inited = 0;
33 int route_list_ipv6_inited = 0;
34
35 struct context c;
36 memset(&c, 0, sizeof(struct context));
37 gc_init(&c.gc);
38 c.es = env_set_create(&c.gc);
39 init_options(&c.options, true);
40 net_ctx_init(&c, &c.net_ctx);
41 init_verb_mute(&c, IVM_LEVEL_1);
42
43 init_options_dev(&c.options);
44
45 // options_postprocess(&c.options);
46 pre_setup(&c.options);
47
48 setenv_settings(c.es, &c.options);
49
50 ALLOC_OBJ_CLEAR_GC(c.options.connection_list, struct connection_list,
51 &c.options.gc);
52 context_init_1(&c);
53
54 in_addr_t remote_host;
55 ssize_t default_metric;
56
57 struct route_ipv6_list rl6;
58 struct route_ipv6_option_list *opt6;
59
60 memset(&rl, 0, sizeof(rl));
61 memset(&rl6, 0, sizeof(rl6));
62 memset(&opt, 0, sizeof(opt));
63 memset(&opt6, 0, sizeof(opt6));
64
65 opt6 = new_route_ipv6_option_list(&c.gc);
66 opt = new_route_option_list(&c.gc);
67
68 int total_to_fuzz = fuzz_randomizer_get_int(1, 20);
69 for (int i = 0; i < total_to_fuzz; i++) {
70 int selector = fuzz_randomizer_get_int(0, 13);
71 switch (selector) {
72 case 0:
73 if (route_list_inited == 0) {
74 const char *remote_endpoint = gb_get_random_string();
75 memset(&rl, 0, sizeof(struct route_list));
76 rl.flags = fuzz_randomizer_get_int(0, 0xffffff);
77
78 init_route_list(&rl, opt, remote_endpoint, default_metric, remote_host,
79 c.es, &c);
80 route_list_inited = 1;
81 }
82 break;
83 case 1:
84 if (route_list_inited) {
85 in_addr_t addr;
86 route_list_add_vpn_gateway(&rl, c.es, addr);
87 }
88 break;
89 case 2:
90 if (route_list_inited && route_list_ipv6_inited) {
91 struct tuntap tt;
92 memset(&tt, 0, sizeof(tt));
93 add_routes(&rl, &rl6, &tt, 0, c.es, &c);
94 }
95 break;
96 case 3:
97 if (route_list_inited) {
98 setenv_routes(c.es, &rl);
99 }
100 break;
101 case 4:
102 if (route_list_inited) {
103 struct route_ipv4 r;
104 struct route_option ro;
105 ro.network = gb_get_random_string();
106 ro.netmask = gb_get_random_string();
107 ro.gateway = gb_get_random_string();
108 ro.metric = gb_get_random_string();
109 ro.next = NULL;
110
111 memset(&r, 0, sizeof(struct route_ipv4));
112 r.option = &ro;
113 r.flags = RT_DEFINED;
114 add_route(&r, NULL, 0, NULL, c.es, &c);
115 }
116 break;
117 case 5:
118 if (route_list_inited) {
119 char *s1 = get_random_string();
120 is_special_addr(s1);
121 free(s1);
122 }
123 break;
124 case 6:
125 if (route_list_ipv6_inited == 0) {
126 const char *remote_endpoint = gb_get_random_string();
127 memset(&rl, 0, sizeof(struct route_list));
128 struct in6_addr remote_host;
129
130 rl6.rgi6.flags = fuzz_randomizer_get_int(0, 0xffffff);
131 fuzz_get_random_data(&rl6.rgi6.hwaddr, 6);
132
133 char *t1 = gb_get_random_string();
134 if (strlen(t1) > 16) {
135 memcpy(rl6.rgi6.iface, t1, 16);
136 } else {
137 memcpy(rl6.rgi6.iface, t1, strlen(t1));
138 }
139
140 init_route_ipv6_list(&rl6, opt6, remote_endpoint, 0, &remote_host, c.es,
141 &c);
142 route_list_ipv6_inited = 1;
143 }
144 break;
145 case 7: {
146 unsigned int flags;
147 struct route_ipv6 r6;
148 struct tuntap tt;
149 memset(&tt, 0, sizeof(tt));
150 tt.actual_name = gb_get_random_string();
151 r6.iface = gb_get_random_string();
152 r6.flags = fuzz_randomizer_get_int(0, 0xfffff);
153 r6.netbits = fuzz_randomizer_get_int(0, 0xfffff);
154 r6.metric = fuzz_randomizer_get_int(0, 0xfffff);
155
156 r6.next = NULL;
157
158 add_route_ipv6(&r6, &tt, 0, c.es, &c);
159 } break;
160 case 8:
161 if (route_list_ipv6_inited && route_list_inited) {
162 delete_routes(&rl, &rl6, NULL, 0, c.es, &c);
163 route_list_ipv6_inited = 0;
164 route_list_inited = 0;
165 }
166 break;
167 case 9:
168 if (route_list_ipv6_inited) {
169 setenv_routes_ipv6(c.es, &rl6);
170 }
171 break;
172 case 10: {
173 add_route_ipv6_to_option_list(opt6, gb_get_random_string(),
174 gb_get_random_string(),
175 gb_get_random_string());
176 } break;
177 case 11: {
178 print_route_options(opt, M_NONFATAL);
179 } break;
180 case 12: {
181 add_route_to_option_list(opt, gb_get_random_string(),
182 gb_get_random_string(), gb_get_random_string(),
183 gb_get_random_string());
184 } break;
185 default:
186 break;
187 }
188 }
189
190 if (route_list_inited) {
191 gc_free(&rl.gc);
192 }
193 env_set_destroy(c.es);
194 context_gc_free(&c);
195
196 fuzz_random_destroy();
197
198 gb_cleanup();
199
200 return 0;
201 }
202