• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <sys/time.h>
15 #include "syshead.h"
16 #include "interval.h"
17 #include "init.h"
18 #include "buffer.h"
19 #include "forward.h"
20 
21 #include "fuzz_randomizer.h"
22 
23 
init_c2_outgoing_link(struct context_2 * c2,struct gc_arena * gc)24 static int init_c2_outgoing_link(struct context_2 *c2, struct gc_arena *gc) {
25   struct link_socket_actual *to_link_addr = NULL;
26   struct link_socket *link_socket = NULL;
27   struct socks_proxy_info *socks_proxy = NULL;
28   struct buffer buf;
29 
30   c2->tun_write_bytes = 0;
31   ALLOC_ARRAY_GC(link_socket, struct link_socket, 1, gc);
32   memset(link_socket, 0, sizeof(*link_socket));
33 
34   c2->link_socket = link_socket;
35 
36   if (fuzz_randomizer_get_int(0, 2) != 0) {
37     c2->link_socket->info.proto = PROTO_UDP;
38   } else {
39     c2->link_socket->info.proto = PROTO_TCP_SERVER;
40   }
41 
42   ALLOC_ARRAY_GC(socks_proxy, struct socks_proxy_info, 1, gc);
43   memset(socks_proxy, 0, sizeof(*socks_proxy));
44   c2->link_socket->socks_proxy = socks_proxy;
45 
46   c2->frame.link_mtu_dynamic = fuzz_randomizer_get_int(0, 0xfffffff);
47   c2->frame.extra_frame = fuzz_randomizer_get_int(0, 0xfffffff);
48   c2->frame.extra_tun = fuzz_randomizer_get_int(0, 0xfffffff);
49   c2->frame.link_mtu = fuzz_randomizer_get_int(0, 0xfffffff);
50 
51   ALLOC_ARRAY_GC(to_link_addr, struct link_socket_actual, 1, gc);
52   memset(to_link_addr, 0, sizeof(*to_link_addr));
53   c2->to_link_addr = to_link_addr;
54 
55   c2->to_link_addr->dest.addr.sa.sa_family = AF_INET;
56   c2->to_link_addr->dest.addr.in4.sin_addr.s_addr = 1;
57 
58   char *tmp = get_random_string();
59   buf = alloc_buf_gc(strlen(tmp), gc);
60   buf_write(&buf, tmp, strlen(tmp));
61   int val = fuzz_randomizer_get_int(0, strlen(tmp));
62   buf.offset = val;
63   free(tmp);
64 
65   c2->link_socket->stream_buf.maxlen = BLEN(&buf);
66   c2->to_link = buf;
67 
68   if (buf.offset < 10) {
69     return -1;
70   }
71   return 0;
72 }
73 
fuzz_process_outgoing_link(const uint8_t * data,size_t size)74 void fuzz_process_outgoing_link(const uint8_t *data, size_t size) {
75   struct context ctx;
76   struct gc_arena gc = gc_new();
77   memset(&ctx, 0, sizeof(ctx));
78 
79   if (init_c2_outgoing_link(&ctx.c2, &gc) == 0) {
80     process_outgoing_link(&ctx);
81   }
82 
83   gc_free(&gc);
84 }
85 
_init_options(struct options * options,struct client_nat_entry ** cne,struct gc_arena * gc)86 static int _init_options(struct options *options, struct client_nat_entry **cne,
87                          struct gc_arena *gc) {
88   options->passtos = false;
89   options->mode = MODE_POINT_TO_POINT;
90   options->allow_recursive_routing = true;
91   options->client_nat = new_client_nat_list(gc);
92 
93   struct client_nat_entry *_cne;
94   ALLOC_ARRAY_GC(cne[0], struct client_nat_entry, 1, gc);
95   _cne = cne[0];
96   memset(_cne, 0, sizeof(struct client_nat_entry));
97 
98   struct client_nat_option_list clist;
99   clist.n = 1;
100   clist.entries[0] = *_cne;
101   copy_client_nat_option_list(options->client_nat, &clist);
102   options->route_gateway_via_dhcp = false;
103 
104   return 0;
105 }
106 
init_c2_incoming_tun(struct context_2 * c2,struct gc_arena * gc)107 static int init_c2_incoming_tun(struct context_2 *c2, struct gc_arena *gc) {
108   struct buffer buf;
109   memset(&buf, 0, sizeof(buf));
110 
111   struct link_socket *link_socket = NULL;
112   ALLOC_ARRAY_GC(link_socket, struct link_socket, 1, gc);
113   c2->link_socket = link_socket;
114 
115   ALLOC_OBJ_GC(c2->link_socket_info, struct link_socket_info, gc);
116   ALLOC_OBJ_GC(c2->link_socket_info->lsa, struct link_socket_addr, gc);
117   c2->link_socket_info->lsa->bind_local = NULL;
118   c2->link_socket_info->lsa->remote_list = NULL;
119   c2->link_socket_info->lsa->current_remote = NULL;
120   c2->link_socket_info->lsa->remote_list = NULL;
121   c2->es = env_set_create(gc);
122 
123   c2->frame.link_mtu_dynamic = 0;
124   c2->frame.extra_frame = 0;
125   c2->frame.extra_tun = 0;
126   c2->to_link_addr = NULL;
127 
128   char *tmp = get_random_string();
129   buf = alloc_buf(strlen(tmp));
130   buf_write(&buf, tmp, strlen(tmp));
131 
132   int retval;
133   if (strlen(tmp) > 5) {
134     retval = 0;
135   } else {
136     retval = 1;
137   }
138 
139   free(tmp);
140 
141   c2->buf = buf;
142   c2->buffers = init_context_buffers(&c2->frame);
143   c2->log_rw = false;
144 
145   return retval;
146 }
147 
run_process_incoming_tun(const uint8_t * data,size_t size)148 int run_process_incoming_tun(const uint8_t *data, size_t size) {
149   struct gc_arena gc;
150   struct context ctx;
151   struct client_nat_entry *cne[MAX_CLIENT_NAT];
152   struct route_list route_list;
153 
154   memset(&ctx, 0, sizeof(ctx));
155   memset(cne, 0, sizeof(cne));
156 
157   gc = gc_new();
158 
159   _init_options(&ctx.options, cne, &gc);
160 
161   // Init tuntap
162   struct tuntap tuntap;
163   tuntap.type = DEV_TYPE_TAP;
164 
165   ctx.c1.tuntap = &tuntap;
166 
167   int retval = init_c2_incoming_tun(&ctx.c2, &gc);
168   ctx.c1.route_list = &route_list;
169   if (retval == 0) {
170     process_incoming_tun(&ctx);
171   }
172 
173   free(ctx.c2.buf.data);
174   free_context_buffers(ctx.c2.buffers);
175   gc_free(&gc);
176 }
177 
init_c2_outgoing_tun(struct context_2 * c2,struct gc_arena * gc)178 static int init_c2_outgoing_tun(struct context_2 *c2, struct gc_arena *gc) {
179   struct buffer buf;
180 
181   c2->tun_write_bytes = 0;
182   c2->frame.link_mtu_dynamic = fuzz_randomizer_get_int(0, 0xfffffff);
183   c2->frame.extra_frame = fuzz_randomizer_get_int(0, 0xfffffff);
184   c2->frame.extra_tun = fuzz_randomizer_get_int(0, 0xfffffff);
185 
186   char *tmp = get_random_string();
187   buf = alloc_buf_gc(strlen(tmp), gc);
188   buf_write(&buf, tmp, strlen(tmp));
189   free(tmp);
190 
191   c2->to_tun = buf;
192   return 0;
193 }
194 
run_process_outgoing_tun(uint8_t * data,size_t size)195 void run_process_outgoing_tun(uint8_t *data, size_t size) {
196   struct gc_arena gc;
197   struct context ctx;
198   struct tuntap tuntap;
199 
200   memset(&ctx, 0, sizeof(ctx));
201   gc = gc_new();
202 
203   tuntap.type = DEV_TYPE_TAP;
204   ctx.c1.tuntap = &tuntap;
205 
206   init_c2_outgoing_tun(&ctx.c2, &gc);
207   process_outgoing_tun(&ctx);
208 
209   gc_free(&gc);
210 }
211 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)212 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
213   fuzz_random_init(data, size);
214 
215   int dec = fuzz_randomizer_get_int(0, 2);
216   if (dec == 0) {
217     run_process_incoming_tun(data, size);
218   }
219 	else if (dec == 1) {
220 		run_process_outgoing_tun(data, size);
221 	}
222   else {
223     fuzz_process_outgoing_link(data, size);
224   }
225 
226   fuzz_random_destroy();
227   return 0;
228 }
229