improved peer_conn fuzzer

This commit is contained in:
arvidn 2019-08-12 23:34:41 -07:00 committed by Arvid Norberg
parent 07ab3b9739
commit b97ac317f6
3 changed files with 46 additions and 33 deletions

View File

@ -161,6 +161,8 @@ extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv)
extern "C" int LLVMFuzzerTestOneInput(uint8_t const* data, size_t size)
{
if (size < 8) return 0;
#ifdef DEBUG_LOGGING
time_point const start_time = clock_type::now();
#endif
@ -175,10 +177,13 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* data, size_t size)
// bittorrent handshake
std::vector<char> handshake(1 + 19 + 8 + 20 + 20 + size);
std::memcpy(handshake.data(), "\x13" "BitTorrent protocol\0\0\0\0\0\0\0\x04", 28);
std::vector<char> handshake(1 + 19 + 8 + 20 + 20 + size - 8);
std::memcpy(handshake.data(), "\x13" "BitTorrent protocol", 20);
std::memcpy(handshake.data() + 20, data, 8);
std::memcpy(handshake.data() + 28, g_info_hash.data(), 20);
lt::aux::random_bytes({handshake.data() + 48, 20});
data += 8;
size -= 8;
std::memcpy(handshake.data() + 68, data, size);
// we're likely to fail to write entire (garbage) messages, as libtorrent may

View File

@ -44,22 +44,33 @@ messages = []
def add_length(msg):
return struct.pack('i', len(msg)) + msg
return struct.pack('>I', len(msg)) + msg
def add_reserved(msg):
return '\0\0\0\0\0\x18\0\x05' + msg
# extended handshake
def add_extended_handshake(msg):
ext_handshake = 'd1:md11:ut_metadatai1e11:lt_donthavei2e12:ut_holepunch' + \
'i3e11:upload_onlyi4ee11:upload_onlyi1e10:share_modei1e4:reqqi1234e6:yourip4:0000e'
return add_length(struct.pack('BB', 20, 0) + ext_handshake) + msg
# request
for i in range(101):
for j in range(-1, 1):
messages.append(add_length(struct.pack('Biii', 6, i, j, 0x4000)))
messages.append(add_length(struct.pack('>Biii', 6, i, j, 0x4000)))
# cancel
for i in range(101):
for j in range(-1, 1):
messages.append(add_length(struct.pack('Biii', 8, i, j, 0x4000)))
messages.append(add_length(struct.pack('>Biii', 8, i, j, 0x4000)))
# piece
for i in range(101):
messages.append(add_length(struct.pack('Bii', 7, i, 0) + ('a' * 0x4000)))
messages.append(add_length(struct.pack('>Bii', 7, i, 0) + ('a' * 0x4000)))
# single-byte
for i in range(256):
@ -67,23 +78,23 @@ for i in range(256):
# reject
for i in range(101):
messages.append(add_length(struct.pack('Biii', 16, i, 0, 0x4000)))
messages.append(add_length(struct.pack('>Biii', 16, i, 0, 0x4000)))
# suggest
for i in range(101):
messages.append(add_length(struct.pack('Bi', 13, i)))
messages.append(add_length(struct.pack('>Bi', 13, i)))
# allow-fast
for i in range(101):
messages.append(add_length(struct.pack('Bi', 17, i)))
messages.append(add_length(struct.pack('>Bi', 17, i)))
# have
for i in range(101):
messages.append(add_length(struct.pack('Bi', 4, i)))
messages.append(add_length(struct.pack('>Bi', 4, i)))
# DHT-port
for i in range(101):
messages.append(add_length(struct.pack('BH', 9, i * 10)))
messages.append(add_length(struct.pack('>BH', 9, i * 10)))
# hash request
for i in range(-10, 200, 20):
@ -91,7 +102,7 @@ for i in range(-10, 200, 20):
for k in range(-1, 1):
for l in range(-1, 1):
for m in range(-1, 1):
messages.append(add_length(struct.pack('biiiii', 21, i, j, k, l, m)))
messages.append(add_length(struct.pack('>Biiiii', 21, i, j, k, l, m)))
# hash reject
for i in range(-10, 200, 20):
@ -99,32 +110,32 @@ for i in range(-10, 200, 20):
for k in range(-1, 1):
for l in range(-1, 1):
for m in range(-1, 1):
messages.append(add_length(struct.pack('biiiii', 23, i, j, k, l, m)))
messages.append(add_length(struct.pack('>Biiiii', 23, i, j, k, l, m)))
# hash
for i in range(-10, 200, 20):
for j in range(-1, 1):
messages.append(add_length(struct.pack('biiiii', 22, i, j, 0, 2, 0) + ('0' * 32 * 5)))
messages.append(add_length(struct.pack('>Biiiii', 22, i, j, 0, 2, 0) + ('0' * 32 * 5)))
# lt_dont_have
messages.append(add_length(struct.pack('BBi', 20, 7, -1)))
messages.append(add_length(struct.pack('BBi', 20, 7, 0)))
messages.append(add_length(struct.pack('BBi', 20, 7, 0x7fffffff)))
messages.append(add_extended_handshake(add_length(struct.pack('>BBi', 20, 7, -1))))
messages.append(add_extended_handshake(add_length(struct.pack('>BBi', 20, 7, 0))))
messages.append(add_extended_handshake(add_length(struct.pack('>BBi', 20, 7, 0x7fffffff))))
# share mode
messages.append(add_length(struct.pack('BBB', 20, 8, 255)))
messages.append(add_length(struct.pack('BBB', 20, 8, 0)))
messages.append(add_length(struct.pack('BBB', 20, 8, 1)))
messages.append(add_extended_handshake(add_length(struct.pack('BBB', 20, 8, 255))))
messages.append(add_extended_handshake(add_length(struct.pack('BBB', 20, 8, 0))))
messages.append(add_extended_handshake(add_length(struct.pack('BBB', 20, 8, 1))))
# holepunch
for i in range(0, 2):
for j in range(0, 1):
messages.append(add_length(struct.pack('BBBBiH', 20, 4, i, j, 0, 0)))
messages.append(add_length(struct.pack('BBBBiiH', 20, 4, i, j, 0, 0, 0)))
messages.append(add_extended_handshake(add_length(struct.pack('>BBBBiH', 20, 4, i, j, 0, 0))))
messages.append(add_extended_handshake(add_length(struct.pack('>BBBBiiH', 20, 4, i, j, 0, 0, 0))))
# upload only
for i in range(0, 1):
messages.append(add_length(struct.pack('BBB', 20, 3, i)))
messages.append(add_extended_handshake(add_length(struct.pack('BBB', 20, 3, i))))
# bitfields
bitfield_len = (100 + 7)/8
@ -132,11 +143,6 @@ bitfield_len = (100 + 7)/8
for i in range(256):
messages.append(add_length(struct.pack('B', 5) + (chr(i) * bitfield_len)))
# extended handshake
ext_handshake = 'd1:md11:ut_metadatai1e11:lt_donthavei2eee'
for i in range(256):
messages.append(add_length(struct.pack('BB', 20, 0) + ext_handshake))
mixes = []
for i in range(200):
@ -147,5 +153,5 @@ messages += mixes
for m in messages:
f = open('corpus/peer_conn/%s' % hashlib.sha1(m).hexdigest(), 'w+')
f.write(m)
f.write(add_reserved(m))
f.close()

