summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Johnston <matt@ucc.asn.au>2020-10-26 22:52:07 +0800
committerMatt Johnston <matt@ucc.asn.au>2020-10-26 22:52:07 +0800
commita533f44e584fea1b2b5393ee7e02e306fb0b8c17 (patch)
tree50fed58e73ff45f59189d2d52355e9ee88ba605a
parent39e9a5ec5970bb85c6bfe1952eeaf0e6490e9df9 (diff)
downloaddropbear-a533f44e584fea1b2b5393ee7e02e306fb0b8c17.tar.gz
Fix fuzz-sshpacketmutator to work
-rw-r--r--Makefile.in5
-rw-r--r--buffer.c1
-rw-r--r--fuzz/fuzz-common.c6
-rw-r--r--fuzz/fuzz-sshpacketmutator.c89
-rw-r--r--fuzz/fuzzer-client_mutator.c2
5 files changed, 67 insertions, 36 deletions
diff --git a/Makefile.in b/Makefile.in
index 39feef9..2ee5e3d 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -273,7 +273,8 @@ FUZZ_TARGETS=fuzzer-preauth fuzzer-pubkey fuzzer-verify fuzzer-preauth_nomaths \
fuzzer-client_mutator
FUZZER_OPTIONS = $(addsuffix .options, $(FUZZ_TARGETS))
-FUZZ_OBJS = $(addprefix fuzz/,$(addsuffix .o,$(FUZZ_TARGETS)))
+FUZZ_OBJS = $(addprefix fuzz/,$(addsuffix .o,$(FUZZ_TARGETS))) \
+ fuzz/fuzz-sshpacketmutator.o
list-fuzz-targets:
@echo $(FUZZ_TARGETS)
@@ -292,6 +293,8 @@ fuzz-targets: $(FUZZ_TARGETS) $(FUZZER_OPTIONS)
$(FUZZ_TARGETS): $(FUZZ_OBJS) $(allobjs) $(LIBTOM_DEPS)
$(CXX) $(CXXFLAGS) fuzz/$@.o $(LDFLAGS) $(allobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) -lcrypt
+fuzzer-client_mutator: allobjs += fuzz/fuzz-sshpacketmutator.o
+
fuzzer-%.options: Makefile
echo "[libfuzzer]" > $@
echo "max_len = 50000" >> $@
diff --git a/buffer.c b/buffer.c
index fee41d6..1397519 100644
--- a/buffer.c
+++ b/buffer.c
@@ -188,6 +188,7 @@ unsigned char* buf_getptr(const buffer* buf, unsigned int len) {
unsigned char* buf_getwriteptr(const buffer* buf, unsigned int len) {
if (len > BUF_MAX_INCR || buf->pos + len > buf->size) {
+ abort();
dropbear_exit("Bad buf_getwriteptr");
}
return &buf->data[buf->pos];
diff --git a/fuzz/fuzz-common.c b/fuzz/fuzz-common.c
index 8dddacb..82a2d5d 100644
--- a/fuzz/fuzz-common.c
+++ b/fuzz/fuzz-common.c
@@ -45,9 +45,9 @@ void fuzz_common_setup(void) {
else
#endif
{
- fprintf(stderr, "Dropbear fuzzer: Disabling stderr output\n");
- fuzz.stderr = fopen("/dev/null", "w");
- assert(fuzz.stderr);
+ // fprintf(stderr, "Dropbear fuzzer: Disabling stderr output\n");
+ // fuzz.stderr = fopen("/dev/null", "w");
+ // assert(fuzz.stderr);
}
}
diff --git a/fuzz/fuzz-sshpacketmutator.c b/fuzz/fuzz-sshpacketmutator.c
index fa0ed5f..d7e554c 100644
--- a/fuzz/fuzz-sshpacketmutator.c
+++ b/fuzz/fuzz-sshpacketmutator.c
@@ -1,4 +1,5 @@
#include "fuzz.h"
+#include "dbutil.h"
size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize);
@@ -11,7 +12,7 @@ static void fuzz_get_packets(buffer *inp, buffer **out_packets, unsigned int *nu
buf_incrpos(inp, version - inp->data);
unsigned char* newline = memchr(&inp->data[inp->pos], '\n', inp->len - inp->pos);
if (newline) {
- buf_incrpos(inp, newline - &inp->data[inp->pos]);
+ buf_incrpos(inp, newline - &inp->data[inp->pos]+1);
} else {
/* Give up on any version string */
buf_setpos(inp, 0);
@@ -32,8 +33,11 @@ static void fuzz_get_packets(buffer *inp, buffer **out_packets, unsigned int *nu
}
/* Read packet */
+ //printf("at %d\n", inp->pos);
+ //printhex("lenget", buf_getptr(inp, 48), 48);
unsigned int packet_len = buf_getint(inp);
- if (packet_len <= RECV_MAX_PACKET_LEN) {
+ // printf("len %u\n", packet_len);
+ if (packet_len > RECV_MAX_PACKET_LEN-4) {
/* Bad length, try skipping a single byte */
buf_decrpos(inp, 3);
continue;
@@ -45,11 +49,11 @@ static void fuzz_get_packets(buffer *inp, buffer **out_packets, unsigned int *nu
buf_putint(new_packet, packet_len);
buf_putbytes(new_packet, buf_getptr(inp, packet_len), packet_len);
buf_incrpos(inp, packet_len);
+ // printf("incr pos %d to %d\n", packet_len, inp->pos);
out_packets[*num_out_packets] = new_packet;
(*num_out_packets)++;
}
-
}
/* Mutate in-place */
@@ -76,22 +80,51 @@ static const size_t MAX_OUT_SIZE = 50000;
size_t LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size,
size_t MaxSize, unsigned int Seed) {
- int i;
+
+ /* Avoid some allocations */
+ /* XXX perhaps this complication isn't worthwhile */
+ static buffer buf_oup, buf_alloc_packetA, buf_alloc_packetB;
+ static buffer *oup = &buf_oup;
+ static buffer *alloc_packetA = &buf_alloc_packetA;
+ static buffer *alloc_packetB = &buf_alloc_packetB;
+ static int once = 1;
+ if (once) {
+ once = 0;
+ // malloc doesn't get intercepted by epoch deallocator
+ oup->size = MAX_OUT_SIZE;
+ alloc_packetA->size = RECV_MAX_PACKET_LEN;
+ alloc_packetB->size = RECV_MAX_PACKET_LEN;
+ oup->data = malloc(oup->size);
+ alloc_packetA->data = malloc(alloc_packetA->size);
+ alloc_packetB->data = malloc(alloc_packetB->size);
+ }
+ alloc_packetA->pos = 0;
+ alloc_packetA->len = 0;
+ alloc_packetB->pos = 0;
+ alloc_packetB->len = 0;
+ oup->pos = 0;
+ oup->len = 0;
+
+ unsigned int i;
unsigned short randstate[3] = {0,0,0};
memcpy(randstate, &Seed, sizeof(Seed));
+ // printhex("mutator input", Data, Size);
+ #if 0
/* 1% chance straight llvm mutate */
if (nrand48(randstate) % 100 == 0) {
return LLVMFuzzerMutate(Data, Size, MaxSize);
}
+ #endif
buffer inp_buf = {.data = Data, .size = Size, .len = Size, .pos = 0};
buffer *inp = &inp_buf;
/* Parse packets */
- buffer* packets[MAX_FUZZ_PACKETS] = {0};
+ buffer* packets[MAX_FUZZ_PACKETS];
unsigned int num_packets = MAX_FUZZ_PACKETS;
fuzz_get_packets(inp, packets, &num_packets);
+ // printf("%d packets\n", num_packets);
if (num_packets == 0) {
// gotta do something
@@ -100,7 +133,6 @@ size_t LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size,
}
/* Start output */
- buffer *oup = buf_new(MAX_OUT_SIZE);
/* Put a new banner to output */
buf_putbytes(oup, FIXED_VERSION, strlen(FIXED_VERSION));
@@ -108,42 +140,46 @@ size_t LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size,
for (i = 0; i < num_packets+1; i++) {
// These are pointers to output
buffer *out_packetA = NULL, *out_packetB = NULL;
- // These need to be freed
- buffer *alloc_packetA = NULL, *alloc_packetB = NULL;
+ alloc_packetA->pos = 0;
+ alloc_packetA->len = 0;
+ alloc_packetB->pos = 0;
+ alloc_packetB->len = 0;
/* 5% chance each */
const int optA = nrand48(randstate) % 20;
- const int other = nrand48(randstate) % num_packets;
if (optA == 0) {
/* Copy another */
- out_packetA = packets[nrand48(randstate) % num_packets];
+ unsigned int other = nrand48(randstate) % num_packets;
+ out_packetA = packets[other];
+ // printf("%d copy another %d\n", i, other);
}
if (optA == 1) {
/* Mutate another */
- alloc_packetA = buf_new(RECV_MAX_PACKET_LEN);
- buffer *from = packets[nrand48(randstate) % num_packets];
+ unsigned int other = nrand48(randstate) % num_packets;
+ buffer *from = packets[other];
buf_putbytes(alloc_packetA, from->data, from->len);
out_packetA = alloc_packetA;
buf_llvm_mutate(out_packetA);
+ // printf("%d mutate another %d\n", i, other);
}
- /* 10% chance each of mutate or drop */
if (i < num_packets) {
int optB = nrand48(randstate) % 10;
- if (optB == 0) {
- /* Copy as-is */
- out_packetB = packets[i];
- }
if (optB == 1) {
+ /* 10% chance of drop */
/* Drop it */
- }
- if (optB == 2) {
- /* Mutate it */
- alloc_packetB = buf_new(RECV_MAX_PACKET_LEN);
+ // printf("%d drop\n", i);
+ } else if (optB <= 6) {
+ /* Mutate it, 50% chance */
+ // printf("%d mutate\n", i);
buffer *from = packets[nrand48(randstate) % num_packets];
buf_putbytes(alloc_packetB, from->data, from->len);
out_packetB = alloc_packetB;
buf_llvm_mutate(out_packetB);
+ } else {
+ /* Copy as-is */
+ out_packetB = packets[i];
+ // printf("%d as-is\n", i);
}
}
@@ -153,14 +189,6 @@ size_t LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size,
if (out_packetB && oup->len + out_packetB->len <= oup->size) {
buf_putbytes(oup, out_packetB->data, out_packetB->len);
}
- if (alloc_packetA) {
- buf_free(alloc_packetA);
- alloc_packetA = NULL;
- }
- if (alloc_packetB) {
- buf_free(alloc_packetB);
- alloc_packetB = NULL;
- }
}
for (i = 0; i < num_packets; i++) {
@@ -169,7 +197,8 @@ size_t LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size,
size_t ret_len = MIN(MaxSize, oup->len);
memcpy(Data, oup->data, ret_len);
- buf_free(oup);
+ // printhex("mutator done", Data, ret_len);
return ret_len;
}
+
diff --git a/fuzz/fuzzer-client_mutator.c b/fuzz/fuzzer-client_mutator.c
index df57314..eb59f46 100644
--- a/fuzz/fuzzer-client_mutator.c
+++ b/fuzz/fuzzer-client_mutator.c
@@ -1,7 +1,5 @@
#include "fuzz.h"
-#include "fuzz-sshpacketmutator.c"
-
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
return fuzz_run_client(Data, Size, 0);
}