mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-30 15:43:32 +01:00
Actually allow unrecognized address types in NETINFO cell
Ignore the address value instead of failing with error condition in case unrecognized address type is found.
This commit is contained in:
parent
5b2acbec0e
commit
c92c0cbc9f
@ -147,6 +147,7 @@ src_test_test_SOURCES += \
|
|||||||
src/test/test_logging.c \
|
src/test/test_logging.c \
|
||||||
src/test/test_mainloop.c \
|
src/test/test_mainloop.c \
|
||||||
src/test/test_microdesc.c \
|
src/test/test_microdesc.c \
|
||||||
|
src/test/test_netinfo.c \
|
||||||
src/test/test_nodelist.c \
|
src/test/test_nodelist.c \
|
||||||
src/test/test_oom.c \
|
src/test/test_oom.c \
|
||||||
src/test/test_oos.c \
|
src/test/test_oos.c \
|
||||||
|
@ -890,6 +890,7 @@ struct testgroup_t testgroups[] = {
|
|||||||
{ "legacy_hs/", hs_tests },
|
{ "legacy_hs/", hs_tests },
|
||||||
{ "link-handshake/", link_handshake_tests },
|
{ "link-handshake/", link_handshake_tests },
|
||||||
{ "mainloop/", mainloop_tests },
|
{ "mainloop/", mainloop_tests },
|
||||||
|
{ "netinfo/", netinfo_tests },
|
||||||
{ "nodelist/", nodelist_tests },
|
{ "nodelist/", nodelist_tests },
|
||||||
{ "oom/", oom_tests },
|
{ "oom/", oom_tests },
|
||||||
{ "oos/", oos_tests },
|
{ "oos/", oos_tests },
|
||||||
|
@ -232,6 +232,7 @@ extern struct testcase_t link_handshake_tests[];
|
|||||||
extern struct testcase_t logging_tests[];
|
extern struct testcase_t logging_tests[];
|
||||||
extern struct testcase_t mainloop_tests[];
|
extern struct testcase_t mainloop_tests[];
|
||||||
extern struct testcase_t microdesc_tests[];
|
extern struct testcase_t microdesc_tests[];
|
||||||
|
extern struct testcase_t netinfo_tests[];
|
||||||
extern struct testcase_t nodelist_tests[];
|
extern struct testcase_t nodelist_tests[];
|
||||||
extern struct testcase_t oom_tests[];
|
extern struct testcase_t oom_tests[];
|
||||||
extern struct testcase_t oos_tests[];
|
extern struct testcase_t oos_tests[];
|
||||||
|
48
src/test/test_netinfo.c
Normal file
48
src/test/test_netinfo.c
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/* Copyright (c) 2007-2018, The Tor Project, Inc. */
|
||||||
|
/* See LICENSE for licensing information */
|
||||||
|
|
||||||
|
#include "orconfig.h"
|
||||||
|
#include "core/or/or.h" // XXX: is this needed?
|
||||||
|
#include "trunnel/netinfo.h"
|
||||||
|
#include "test/test.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_netinfo_unsupported_addr(void *arg)
|
||||||
|
{
|
||||||
|
const uint8_t wire_data[] =
|
||||||
|
{ // TIME
|
||||||
|
0x00, 0x00, 0x00, 0x01,
|
||||||
|
// OTHERADDR
|
||||||
|
0x04, // ATYPE
|
||||||
|
0x04, // ALEN
|
||||||
|
0x08, 0x08, 0x08, 0x08, // AVAL
|
||||||
|
0x01, // NMYADDR
|
||||||
|
0x03, // ATYPE (unsupported)
|
||||||
|
0x05, // ALEN
|
||||||
|
'a', 'd', 'r', 'r', '!' // AVAL (unsupported)
|
||||||
|
};
|
||||||
|
|
||||||
|
(void)arg;
|
||||||
|
|
||||||
|
netinfo_cell_t *parsed_cell = NULL;
|
||||||
|
|
||||||
|
ssize_t parsed = netinfo_cell_parse(&parsed_cell, wire_data,
|
||||||
|
sizeof(wire_data));
|
||||||
|
|
||||||
|
tt_assert(parsed == sizeof(wire_data));
|
||||||
|
|
||||||
|
netinfo_addr_t *addr = netinfo_cell_get_my_addrs(parsed_cell, 0);
|
||||||
|
tt_assert(addr);
|
||||||
|
|
||||||
|
tt_int_op(3, OP_EQ, netinfo_addr_get_addr_type(addr));
|
||||||
|
tt_int_op(5, OP_EQ, netinfo_addr_get_len(addr));
|
||||||
|
|
||||||
|
done:
|
||||||
|
netinfo_cell_free(parsed_cell);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct testcase_t netinfo_tests[] = {
|
||||||
|
{ "unsupported_addr", test_netinfo_unsupported_addr, 0, NULL, NULL },
|
||||||
|
END_OF_TESTCASES
|
||||||
|
};
|
||||||
|
|
@ -140,7 +140,6 @@ netinfo_addr_check(const netinfo_addr_t *obj)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return "Bad tag for union";
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -175,7 +174,6 @@ netinfo_addr_encoded_len(const netinfo_addr_t *obj)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
trunnel_assert(0);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -198,6 +196,8 @@ netinfo_addr_encode(uint8_t *output, const size_t avail, const netinfo_addr_t *o
|
|||||||
const ssize_t encoded_len = netinfo_addr_encoded_len(obj);
|
const ssize_t encoded_len = netinfo_addr_encoded_len(obj);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
uint8_t *backptr_len = NULL;
|
||||||
|
|
||||||
if (NULL != (msg = netinfo_addr_check(obj)))
|
if (NULL != (msg = netinfo_addr_check(obj)))
|
||||||
goto check_failed;
|
goto check_failed;
|
||||||
|
|
||||||
@ -213,11 +213,14 @@ netinfo_addr_encode(uint8_t *output, const size_t avail, const netinfo_addr_t *o
|
|||||||
written += 1; ptr += 1;
|
written += 1; ptr += 1;
|
||||||
|
|
||||||
/* Encode u8 len */
|
/* Encode u8 len */
|
||||||
|
backptr_len = ptr;
|
||||||
trunnel_assert(written <= avail);
|
trunnel_assert(written <= avail);
|
||||||
if (avail - written < 1)
|
if (avail - written < 1)
|
||||||
goto truncated;
|
goto truncated;
|
||||||
trunnel_set_uint8(ptr, (obj->len));
|
trunnel_set_uint8(ptr, (obj->len));
|
||||||
written += 1; ptr += 1;
|
written += 1; ptr += 1;
|
||||||
|
{
|
||||||
|
size_t written_before_union = written;
|
||||||
|
|
||||||
/* Encode union addr[addr_type] */
|
/* Encode union addr[addr_type] */
|
||||||
trunnel_assert(written <= avail);
|
trunnel_assert(written <= avail);
|
||||||
@ -244,9 +247,16 @@ netinfo_addr_encode(uint8_t *output, const size_t avail, const netinfo_addr_t *o
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
trunnel_assert(0);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/* Write the length field back to len */
|
||||||
|
trunnel_assert(written >= written_before_union);
|
||||||
|
#if UINT8_MAX < SIZE_MAX
|
||||||
|
if (written - written_before_union > UINT8_MAX)
|
||||||
|
goto check_failed;
|
||||||
|
#endif
|
||||||
|
trunnel_set_uint8(backptr_len, (written - written_before_union));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
trunnel_assert(ptr == output + written);
|
trunnel_assert(ptr == output + written);
|
||||||
@ -291,6 +301,11 @@ netinfo_addr_parse_into(netinfo_addr_t *obj, const uint8_t *input, const size_t
|
|||||||
CHECK_REMAINING(1, truncated);
|
CHECK_REMAINING(1, truncated);
|
||||||
obj->len = (trunnel_get_uint8(ptr));
|
obj->len = (trunnel_get_uint8(ptr));
|
||||||
remaining -= 1; ptr += 1;
|
remaining -= 1; ptr += 1;
|
||||||
|
{
|
||||||
|
size_t remaining_after;
|
||||||
|
CHECK_REMAINING(obj->len, truncated);
|
||||||
|
remaining_after = remaining - obj->len;
|
||||||
|
remaining = obj->len;
|
||||||
|
|
||||||
/* Parse union addr[addr_type] */
|
/* Parse union addr[addr_type] */
|
||||||
switch (obj->addr_type) {
|
switch (obj->addr_type) {
|
||||||
@ -298,7 +313,7 @@ netinfo_addr_parse_into(netinfo_addr_t *obj, const uint8_t *input, const size_t
|
|||||||
case NETINFO_ADDR_TYPE_IPV4:
|
case NETINFO_ADDR_TYPE_IPV4:
|
||||||
|
|
||||||
/* Parse u32 addr_ipv4 */
|
/* Parse u32 addr_ipv4 */
|
||||||
CHECK_REMAINING(4, truncated);
|
CHECK_REMAINING(4, fail);
|
||||||
obj->addr_ipv4 = trunnel_ntohl(trunnel_get_uint32(ptr));
|
obj->addr_ipv4 = trunnel_ntohl(trunnel_get_uint32(ptr));
|
||||||
remaining -= 4; ptr += 4;
|
remaining -= 4; ptr += 4;
|
||||||
break;
|
break;
|
||||||
@ -306,15 +321,20 @@ netinfo_addr_parse_into(netinfo_addr_t *obj, const uint8_t *input, const size_t
|
|||||||
case NETINFO_ADDR_TYPE_IPV6:
|
case NETINFO_ADDR_TYPE_IPV6:
|
||||||
|
|
||||||
/* Parse u8 addr_ipv6[16] */
|
/* Parse u8 addr_ipv6[16] */
|
||||||
CHECK_REMAINING(16, truncated);
|
CHECK_REMAINING(16, fail);
|
||||||
memcpy(obj->addr_ipv6, ptr, 16);
|
memcpy(obj->addr_ipv6, ptr, 16);
|
||||||
remaining -= 16; ptr += 16;
|
remaining -= 16; ptr += 16;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
goto fail;
|
/* Skip to end of union */
|
||||||
|
ptr += remaining; remaining = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (remaining != 0)
|
||||||
|
goto fail;
|
||||||
|
remaining = remaining_after;
|
||||||
|
}
|
||||||
trunnel_assert(ptr + remaining == input + len_in);
|
trunnel_assert(ptr + remaining == input + len_in);
|
||||||
return len_in - remaining;
|
return len_in - remaining;
|
||||||
|
|
||||||
|
@ -7,10 +7,10 @@ const NETINFO_ADDR_TYPE_IPV6 = 6;
|
|||||||
struct netinfo_addr {
|
struct netinfo_addr {
|
||||||
u8 addr_type;
|
u8 addr_type;
|
||||||
u8 len;
|
u8 len;
|
||||||
union addr[addr_type] {
|
union addr[addr_type] with length len {
|
||||||
NETINFO_ADDR_TYPE_IPV4: u32 ipv4;
|
NETINFO_ADDR_TYPE_IPV4: u32 ipv4;
|
||||||
NETINFO_ADDR_TYPE_IPV6: u8 ipv6[16];
|
NETINFO_ADDR_TYPE_IPV6: u8 ipv6[16];
|
||||||
default: fail;
|
default: ignore;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user