Mercurial > dropbear
annotate fuzz/fuzz-sshpacketmutator.c @ 1766:b14e0a19bcbe
crossover works
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Mon, 26 Oct 2020 23:06:41 +0800 |
parents | b688c884dad7 |
children | 3e1e1f82eba6 |
rev | line source |
---|---|
1760
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1 #include "fuzz.h" |
1765
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
2 #include "dbutil.h" |
1760
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
3 |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
4 size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize); |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
5 |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
6 static void fuzz_get_packets(buffer *inp, buffer **out_packets, unsigned int *num_out_packets) { |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
7 /* Skip any existing banner. Format is |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
8 SSH-protoversion-softwareversion SP comments CR LF |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
9 so we look for SSH-2. then a subsequent LF */ |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
10 unsigned char* version = memmem(inp->data, inp->len, "SSH-2.", strlen("SSH-2.")); |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
11 if (version) { |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
12 buf_incrpos(inp, version - inp->data); |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
13 unsigned char* newline = memchr(&inp->data[inp->pos], '\n', inp->len - inp->pos); |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
14 if (newline) { |
1765
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
15 buf_incrpos(inp, newline - &inp->data[inp->pos]+1); |
1760
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
16 } else { |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
17 /* Give up on any version string */ |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
18 buf_setpos(inp, 0); |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
19 } |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
20 } |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
21 |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
22 const unsigned int max_out_packets = *num_out_packets; |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
23 *num_out_packets = 0; |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
24 while (1) { |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
25 if (inp->pos + 4 > inp->len) { |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
26 /* End of input */ |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
27 break; |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
28 } |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
29 |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
30 if (*num_out_packets >= max_out_packets) { |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
31 /* End of output */ |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
32 break; |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
33 } |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
34 |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
35 /* Read packet */ |
1765
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
36 //printf("at %d\n", inp->pos); |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
37 //printhex("lenget", buf_getptr(inp, 48), 48); |
1760
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
38 unsigned int packet_len = buf_getint(inp); |
1765
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
39 // printf("len %u\n", packet_len); |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
40 if (packet_len > RECV_MAX_PACKET_LEN-4) { |
1760
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
41 /* Bad length, try skipping a single byte */ |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
42 buf_decrpos(inp, 3); |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
43 continue; |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
44 } |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
45 packet_len = MIN(packet_len, inp->len - inp->pos); |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
46 |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
47 /* Copy to output buffer */ |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
48 buffer* new_packet = buf_new(RECV_MAX_PACKET_LEN); |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
49 buf_putint(new_packet, packet_len); |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
50 buf_putbytes(new_packet, buf_getptr(inp, packet_len), packet_len); |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
51 buf_incrpos(inp, packet_len); |
1765
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
52 // printf("incr pos %d to %d\n", packet_len, inp->pos); |
1760
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
53 |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
54 out_packets[*num_out_packets] = new_packet; |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
55 (*num_out_packets)++; |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
56 } |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
57 } |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
58 |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
59 /* Mutate in-place */ |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
60 void buf_llvm_mutate(buffer *buf) { |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
61 /* Position it after packet_length and padding_length */ |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
62 const unsigned int offset = 5; |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
63 if (buf->len < offset) { |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
64 return; |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
65 } |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
66 buf_setpos(buf, offset); |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
67 size_t max_size = buf->size - buf->pos; |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
68 size_t new_size = LLVMFuzzerMutate(buf_getwriteptr(buf, max_size), |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
69 buf->len - buf->pos, max_size); |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
70 buf_setpos(buf, 0); |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
71 buf_putint(buf, new_size); |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
72 buf_setlen(buf, offset + new_size); |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
73 } |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
74 |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
75 |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
76 static const char* FIXED_VERSION = "SSH-2.0-dbfuzz\r\n"; |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
77 static const size_t MAX_FUZZ_PACKETS = 500; |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
78 /* XXX This might need tuning */ |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
79 static const size_t MAX_OUT_SIZE = 50000; |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
80 |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
81 size_t LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size, |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
82 size_t MaxSize, unsigned int Seed) { |
1765
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
83 |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
84 /* Avoid some allocations */ |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
85 /* XXX perhaps this complication isn't worthwhile */ |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
86 static buffer buf_oup, buf_alloc_packetA, buf_alloc_packetB; |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
87 static buffer *oup = &buf_oup; |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
88 static buffer *alloc_packetA = &buf_alloc_packetA; |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
89 static buffer *alloc_packetB = &buf_alloc_packetB; |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
90 static int once = 1; |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
91 if (once) { |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
92 once = 0; |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
93 // malloc doesn't get intercepted by epoch deallocator |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
94 oup->size = MAX_OUT_SIZE; |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
95 alloc_packetA->size = RECV_MAX_PACKET_LEN; |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
96 alloc_packetB->size = RECV_MAX_PACKET_LEN; |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
97 oup->data = malloc(oup->size); |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
98 alloc_packetA->data = malloc(alloc_packetA->size); |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
99 alloc_packetB->data = malloc(alloc_packetB->size); |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
100 } |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
101 alloc_packetA->pos = 0; |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
102 alloc_packetA->len = 0; |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
103 alloc_packetB->pos = 0; |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
104 alloc_packetB->len = 0; |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
105 oup->pos = 0; |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
106 oup->len = 0; |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
107 |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
108 unsigned int i; |
1760
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
109 unsigned short randstate[3] = {0,0,0}; |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
110 memcpy(randstate, &Seed, sizeof(Seed)); |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
111 |
1765
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
112 // printhex("mutator input", Data, Size); |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
113 #if 0 |
1760
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
114 /* 1% chance straight llvm mutate */ |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
115 if (nrand48(randstate) % 100 == 0) { |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
116 return LLVMFuzzerMutate(Data, Size, MaxSize); |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
117 } |
1765
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
118 #endif |
1760
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
119 |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
120 buffer inp_buf = {.data = Data, .size = Size, .len = Size, .pos = 0}; |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
121 buffer *inp = &inp_buf; |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
122 |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
123 /* Parse packets */ |
1765
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
124 buffer* packets[MAX_FUZZ_PACKETS]; |
1760
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
125 unsigned int num_packets = MAX_FUZZ_PACKETS; |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
126 fuzz_get_packets(inp, packets, &num_packets); |
1765
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
127 // printf("%d packets\n", num_packets); |
1760
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
128 |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
129 if (num_packets == 0) { |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
130 // gotta do something |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
131 memcpy(Data, FIXED_VERSION, MIN(strlen(FIXED_VERSION), MaxSize)); |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
132 return LLVMFuzzerMutate(Data, Size, MaxSize); |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
133 } |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
134 |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
135 /* Start output */ |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
136 /* Put a new banner to output */ |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
137 buf_putbytes(oup, FIXED_VERSION, strlen(FIXED_VERSION)); |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
138 |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
139 /* Iterate output */ |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
140 for (i = 0; i < num_packets+1; i++) { |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
141 // These are pointers to output |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
142 buffer *out_packetA = NULL, *out_packetB = NULL; |
1765
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
143 alloc_packetA->pos = 0; |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
144 alloc_packetA->len = 0; |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
145 alloc_packetB->pos = 0; |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
146 alloc_packetB->len = 0; |
1760
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
147 |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
148 /* 5% chance each */ |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
149 const int optA = nrand48(randstate) % 20; |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
150 if (optA == 0) { |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
151 /* Copy another */ |
1765
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
152 unsigned int other = nrand48(randstate) % num_packets; |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
153 out_packetA = packets[other]; |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
154 // printf("%d copy another %d\n", i, other); |
1760
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
155 } |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
156 if (optA == 1) { |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
157 /* Mutate another */ |
1765
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
158 unsigned int other = nrand48(randstate) % num_packets; |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
159 buffer *from = packets[other]; |
1760
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
160 buf_putbytes(alloc_packetA, from->data, from->len); |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
161 out_packetA = alloc_packetA; |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
162 buf_llvm_mutate(out_packetA); |
1765
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
163 // printf("%d mutate another %d\n", i, other); |
1760
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
164 } |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
165 |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
166 if (i < num_packets) { |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
167 int optB = nrand48(randstate) % 10; |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
168 if (optB == 1) { |
1765
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
169 /* 10% chance of drop */ |
1760
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
170 /* Drop it */ |
1765
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
171 // printf("%d drop\n", i); |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
172 } else if (optB <= 6) { |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
173 /* Mutate it, 50% chance */ |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
174 // printf("%d mutate\n", i); |
1760
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
175 buffer *from = packets[nrand48(randstate) % num_packets]; |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
176 buf_putbytes(alloc_packetB, from->data, from->len); |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
177 out_packetB = alloc_packetB; |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
178 buf_llvm_mutate(out_packetB); |
1765
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
179 } else { |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
180 /* Copy as-is */ |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
181 out_packetB = packets[i]; |
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
182 // printf("%d as-is\n", i); |
1760
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
183 } |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
184 } |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
185 |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
186 if (out_packetA && oup->len + out_packetA->len <= oup->size) { |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
187 buf_putbytes(oup, out_packetA->data, out_packetA->len); |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
188 } |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
189 if (out_packetB && oup->len + out_packetB->len <= oup->size) { |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
190 buf_putbytes(oup, out_packetB->data, out_packetB->len); |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
191 } |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
192 } |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
193 |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
194 for (i = 0; i < num_packets; i++) { |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
195 buf_free(packets[i]); |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
196 } |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
197 |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
198 size_t ret_len = MIN(MaxSize, oup->len); |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
199 memcpy(Data, oup->data, ret_len); |
1765
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
200 // printhex("mutator done", Data, ret_len); |
1760
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
201 return ret_len; |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
202 } |
2406a9987810
Add first try at fuzzing custom mutator
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
203 |
1766 | 204 size_t LLVMFuzzerCustomCrossOver(const uint8_t *Data1, size_t Size1, |
205 const uint8_t *Data2, size_t Size2, | |
206 uint8_t *Out, size_t MaxOutSize, | |
207 unsigned int Seed) { | |
208 unsigned short randstate[3] = {0,0,0}; | |
209 memcpy(randstate, &Seed, sizeof(Seed)); | |
1765
b688c884dad7
Fix fuzz-sshpacketmutator to work
Matt Johnston <matt@ucc.asn.au>
parents:
1760
diff
changeset
|
210 |
1766 | 211 unsigned int i; |
212 buffer inp_buf1 = {.data = (void*)Data1, .size = Size1, .len = Size1, .pos = 0}; | |
213 buffer *inp1 = &inp_buf1; | |
214 buffer inp_buf2 = {.data = (void*)Data2, .size = Size2, .len = Size2, .pos = 0}; | |
215 buffer *inp2 = &inp_buf2; | |
216 | |
217 buffer* packets1[MAX_FUZZ_PACKETS]; | |
218 unsigned int num_packets1 = MAX_FUZZ_PACKETS; | |
219 fuzz_get_packets(inp1, packets1, &num_packets1); | |
220 buffer* packets2[MAX_FUZZ_PACKETS]; | |
221 unsigned int num_packets2 = MAX_FUZZ_PACKETS; | |
222 fuzz_get_packets(inp2, packets2, &num_packets2); | |
223 | |
224 buffer *oup = buf_new(MAX_OUT_SIZE); | |
225 /* Put a new banner to output */ | |
226 buf_putbytes(oup, FIXED_VERSION, strlen(FIXED_VERSION)); | |
227 | |
228 for (i = 0; i < num_packets1+1; i++) { | |
229 if (num_packets2 > 0 && nrand48(randstate) % 10 == 0) { | |
230 /* 10% chance of taking another packet at each position */ | |
231 int other = nrand48(randstate) % num_packets2; | |
232 buffer *otherp = packets2[other]; | |
233 if (oup->len + otherp->len <= oup->size) { | |
234 buf_putbytes(oup, otherp->data, otherp->len); | |
235 } | |
236 } | |
237 if (i < num_packets1) { | |
238 buffer *thisp = packets1[i]; | |
239 if (oup->len + thisp->len <= oup->size) { | |
240 buf_putbytes(oup, thisp->data, thisp->len); | |
241 } | |
242 } | |
243 } | |
244 | |
245 for (i = 0; i < num_packets1; i++) { | |
246 buf_free(packets1[i]); | |
247 } | |
248 for (i = 0; i < num_packets2; i++) { | |
249 buf_free(packets2[i]); | |
250 } | |
251 | |
252 size_t ret_len = MIN(MaxOutSize, oup->len); | |
253 memcpy(Out, oup->data, ret_len); | |
254 buf_free(oup); | |
255 return ret_len; | |
256 } | |
257 |