mirror of https://github.com/google/oss-fuzz.git
openvpn: three new fuzzers and improved proxy fuzzer (#5979)
* add list fuzzer * add header file inclusion order. * added an mroute fuzzer. * add packet id fuzzer. * refactor list, mroute and packet_id fuzzers. * set it up so fgets always returns a string with an ASCII char. * refactor build script. * hook fopen and fclose in builtin_console.
This commit is contained in:
parent
51a97a0c41
commit
1c54b327c8
|
@ -28,6 +28,9 @@ sed -i 's/select(/fuzz_select(/g' ./src/openvpn/proxy.c
|
|||
sed -i 's/send(/fuzz_send(/g' ./src/openvpn/proxy.c
|
||||
sed -i 's/recv(/fuzz_recv(/g' ./src/openvpn/proxy.c
|
||||
|
||||
sed -i 's/fopen/fuzz_fopen/g' ./src/openvpn/console_builtin.c
|
||||
sed -i 's/fclose/fuzz_fclose/g' ./src/openvpn/console_builtin.c
|
||||
|
||||
sed -i 's/fp = (flags/fp = stdout;\n\/\//g' ./src/openvpn/error.c
|
||||
|
||||
# Build openvpn
|
||||
|
@ -44,13 +47,13 @@ ar r libopenvpn.a *.o
|
|||
$CXX $CXXFLAGS -g -c $SRC/fuzz_randomizer.cpp -o $SRC/fuzz_randomizer.o
|
||||
|
||||
# Compile the fuzzers
|
||||
for fuzzname in fuzz_dhcp fuzz_misc fuzz_base64 fuzz_proxy fuzz_buffer fuzz_route; do
|
||||
for fuzzname in fuzz_dhcp fuzz_misc fuzz_base64 fuzz_proxy fuzz_buffer fuzz_route fuzz_packet_id fuzz_mroute fuzz_list; do
|
||||
$CC -DHAVE_CONFIG_H -I. -I../.. -I../../include -I../../include -I../../src/compat \
|
||||
-DPLUGIN_LIBDIR=\"/usr/local/lib/openvpn/plugins\" -Wall -std=c99 $CFLAGS \
|
||||
-c $SRC/${fuzzname}.c -o ${fuzzname}.o
|
||||
-c $SRC/${fuzzname}.c -o $SRC/${fuzzname}.o
|
||||
|
||||
# Link with CXX
|
||||
$CXX ${CXXFLAGS} ${LIB_FUZZING_ENGINE} ./${fuzzname}.o -o $OUT/${fuzzname} $SRC/fuzz_randomizer.o \
|
||||
$CXX ${CXXFLAGS} ${LIB_FUZZING_ENGINE} $SRC/${fuzzname}.o -o $OUT/${fuzzname} $SRC/fuzz_randomizer.o \
|
||||
libopenvpn.a ../../src/compat/.libs/libcompat.a /usr/lib/x86_64-linux-gnu/libnsl.a \
|
||||
/usr/lib/x86_64-linux-gnu/libresolv.a /usr/lib/x86_64-linux-gnu/liblzo2.a \
|
||||
-lssl -lcrypto -ldl
|
||||
|
|
|
@ -25,9 +25,14 @@ ssize_t fuzz_read(int sockfd, void *buf, size_t len){
|
|||
return fuzz_get_random_data(buf, len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
char *fuzz_fgets(char *s, int size, FILE *stream) {
|
||||
ssize_t v = fuzz_get_random_data(s, size-1);
|
||||
if (s[0] == '\0') {
|
||||
// We use fgets to get trusted input. As such, assume we have
|
||||
// an ascii printable char at the beginning.
|
||||
printf("Calling into fgets\n");
|
||||
if (s[0] <= 0x21 || s[0] >= 0x7f) {
|
||||
s[0] = 'A';
|
||||
}
|
||||
s[size-1] = '\0';
|
||||
|
@ -45,3 +50,14 @@ int fuzz_select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, s
|
|||
ssize_t fuzz_send(int sockfd, const void *buf, size_t len, int flags) {
|
||||
return len;
|
||||
}
|
||||
|
||||
FILE *fp_p = NULL;
|
||||
FILE *fuzz_fopen(const char *pathname, const char *mode) {
|
||||
if (mode == NULL) return fp_p;
|
||||
return fp_p;
|
||||
}
|
||||
|
||||
int fuzz_fclose(FILE *stream) {
|
||||
if (stream == NULL) return 1;
|
||||
return 2;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
/* Copyright 2021 Google LLC
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "syshead.h"
|
||||
#include "list.h"
|
||||
|
||||
#include "fuzz_randomizer.h"
|
||||
|
||||
#define KEY_SIZE 23
|
||||
|
||||
/* Required for hash_init() */
|
||||
static uint32_t word_hash_function(const void *key, uint32_t iv) {
|
||||
return hash_func(key, KEY_SIZE, iv);
|
||||
}
|
||||
|
||||
/* Required for hash_init() */
|
||||
static bool word_compare_function(const void *key1, const void *key2) {
|
||||
return ((size_t)key1 & 0xFFF) == ((size_t)key1 & 0xFFF);
|
||||
}
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||
struct gc_arena gc;
|
||||
struct hash *hash = NULL;
|
||||
ssize_t generic_ssizet, generic_ssizet2, num_loops;
|
||||
|
||||
fuzz_random_init(data, size);
|
||||
|
||||
gc = gc_new();
|
||||
|
||||
int total_to_fuzz = fuzz_randomizer_get_int(1, 20);
|
||||
for (int i = 0; i < total_to_fuzz; i++) {
|
||||
generic_ssizet = fuzz_randomizer_get_int(0, 8);
|
||||
|
||||
switch (generic_ssizet) {
|
||||
case 0:
|
||||
if (hash == NULL) {
|
||||
int n_buckets = fuzz_randomizer_get_int(1, 1000);
|
||||
uint32_t iv;
|
||||
|
||||
hash =
|
||||
hash_init(n_buckets, iv, word_hash_function, word_compare_function);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (hash) {
|
||||
hash_free(hash);
|
||||
hash = NULL;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (hash) {
|
||||
struct hash_iterator hi;
|
||||
struct hash_element *he;
|
||||
hash_iterator_init(hash, &hi);
|
||||
while ((he = hash_iterator_next(&hi))) {
|
||||
void *w = he->value;
|
||||
}
|
||||
hash_iterator_free(&hi);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (hash) {
|
||||
void *key;
|
||||
void *value;
|
||||
char arr[KEY_SIZE];
|
||||
memset(arr, 0, KEY_SIZE);
|
||||
fuzz_get_random_data(arr, KEY_SIZE);
|
||||
key = (void *)arr;
|
||||
if (!hash_lookup(hash, key)) {
|
||||
generic_ssizet = fuzz_randomizer_get_int(0, 0xfffffff);
|
||||
value = (void *)generic_ssizet;
|
||||
hash_add(hash, key, value, false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (hash) {
|
||||
hash_n_elements(hash);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
if (hash) {
|
||||
hash_n_buckets(hash);
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
if (hash) {
|
||||
uint32_t hv;
|
||||
generic_ssizet = fuzz_randomizer_get_int(0, 0xfffffff);
|
||||
hv = generic_ssizet;
|
||||
hash_bucket(hash, hv);
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
if (hash) {
|
||||
void *key;
|
||||
char arr[KEY_SIZE];
|
||||
memset(arr, 0, KEY_SIZE);
|
||||
fuzz_get_random_data(arr, KEY_SIZE);
|
||||
key = (void *)arr;
|
||||
hash_remove(hash, key);
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
if (hash) {
|
||||
void *value;
|
||||
generic_ssizet = fuzz_randomizer_get_int(0, 0xfffffff);
|
||||
value = (void *)generic_ssizet;
|
||||
hash_remove_by_value(hash, value);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hash) {
|
||||
hash_free(hash);
|
||||
}
|
||||
|
||||
gc_free(&gc);
|
||||
|
||||
fuzz_random_destroy();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/* Copyright 2021 Google LLC
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "syshead.h"
|
||||
#include "init.h"
|
||||
#include "mroute.h"
|
||||
|
||||
#include "fuzz_randomizer.h"
|
||||
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||
|
||||
fuzz_random_init(data, size);
|
||||
struct buffer buf;
|
||||
struct gc_arena gc;
|
||||
|
||||
gc = gc_new();
|
||||
|
||||
char *tmp = get_random_string();
|
||||
buf = string_alloc_buf(tmp, &gc);
|
||||
free(tmp);
|
||||
|
||||
struct mroute_addr src_addr;
|
||||
struct mroute_addr dst_addr;
|
||||
mroute_addr_init(&src_addr);
|
||||
mroute_addr_init(&dst_addr);
|
||||
unsigned int ret = mroute_extract_addr_ip(&src_addr, &dst_addr, &buf);
|
||||
|
||||
if (ret & MROUTE_EXTRACT_SUCCEEDED) {
|
||||
mroute_addr_mask_host_bits(&src_addr);
|
||||
mroute_addr_print(&src_addr, &gc);
|
||||
mroute_learnable_address(&src_addr, &gc);
|
||||
}
|
||||
|
||||
uint16_t vid;
|
||||
struct mroute_addr a1, a2, a3, a4;
|
||||
mroute_addr_init(&a1);
|
||||
mroute_addr_init(&a2);
|
||||
mroute_addr_init(&a3);
|
||||
mroute_addr_init(&a4);
|
||||
mroute_extract_addr_ether(&a1, &a2, &a3, &a3, vid, &buf);
|
||||
|
||||
if (size > sizeof(struct openvpn_sockaddr)) {
|
||||
struct openvpn_sockaddr local_sock;
|
||||
memcpy(&local_sock, data, sizeof(struct openvpn_sockaddr));
|
||||
mroute_extract_openvpn_sockaddr(&a1, &local_sock, true);
|
||||
mroute_extract_openvpn_sockaddr(&a1, &local_sock, false);
|
||||
}
|
||||
|
||||
struct mroute_helper *mhelper = NULL;
|
||||
mhelper = mroute_helper_init(fuzz_randomizer_get_int(0, 0xfffffff));
|
||||
if (mhelper != NULL) {
|
||||
mroute_helper_add_iroute46(mhelper, fuzz_randomizer_get_int(0, MR_HELPER_NET_LEN-1));
|
||||
mroute_helper_free(mhelper);
|
||||
}
|
||||
|
||||
gc_free(&gc);
|
||||
|
||||
fuzz_random_destroy();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/* Copyright 2021 Google LLC
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "syshead.h"
|
||||
#include "init.h"
|
||||
#include "packet_id.h"
|
||||
|
||||
#include "fuzz_randomizer.h"
|
||||
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||
fuzz_random_init(data, size);
|
||||
|
||||
struct packet_id pid;
|
||||
struct packet_id_net pin;
|
||||
const int seq_backtrack = 10;
|
||||
const int time_backtrack = 10;
|
||||
|
||||
packet_id_init(&pid, seq_backtrack, time_backtrack, "name", 0);
|
||||
|
||||
int total_sends = fuzz_randomizer_get_int(0, 10);
|
||||
for (int i = 0; i < total_sends; i++) {
|
||||
update_time();
|
||||
pin.time = fuzz_randomizer_get_int(0, 0xfffffff);
|
||||
pin.id = fuzz_randomizer_get_int(0, 0xfffffff);
|
||||
|
||||
packet_id_reap_test(&pid.rec);
|
||||
bool test = packet_id_test(&pid.rec, &pin);
|
||||
if (test) {
|
||||
packet_id_add(&pid.rec, &pin);
|
||||
}
|
||||
}
|
||||
packet_id_free(&pid);
|
||||
|
||||
struct gc_arena gc;
|
||||
gc = gc_new();
|
||||
struct buffer buf;
|
||||
char *tmp = get_random_string();
|
||||
buf = string_alloc_buf(tmp, &gc);
|
||||
free(tmp);
|
||||
packet_id_read(&pid, &buf, false);
|
||||
packet_id_read(&pid, &buf, true);
|
||||
gc_free(&gc);
|
||||
|
||||
char filename[256];
|
||||
sprintf(filename, "/tmp/libfuzzer.%d", getpid());
|
||||
|
||||
FILE *fp = fopen(filename, "wb");
|
||||
if (!fp) {
|
||||
return 0;
|
||||
}
|
||||
fwrite(data, size, 1, fp);
|
||||
fclose(fp);
|
||||
|
||||
struct packet_id_persist p;
|
||||
memset(&p, 0, sizeof(struct packet_id_persist));
|
||||
packet_id_persist_init(&p);
|
||||
packet_id_persist_load(&p, filename);
|
||||
gc = gc_new();
|
||||
packet_id_persist_print(&p, &gc);
|
||||
gc_free(&gc);
|
||||
packet_id_persist_close(&p);
|
||||
|
||||
fuzz_random_destroy();
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue