Skip to content

Commit

Permalink
Sync master with fuzzing branch (#551)
Browse files Browse the repository at this point in the history
  • Loading branch information
weinrank authored Nov 19, 2020
1 parent b973bdb commit a171095
Show file tree
Hide file tree
Showing 11 changed files with 82 additions and 48 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -253,9 +253,9 @@ elseif (CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID MATCHES "Appl
endif ()

if (sctp_build_fuzzer)
set(CMAKE_BUILD_TYPE "DEBUG")
set(CMAKE_BUILD_TYPE "RelWithDebInfo")
add_definitions(-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O1 -fsanitize=fuzzer-no-link")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=fuzzer-no-link")
endif ()
endif ()

Expand Down
6 changes: 5 additions & 1 deletion fuzzer/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright (C) 2015-2019 Felix Weinrank
# Copyright (C) 2015-2020 Felix Weinrank
#
# All rights reserved.
#
Expand Down Expand Up @@ -79,6 +79,10 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=fuzzer")
add_executable(fuzzer_listen fuzzer_listen.c ../programs/programs_helper.c)
target_link_libraries(fuzzer_listen usrsctp)

add_executable(fuzzer_listen_verbose fuzzer_listen.c ../programs/programs_helper.c)
target_compile_definitions(fuzzer_listen_verbose PRIVATE FUZZ_VERBOSE)
target_link_libraries(fuzzer_listen_verbose usrsctp)

add_executable(fuzzer_fragment fuzzer_fragment.c ../programs/programs_helper.c)
target_link_libraries(fuzzer_fragment usrsctp)

Expand Down
Binary file not shown.
2 changes: 1 addition & 1 deletion fuzzer/build-fuzzer.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ NPROC=1
# OS detection
if [ "$(uname)" = "Linux" ]; then
NPROC=$(nproc)
CC=clang-10
CC=clang-12
elif [ "$(uname)" = "Darwin" ]; then
NPROC=$(sysctl -n hw.ncpu)
CC=clang
Expand Down
4 changes: 3 additions & 1 deletion fuzzer/check-input.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ echo "########## Beginning Fuzzer Chain"
echo ""

set +e
./fuzzer_connect_multi_verbose -timeout=10 $1 > $1.log 2>&1
./fuzzer_listen_verbose -timeout=10 $1 > $1.log 2>&1
#./fuzzer_connect_multi_verbose -timeout=10 $1 > $1.log 2>&1
FUZZER_RETVAL=$?
set -e

Expand All @@ -28,6 +29,7 @@ if [ "$FUZZER_RETVAL" -eq "0" ]; then
echo -e "$C_RED"
echo "$1 - NOT REPRODUCABLE"
echo -e "$C_NOC"
exit $FUZZER_RETVAL
elif [ "$FUZZER_RETVAL" -eq "77" ]; then
echo -e "$C_GRN"
echo "$1 - REPRODUCABLE"
Expand Down
31 changes: 16 additions & 15 deletions fuzzer/fuzzer_connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ static uint32_t assoc_vtag = 0;
#endif

static void
dump_packet(const void *buffer, size_t bufferlen, int inout) {
dump_packet(const void *buffer, size_t bufferlen, int inout)
{
#ifdef FUZZ_VERBOSE
static char *dump_buf;
if ((dump_buf = usrsctp_dumppacket(buffer, bufferlen, inout)) != NULL) {
Expand Down Expand Up @@ -275,41 +276,41 @@ LLVMFuzzerTestOneInput(const uint8_t* data, size_t data_size)
}

socket_client = usrsctp_socket(AF_CONN, SOCK_STREAM, IPPROTO_SCTP, NULL, NULL, 0, 0);
assert(socket_client != NULL);
FUZZER_ASSERT(socket_client != NULL);

usrsctp_set_non_blocking(socket_client, 1);

// all max!
memset(&initmsg, 1, sizeof(struct sctp_initmsg));
result = usrsctp_setsockopt(socket_client, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof(struct sctp_initmsg));
assert(result == 0);
FUZZER_ASSERT(result == 0);

so_linger.l_onoff = 1;
so_linger.l_linger = 0;
result = usrsctp_setsockopt(socket_client, SOL_SOCKET, SO_LINGER, &so_linger, sizeof(struct linger));
assert(result == 0);
FUZZER_ASSERT(result == 0);

memset(&event, 0, sizeof(event));
event.se_on = 1;
for (i = 0; i < (sizeof(event_types) / sizeof(uint16_t)); i++) {
event.se_type = event_types[i];
result = usrsctp_setsockopt(socket_client, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(event));
assert(result == 0);
FUZZER_ASSERT(result == 0);
}

optval = 1;
result = usrsctp_setsockopt(socket_client, IPPROTO_SCTP, SCTP_RECVRCVINFO, &optval, sizeof(optval));
assert(result == 0);
FUZZER_ASSERT(result == 0);

optval = 1;
result = usrsctp_setsockopt(socket_client, IPPROTO_SCTP, SCTP_RECVNXTINFO, &optval, sizeof(optval));
assert(result == 0);
FUZZER_ASSERT(result == 0);

#if defined(FUZZ_STREAM_RESET)
assoc_val.assoc_id = SCTP_ALL_ASSOC;
assoc_val.assoc_value = SCTP_ENABLE_RESET_STREAM_REQ | SCTP_ENABLE_RESET_ASSOC_REQ | SCTP_ENABLE_CHANGE_ASSOC_REQ;
result = usrsctp_setsockopt(socket_client, IPPROTO_SCTP, SCTP_ENABLE_STREAM_RESET, &assoc_val, sizeof(struct sctp_assoc_value));
assert(result == 0);
FUZZER_ASSERT(result == 0);
#endif // defined(FUZZ_STREAM_RESET)

#if defined(FUZZ_INTERLEAVING)
Expand All @@ -320,18 +321,18 @@ LLVMFuzzerTestOneInput(const uint8_t* data, size_t data_size)
if (data[0] & FUZZ_B_I_DATA_SUPPORT) {
optval = 2;
result = usrsctp_setsockopt(socket_client, IPPROTO_SCTP, SCTP_FRAGMENT_INTERLEAVE, &optval, sizeof(optval));
assert(result == 0);
FUZZER_ASSERT(result == 0);

memset(&assoc_val, 0, sizeof(assoc_val));
assoc_val.assoc_value = 1;
result = usrsctp_setsockopt(socket_client, IPPROTO_SCTP, SCTP_INTERLEAVING_SUPPORTED, &assoc_val, sizeof(assoc_val));
assert(result == 0);
FUZZER_ASSERT(result == 0);
}
#endif // defined(FUZZ_INTERLEAVING)

optval = 1;
result = usrsctp_setsockopt(socket_client, IPPROTO_SCTP, SCTP_REUSE_PORT, &optval, sizeof(optval));
assert(result == 0);
FUZZER_ASSERT(result == 0);

memset(&sconn, 0, sizeof(struct sockaddr_conn));
sconn.sconn_family = AF_CONN;
Expand All @@ -342,12 +343,12 @@ LLVMFuzzerTestOneInput(const uint8_t* data, size_t data_size)
sconn.sconn_addr = (void *)1;

result = usrsctp_bind(socket_client, (struct sockaddr *)&sconn, sizeof(struct sockaddr_conn));
assert(result == 0);
FUZZER_ASSERT(result == 0);

// Disable Nagle.
optval = 1;
result = usrsctp_setsockopt(socket_client, IPPROTO_SCTP, SCTP_NODELAY, &optval, sizeof(optval));
assert(result == 0);
FUZZER_ASSERT(result == 0);

usrsctp_set_upcall(socket_client, handle_upcall, NULL);

Expand All @@ -361,7 +362,7 @@ LLVMFuzzerTestOneInput(const uint8_t* data, size_t data_size)

fuzzer_printf("Calling usrsctp_connect()\n");
result = usrsctp_connect(socket_client, (struct sockaddr *)&sconn, sizeof(struct sockaddr_conn));
assert(result == 0 || errno == EINPROGRESS);
FUZZER_ASSERT(result == 0 || errno == EINPROGRESS);

if (data[0] & FUZZ_B_INJECT_INIT_ACK) {
fuzzer_printf("Injecting INIT-ACK\n");
Expand Down Expand Up @@ -401,7 +402,7 @@ LLVMFuzzerTestOneInput(const uint8_t* data, size_t data_size)
memset(&srs, 0, sizeof(struct sctp_reset_streams));
srs.srs_flags = SCTP_STREAM_RESET_INCOMING | SCTP_STREAM_RESET_OUTGOING;
result = usrsctp_setsockopt(socket_client, IPPROTO_SCTP, SCTP_RESET_STREAMS, &srs, sizeof(struct sctp_reset_streams));
assert(result == 0);
FUZZER_ASSERT(result == 0);
}

// Required: INIT-ACK and COOKIE-ACK
Expand Down
33 changes: 16 additions & 17 deletions fuzzer/fuzzer_fragment.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,14 @@
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <assert.h>
#include <usrsctp.h>
#include "../programs/programs_helper.h"
#define FUZZ_B_RESERVED1 (1 << 0)
#define FUZZ_B_RESERVED2 (1 << 1)
#define FUZZ_B_RESERVED3 (1 << 2)
#define FUZZ_B_RESERVED4 (1 << 3)
#define FUZZ_B_RESERVED4 (1 << 3)
#define NR_SACK_FLAG (1 << 4)
#define FUZZ_B_RESERVED5 (1 << 5)
#define FUZZ_B_RESERVED5 (1 << 5)
#define I_DATA_FLAG (1 << 6)
#define FUZZ_B_RESERVED6 (1 << 7)

Expand Down Expand Up @@ -140,7 +139,7 @@ LLVMFuzzerTestOneInput(const uint8_t* data, size_t data_size)
int optval;
unsigned long i;
char* send_data_buffer;
uint16_t event_types[] = {
uint16_t event_types[] = {
SCTP_ASSOC_CHANGE,
SCTP_PEER_ADDR_CHANGE,
SCTP_REMOTE_ERROR,
Expand Down Expand Up @@ -226,18 +225,18 @@ LLVMFuzzerTestOneInput(const uint8_t* data, size_t data_size)
}

socket_client = usrsctp_socket(AF_CONN, SOCK_STREAM, IPPROTO_SCTP, NULL, NULL, 0, 0);
assert(socket_client != NULL);
FUZZER_ASSERT(socket_client != NULL);

usrsctp_set_non_blocking(socket_client, 1);

memset(&initmsg, 1, sizeof(struct sctp_initmsg));
result = usrsctp_setsockopt(socket_client, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof(struct sctp_initmsg));
assert(result == 0);
FUZZER_ASSERT(result == 0);

so_linger.l_onoff = 1;
so_linger.l_linger = 0;
result = usrsctp_setsockopt(socket_client, SOL_SOCKET, SO_LINGER, &so_linger, sizeof(struct linger));
assert(result == 0);
FUZZER_ASSERT(result == 0);

memset(&event, 0, sizeof(event));
event.se_on = 1;
Expand All @@ -248,27 +247,27 @@ LLVMFuzzerTestOneInput(const uint8_t* data, size_t data_size)

optval = 1;
result = usrsctp_setsockopt(socket_client, IPPROTO_SCTP, SCTP_RECVRCVINFO, &optval, sizeof(optval));
assert(result == 0);
FUZZER_ASSERT(result == 0);

optval = 1;
result = usrsctp_setsockopt(socket_client, IPPROTO_SCTP, SCTP_RECVNXTINFO, &optval, sizeof(optval));
assert(result == 0);
FUZZER_ASSERT(result == 0);

if (data[0] & I_DATA_FLAG) {
// set the program supporting I-DATA
optval = 2;
result = usrsctp_setsockopt(socket_client, IPPROTO_SCTP, SCTP_FRAGMENT_INTERLEAVE, &optval, sizeof(optval));
assert(result == 0);
FUZZER_ASSERT(result == 0);

memset(&assoc_val, 0, sizeof(assoc_val));
assoc_val.assoc_value = 1;
result = usrsctp_setsockopt(socket_client, IPPROTO_SCTP, SCTP_INTERLEAVING_SUPPORTED, &assoc_val, sizeof(assoc_val));
assert(result == 0);
FUZZER_ASSERT(result == 0);
}

optval = 1;
result = usrsctp_setsockopt(socket_client, IPPROTO_SCTP, SCTP_REUSE_PORT, &optval, sizeof(optval));
assert(result == 0);
FUZZER_ASSERT(result == 0);

memset(&sconn, 0, sizeof(struct sockaddr_conn));
sconn.sconn_family = AF_CONN;
Expand All @@ -279,11 +278,11 @@ LLVMFuzzerTestOneInput(const uint8_t* data, size_t data_size)
sconn.sconn_addr = (void *)1;

result = usrsctp_bind(socket_client, (struct sockaddr *)&sconn, sizeof(struct sockaddr_conn));
assert(result == 0);
FUZZER_ASSERT(result == 0);

optval = 1;
result = usrsctp_setsockopt(socket_client, IPPROTO_SCTP, SCTP_NODELAY, &optval, sizeof(optval));
assert(result == 0);
FUZZER_ASSERT(result == 0);

usrsctp_set_upcall(socket_client, handle_upcall, NULL);

Expand All @@ -296,7 +295,7 @@ LLVMFuzzerTestOneInput(const uint8_t* data, size_t data_size)
sconn.sconn_addr = (void *)1;

result = usrsctp_connect(socket_client, (struct sockaddr *)&sconn, sizeof(struct sockaddr_conn));
assert(result == 0 || errno == EINPROGRESS);
FUZZER_ASSERT(result == 0 || errno == EINPROGRESS);

if (data[0] & NR_SACK_FLAG) {
common_header = (struct sctp_common_header*) fuzz_init_ack_nrsack_support;
Expand Down Expand Up @@ -324,8 +323,8 @@ LLVMFuzzerTestOneInput(const uint8_t* data, size_t data_size)
}
if (data[fuzz_data_count] & NR_SACK_FLAG) {
send_data_buffer = malloc(SEND_DATA_SIZE);
assert( send_data_buffer != NULL );
memset(send_data_buffer,1,SEND_DATA_SIZE);
FUZZER_ASSERT(send_data_buffer != NULL );
memset(send_data_buffer, 1, SEND_DATA_SIZE);
fuzzer_printf("Calling usrsctp_sendv()\n");
usrsctp_sendv(socket_client, send_data_buffer, SEND_DATA_SIZE, NULL, 0, NULL, 0, SCTP_SENDV_NOINFO, 0);
free(send_data_buffer);
Expand Down
41 changes: 33 additions & 8 deletions fuzzer/fuzzer_listen.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2017-2019 Felix Weinrank
* Copyright (C) 2017-2020 Felix Weinrank
*
* All rights reserved.
*
Expand Down Expand Up @@ -45,24 +45,39 @@
struct sockaddr_conn sconn;
struct socket *s_l;

static int
conn_output(void *addr, void *buf, size_t length, uint8_t tos, uint8_t set_df)
static void
dump_packet(const void *buffer, size_t bufferlen, int inout)
{
#if 0
#ifdef FUZZ_VERBOSE
char *dump_buf;
if ((dump_buf = usrsctp_dumppacket(buf, length, SCTP_DUMP_OUTBOUND)) != NULL) {

if ((dump_buf = usrsctp_dumppacket(buffer, bufferlen, inout)) != NULL) {
fprintf(stderr, "%s", dump_buf);
usrsctp_freedumpbuffer(dump_buf);
}
#endif
#endif // FUZZ_VERBOSE
}

static int
conn_output(void *addr, void *buf, size_t length, uint8_t tos, uint8_t set_df)
{
dump_packet(buf, length, SCTP_DUMP_OUTBOUND);
return (0);
}

static void
handle_upcall(struct socket *sock, void *arg, int flgs)
{
fuzzer_printf("Listening socket established, implement logic!\n");
exit(EXIT_FAILURE);
struct socket *conn_sock;
struct sockaddr_in remote_addr;
socklen_t addr_len = sizeof(struct sockaddr_in);

memset(&remote_addr, 0, sizeof(struct sockaddr_in));
if (((conn_sock = usrsctp_accept(sock, (struct sockaddr *) &remote_addr, &addr_len)) == NULL) && (errno != EINPROGRESS)) {
perror("usrsctp_accept");
}

usrsctp_close(conn_sock);
}

int
Expand All @@ -78,6 +93,8 @@ init_fuzzer(void) {
SCTP_ADAPTATION_INDICATION,
SCTP_PARTIAL_DELIVERY_EVENT};
unsigned long i;
struct linger so_linger;
int result;

#if defined(FUZZ_FAST)
if (initialized) {
Expand Down Expand Up @@ -134,6 +151,11 @@ init_fuzzer(void) {
exit(EXIT_FAILURE);
}

so_linger.l_onoff = 1;
so_linger.l_linger = 0;
result = usrsctp_setsockopt(s_l, SOL_SOCKET, SO_LINGER, &so_linger, sizeof(struct linger));
FUZZER_ASSERT(result == 0);

usrsctp_set_upcall(s_l, handle_upcall, NULL);

initialized = 1;
Expand All @@ -150,6 +172,9 @@ LLVMFuzzerTestOneInput(const uint8_t* data, size_t data_size)
// Skip too small and too large packets
return (0);
}

dump_packet(data, data_size, SCTP_DUMP_INBOUND);

usrsctp_conninput((void *)1, data, data_size, 0);

#if !defined(FUZZ_FAST)
Expand Down
2 changes: 1 addition & 1 deletion fuzzer/fuzzer_listen.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
export ASAN_OPTIONS=abort_on_error=1:disable_core=0:unmap_shadow_on_exit=1:disable_coredump=0
ulimit -c unlimited
mkdir -p CORPUS_LISTEN
./fuzzer_listen -jobs=32 -timeout=10 -max_len=4086 CORPUS_LISTEN
./fuzzer_listen -jobs=36 -timeout=10 -max_len=4086 CORPUS_LISTEN
5 changes: 4 additions & 1 deletion programs/programs_helper.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*-
* Copyright (c) 2019 Felix Weinrank
* Copyright (c) 2020 Felix Weinrank
*
* All rights reserved.
*
Expand Down Expand Up @@ -84,4 +84,7 @@ debug_printf_stack(const char *format, ...);
void
debug_set_target(FILE *fp);

#define FUZZER_ASSERT(x) if (!(x)) { printf("USRSCTP assertion failed: function %s, file %s, line %d.\n", __PRETTY_FUNCTION__, __FILE__, __LINE__); abort(); }


#endif /* __PROGRAMS_HELPER_H__ */
Loading

0 comments on commit a171095

Please sign in to comment.