View File

@ -1343,7 +1343,8 @@ namespace {
TORRENT_ASSERT(recv_buffer.front() == holepunch_msg);
recv_buffer = recv_buffer.subspan(1);
const char* ptr = recv_buffer.data();
char const* ptr = recv_buffer.data();
char const* const end = recv_buffer.data() + recv_buffer.size();
// ignore invalid messages
if (int(recv_buffer.size()) < 2) return;
@ -1355,14 +1356,14 @@ namespace {
if (addr_type == 0)
{
if (int(recv_buffer.size()) != 2 + 4 + 2) return;
if (int(recv_buffer.size()) < 2 + 4 + 2) return;
// IPv4 address
ep = detail::read_v4_endpoint<tcp::endpoint>(ptr);
}
else if (addr_type == 1)
{
// IPv6 address
if (int(recv_buffer.size()) != 2 + 18 + 2) return;
if (int(recv_buffer.size()) < 2 + 16 + 2) return;
ep = detail::read_v6_endpoint<tcp::endpoint>(ptr);
}
else
@ -1487,7 +1488,8 @@ namespace {
} break;
case hp_message::failed:
{
std::uint32_t error = detail::read_uint32(ptr);
if (end - ptr < 4) return;
std::uint32_t const error = detail::read_uint32(ptr);
#ifndef TORRENT_DISABLE_LOGGING
if (should_log(peer_log_alert::incoming_message))
{