mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-30 15:43:32 +01:00
Merge remote-tracking branch 'mikeperry-private/bug40897' into maint-0.4.8
This commit is contained in:
commit
6fbbcdde35
6
changes/bug40897
Normal file
6
changes/bug40897
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
o Major bugfixes (TROVE-2023-007, exit):
|
||||||
|
- Improper error propagation from a safety check in conflux leg
|
||||||
|
linking lead to a desynchronization of which legs were part of
|
||||||
|
a conflux set, ultimately causing a UAF and NULL pointer
|
||||||
|
dereference crash on Exit relays. Fixes bug 40897;
|
||||||
|
bugfix on 0.4.8.1-alpha.
|
@ -115,6 +115,8 @@ conflux_leg_t *
|
|||||||
conflux_get_leg(conflux_t *cfx, const circuit_t *circ)
|
conflux_get_leg(conflux_t *cfx, const circuit_t *circ)
|
||||||
{
|
{
|
||||||
conflux_leg_t *leg_found = NULL;
|
conflux_leg_t *leg_found = NULL;
|
||||||
|
tor_assert(cfx);
|
||||||
|
tor_assert(cfx->legs);
|
||||||
|
|
||||||
// Find the leg that the cell is written on
|
// Find the leg that the cell is written on
|
||||||
CONFLUX_FOR_EACH_LEG_BEGIN(cfx, leg) {
|
CONFLUX_FOR_EACH_LEG_BEGIN(cfx, leg) {
|
||||||
|
@ -56,6 +56,11 @@
|
|||||||
#define NUM_LEGS_SET_MAX (UINT8_MAX)
|
#define NUM_LEGS_SET_MAX (UINT8_MAX)
|
||||||
#define NUM_LEGS_SET_DEFAULT (2)
|
#define NUM_LEGS_SET_DEFAULT (2)
|
||||||
|
|
||||||
|
/* For "cfx_max_legs_set" */
|
||||||
|
#define MAX_LEGS_SET_MIN (3)
|
||||||
|
#define MAX_LEGS_SET_MAX (UINT8_MAX)
|
||||||
|
#define MAX_LEGS_SET_DEFAULT (8)
|
||||||
|
|
||||||
/* For "cfx_send_pct". */
|
/* For "cfx_send_pct". */
|
||||||
#define CFX_SEND_PCT_MIN (0)
|
#define CFX_SEND_PCT_MIN (0)
|
||||||
#define CFX_SEND_PCT_MAX (255)
|
#define CFX_SEND_PCT_MAX (255)
|
||||||
@ -81,6 +86,8 @@ static uint8_t max_prebuilt_set = MAX_PREBUILT_SET_DEFAULT;
|
|||||||
STATIC uint32_t max_unlinked_leg_retry = MAX_UNLINKED_LEG_RETRY_DEFAULT;
|
STATIC uint32_t max_unlinked_leg_retry = MAX_UNLINKED_LEG_RETRY_DEFAULT;
|
||||||
/* Number of legs per set. */
|
/* Number of legs per set. */
|
||||||
static uint8_t num_legs_set = NUM_LEGS_SET_DEFAULT;
|
static uint8_t num_legs_set = NUM_LEGS_SET_DEFAULT;
|
||||||
|
/* Maximum number of legs per set allowed at exits */
|
||||||
|
static uint8_t max_legs_set = MAX_LEGS_SET_DEFAULT;
|
||||||
/* The low Exit relay threshold, as a ratio between 0 and 1, used as a limit to
|
/* The low Exit relay threshold, as a ratio between 0 and 1, used as a limit to
|
||||||
* decide the amount of pre-built set we build depending on how many Exit relay
|
* decide the amount of pre-built set we build depending on how many Exit relay
|
||||||
* supports conflux in our current consensus. */
|
* supports conflux in our current consensus. */
|
||||||
@ -223,6 +230,13 @@ conflux_params_get_num_legs_set(void)
|
|||||||
return num_legs_set;
|
return num_legs_set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Return the maximum number of legs per set. */
|
||||||
|
uint8_t
|
||||||
|
conflux_params_get_max_legs_set(void)
|
||||||
|
{
|
||||||
|
return max_legs_set;
|
||||||
|
}
|
||||||
|
|
||||||
/** Return the drain percent we must hit before switching */
|
/** Return the drain percent we must hit before switching */
|
||||||
uint8_t
|
uint8_t
|
||||||
conflux_params_get_drain_pct(void)
|
conflux_params_get_drain_pct(void)
|
||||||
@ -275,6 +289,11 @@ conflux_params_new_consensus(const networkstatus_t *ns)
|
|||||||
NUM_LEGS_SET_DEFAULT,
|
NUM_LEGS_SET_DEFAULT,
|
||||||
NUM_LEGS_SET_MIN, NUM_LEGS_SET_MAX);
|
NUM_LEGS_SET_MIN, NUM_LEGS_SET_MAX);
|
||||||
|
|
||||||
|
max_legs_set =
|
||||||
|
networkstatus_get_param(ns, "cfx_max_legs_set",
|
||||||
|
MAX_LEGS_SET_DEFAULT,
|
||||||
|
MAX_LEGS_SET_MIN, MAX_LEGS_SET_MAX);
|
||||||
|
|
||||||
/* Params used by conflux.c */
|
/* Params used by conflux.c */
|
||||||
cfx_send_pct = networkstatus_get_param(ns, "cfx_send_pct",
|
cfx_send_pct = networkstatus_get_param(ns, "cfx_send_pct",
|
||||||
CFX_SEND_PCT_DFLT,
|
CFX_SEND_PCT_DFLT,
|
||||||
|
@ -16,6 +16,7 @@ uint8_t conflux_params_get_max_linked_set(void);
|
|||||||
uint8_t conflux_params_get_max_prebuilt(void);
|
uint8_t conflux_params_get_max_prebuilt(void);
|
||||||
uint8_t conflux_params_get_max_unlinked_leg_retry(void);
|
uint8_t conflux_params_get_max_unlinked_leg_retry(void);
|
||||||
uint8_t conflux_params_get_num_legs_set(void);
|
uint8_t conflux_params_get_num_legs_set(void);
|
||||||
|
uint8_t conflux_params_get_max_legs_set(void);
|
||||||
uint8_t conflux_params_get_drain_pct(void);
|
uint8_t conflux_params_get_drain_pct(void);
|
||||||
uint8_t conflux_params_get_send_pct(void);
|
uint8_t conflux_params_get_send_pct(void);
|
||||||
|
|
||||||
|
@ -187,6 +187,8 @@ conflux_free_(conflux_t *cfx)
|
|||||||
if (!cfx) {
|
if (!cfx) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
tor_assert(cfx->legs);
|
||||||
|
tor_assert(cfx->ooo_q);
|
||||||
|
|
||||||
SMARTLIST_FOREACH_BEGIN(cfx->legs, conflux_leg_t *, leg) {
|
SMARTLIST_FOREACH_BEGIN(cfx->legs, conflux_leg_t *, leg) {
|
||||||
SMARTLIST_DEL_CURRENT(cfx->legs, leg);
|
SMARTLIST_DEL_CURRENT(cfx->legs, leg);
|
||||||
@ -260,6 +262,8 @@ unlinked_free(unlinked_circuits_t *unlinked)
|
|||||||
if (!unlinked) {
|
if (!unlinked) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
tor_assert(unlinked->legs);
|
||||||
|
|
||||||
/* This cfx is pointing to a linked set. */
|
/* This cfx is pointing to a linked set. */
|
||||||
if (!unlinked->is_for_linked_set) {
|
if (!unlinked->is_for_linked_set) {
|
||||||
conflux_free(unlinked->cfx);
|
conflux_free(unlinked->cfx);
|
||||||
@ -493,10 +497,6 @@ cfx_add_leg(conflux_t *cfx, leg_t *leg)
|
|||||||
/* Big trouble if we add a leg to the wrong set. */
|
/* Big trouble if we add a leg to the wrong set. */
|
||||||
tor_assert(tor_memeq(cfx->nonce, leg->link->nonce, sizeof(cfx->nonce)));
|
tor_assert(tor_memeq(cfx->nonce, leg->link->nonce, sizeof(cfx->nonce)));
|
||||||
|
|
||||||
if (BUG(CONFLUX_NUM_LEGS(cfx) > CONFLUX_MAX_CIRCS)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
conflux_leg_t *cleg = tor_malloc_zero(sizeof(*cleg));
|
conflux_leg_t *cleg = tor_malloc_zero(sizeof(*cleg));
|
||||||
cleg->circ = leg->circ;
|
cleg->circ = leg->circ;
|
||||||
// TODO-329-ARTI: Blindly copying the values from the cell. Is this correct?
|
// TODO-329-ARTI: Blindly copying the values from the cell. Is this correct?
|
||||||
@ -731,6 +731,9 @@ try_finalize_set(unlinked_circuits_t *unlinked)
|
|||||||
bool is_client;
|
bool is_client;
|
||||||
|
|
||||||
tor_assert(unlinked);
|
tor_assert(unlinked);
|
||||||
|
tor_assert(unlinked->legs);
|
||||||
|
tor_assert(unlinked->cfx);
|
||||||
|
tor_assert(unlinked->cfx->legs);
|
||||||
|
|
||||||
/* Without legs, this is not ready to become a linked set. */
|
/* Without legs, this is not ready to become a linked set. */
|
||||||
if (BUG(smartlist_len(unlinked->legs) == 0)) {
|
if (BUG(smartlist_len(unlinked->legs) == 0)) {
|
||||||
@ -738,6 +741,17 @@ try_finalize_set(unlinked_circuits_t *unlinked)
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If there are too many legs, we can't link. */
|
||||||
|
if (smartlist_len(unlinked->legs) +
|
||||||
|
smartlist_len(unlinked->cfx->legs) > conflux_params_get_max_legs_set()) {
|
||||||
|
log_fn(LOG_PROTOCOL_WARN, LD_CIRC,
|
||||||
|
"Conflux set has too many legs to link. "
|
||||||
|
"Rejecting this circuit.");
|
||||||
|
conflux_log_set(LOG_PROTOCOL_WARN, unlinked->cfx, unlinked->is_client);
|
||||||
|
err = ERR_LINK_CIRC_INVALID_LEG;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
/* Validate that all legs are coherent and parameters match. On failure, we
|
/* Validate that all legs are coherent and parameters match. On failure, we
|
||||||
* teardown the whole unlinked set because this means we either have a code
|
* teardown the whole unlinked set because this means we either have a code
|
||||||
* flow problem or the Exit is trying to trick us. */
|
* flow problem or the Exit is trying to trick us. */
|
||||||
@ -1601,6 +1615,9 @@ linked_circuit_free(circuit_t *circ, bool is_client)
|
|||||||
{
|
{
|
||||||
tor_assert(circ);
|
tor_assert(circ);
|
||||||
tor_assert(circ->conflux);
|
tor_assert(circ->conflux);
|
||||||
|
tor_assert(circ->conflux->legs);
|
||||||
|
tor_assert(circ->conflux->ooo_q);
|
||||||
|
|
||||||
if (is_client) {
|
if (is_client) {
|
||||||
tor_assert(circ->purpose == CIRCUIT_PURPOSE_CONFLUX_LINKED);
|
tor_assert(circ->purpose == CIRCUIT_PURPOSE_CONFLUX_LINKED);
|
||||||
}
|
}
|
||||||
|
@ -22,19 +22,6 @@ typedef enum {
|
|||||||
CONFLUX_ALG_CWNDRTT = 2,
|
CONFLUX_ALG_CWNDRTT = 2,
|
||||||
} conflux_alg_t;
|
} conflux_alg_t;
|
||||||
|
|
||||||
/**
|
|
||||||
* Maximum number of linked circuits.
|
|
||||||
*
|
|
||||||
* We want to experiment with 3 guards, so we need at least 3 here.
|
|
||||||
*
|
|
||||||
* However, we need 1 more than this, to support using a test circuit to probe
|
|
||||||
* for a faster path, for applications that *require* a specific latency target
|
|
||||||
* (like VoIP).
|
|
||||||
*
|
|
||||||
* We may also want to raise this for traffic analysis defense evaluation.
|
|
||||||
*/
|
|
||||||
#define CONFLUX_MAX_CIRCS 4
|
|
||||||
|
|
||||||
/** XXX: Cached consensus params+scheduling alg */
|
/** XXX: Cached consensus params+scheduling alg */
|
||||||
struct conflux_params_t {
|
struct conflux_params_t {
|
||||||
conflux_alg_t alg;
|
conflux_alg_t alg;
|
||||||
|
Loading…
Reference in New Issue
Block a user