mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 21:23:58 +01:00
Fix IPv6 support in policy_summary_reject and policy_summary_accept
This interim fix results in too many IPv6 rejections. No behaviour change for IPv4 counts, except for overflow fixes that would require 4 billion redundant 0.0.0.0/0 policy entries to trigger. Part of 21357
This commit is contained in:
parent
82850d0da6
commit
4667a40ca9
@ -2304,6 +2304,12 @@ policy_summary_item_split(policy_summary_item_t* old, uint16_t new_starts)
|
|||||||
* IPv4 /8 address blocks */
|
* IPv4 /8 address blocks */
|
||||||
#define REJECT_CUTOFF_COUNT_IPV4 (U64_LITERAL(1) << \
|
#define REJECT_CUTOFF_COUNT_IPV4 (U64_LITERAL(1) << \
|
||||||
(IPV4_BITS - 7))
|
(IPV4_BITS - 7))
|
||||||
|
|
||||||
|
#define IPV6_BITS (128)
|
||||||
|
/* Ports are rejected in an IPv6 summary if they are rejected in at least one
|
||||||
|
* IPv6 /64. */
|
||||||
|
#define REJECT_CUTOFF_COUNT_IPV6 (UINT64_MAX)
|
||||||
|
|
||||||
/** Split an exit policy summary so that prt_min and prt_max
|
/** Split an exit policy summary so that prt_min and prt_max
|
||||||
* fall at exactly the start and end of an item respectively.
|
* fall at exactly the start and end of an item respectively.
|
||||||
*/
|
*/
|
||||||
@ -2336,40 +2342,68 @@ policy_summary_split(smartlist_t *summary,
|
|||||||
return start_at_index;
|
return start_at_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Mark port ranges as accepted if they are below the reject_count */
|
/** Mark port ranges as accepted if they are below the reject_count for family
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
policy_summary_accept(smartlist_t *summary,
|
policy_summary_accept(smartlist_t *summary,
|
||||||
uint16_t prt_min, uint16_t prt_max)
|
uint16_t prt_min, uint16_t prt_max,
|
||||||
|
sa_family_t family)
|
||||||
{
|
{
|
||||||
|
tor_assert_nonfatal_once(family == AF_INET || family == AF_INET6);
|
||||||
|
uint64_t family_reject_count = ((family == AF_INET) ?
|
||||||
|
REJECT_CUTOFF_COUNT_IPV4 :
|
||||||
|
REJECT_CUTOFF_COUNT_IPV6);
|
||||||
|
|
||||||
int i = policy_summary_split(summary, prt_min, prt_max);
|
int i = policy_summary_split(summary, prt_min, prt_max);
|
||||||
while (i < smartlist_len(summary) &&
|
while (i < smartlist_len(summary) &&
|
||||||
AT(i)->prt_max <= prt_max) {
|
AT(i)->prt_max <= prt_max) {
|
||||||
if (!AT(i)->accepted &&
|
if (!AT(i)->accepted &&
|
||||||
AT(i)->reject_count <= REJECT_CUTOFF_COUNT_IPV4)
|
AT(i)->reject_count <= family_reject_count)
|
||||||
AT(i)->accepted = 1;
|
AT(i)->accepted = 1;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
tor_assert(i < smartlist_len(summary) || prt_max==65535);
|
tor_assert(i < smartlist_len(summary) || prt_max==65535);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Count the number of addresses in a network with prefixlen maskbits
|
/** Count the number of addresses in a network in family with prefixlen
|
||||||
* against the given portrange. */
|
* maskbits against the given portrange. */
|
||||||
static void
|
static void
|
||||||
policy_summary_reject(smartlist_t *summary,
|
policy_summary_reject(smartlist_t *summary,
|
||||||
maskbits_t maskbits,
|
maskbits_t maskbits,
|
||||||
uint16_t prt_min, uint16_t prt_max)
|
uint16_t prt_min, uint16_t prt_max,
|
||||||
|
sa_family_t family)
|
||||||
{
|
{
|
||||||
|
tor_assert_nonfatal_once(family == AF_INET || family == AF_INET6);
|
||||||
|
|
||||||
int i = policy_summary_split(summary, prt_min, prt_max);
|
int i = policy_summary_split(summary, prt_min, prt_max);
|
||||||
/* XXX: ipv4 specific */
|
|
||||||
/* The length of a single address mask */
|
/* The length of a single address mask */
|
||||||
int addrbits = IPV4_BITS;
|
int addrbits = (family == AF_INET) ? IPV4_BITS : IPV6_BITS;
|
||||||
tor_assert_nonfatal_once(addrbits >= maskbits);
|
tor_assert_nonfatal_once(addrbits >= maskbits);
|
||||||
|
|
||||||
uint64_t count = (U64_LITERAL(1) << (addrbits-maskbits));
|
uint64_t count = 0;
|
||||||
|
if (addrbits - maskbits >= 64) {
|
||||||
|
tor_assert_nonfatal_once(family == AF_INET6);
|
||||||
|
/* The address range is so large, it's an automatic rejection for all ports
|
||||||
|
* in the range. */
|
||||||
|
count = UINT64_MAX;
|
||||||
|
} else {
|
||||||
|
count = (U64_LITERAL(1) << (addrbits - maskbits));
|
||||||
|
}
|
||||||
tor_assert_nonfatal_once(count > 0);
|
tor_assert_nonfatal_once(count > 0);
|
||||||
while (i < smartlist_len(summary) &&
|
while (i < smartlist_len(summary) &&
|
||||||
AT(i)->prt_max <= prt_max) {
|
AT(i)->prt_max <= prt_max) {
|
||||||
AT(i)->reject_count += count;
|
if (AT(i)->reject_count <= UINT64_MAX - count) {
|
||||||
|
AT(i)->reject_count += count;
|
||||||
|
} else {
|
||||||
|
/* IPv4 would require a 4-billion address redundant policy to get here,
|
||||||
|
* but IPv6 just needs to have ::/0 */
|
||||||
|
if (family == AF_INET) {
|
||||||
|
tor_assert_nonfatal_unreached_once();
|
||||||
|
}
|
||||||
|
/* If we do get here, use saturating arithmetic */
|
||||||
|
AT(i)->reject_count = UINT64_MAX;
|
||||||
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
tor_assert(i < smartlist_len(summary) || prt_max==65535);
|
tor_assert(i < smartlist_len(summary) || prt_max==65535);
|
||||||
@ -2389,7 +2423,7 @@ policy_summary_add_item(smartlist_t *summary, addr_policy_t *p)
|
|||||||
{
|
{
|
||||||
if (p->policy_type == ADDR_POLICY_ACCEPT) {
|
if (p->policy_type == ADDR_POLICY_ACCEPT) {
|
||||||
if (p->maskbits == 0) {
|
if (p->maskbits == 0) {
|
||||||
policy_summary_accept(summary, p->prt_min, p->prt_max);
|
policy_summary_accept(summary, p->prt_min, p->prt_max, p->addr.family);
|
||||||
}
|
}
|
||||||
} else if (p->policy_type == ADDR_POLICY_REJECT) {
|
} else if (p->policy_type == ADDR_POLICY_REJECT) {
|
||||||
|
|
||||||
@ -2410,7 +2444,8 @@ policy_summary_add_item(smartlist_t *summary, addr_policy_t *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!is_private) {
|
if (!is_private) {
|
||||||
policy_summary_reject(summary, p->maskbits, p->prt_min, p->prt_max);
|
policy_summary_reject(summary, p->maskbits, p->prt_min, p->prt_max,
|
||||||
|
p->addr.family);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
tor_assert(0);
|
tor_assert(0);
|
||||||
@ -2444,7 +2479,6 @@ policy_summarize(smartlist_t *policy, sa_family_t family)
|
|||||||
}
|
}
|
||||||
if (f != family)
|
if (f != family)
|
||||||
continue;
|
continue;
|
||||||
/* XXXX-ipv6 More family work is needed */
|
|
||||||
policy_summary_add_item(summary, p);
|
policy_summary_add_item(summary, p);
|
||||||
} SMARTLIST_FOREACH_END(p);
|
} SMARTLIST_FOREACH_END(p);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user