Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 441c7703 authored by Jason A. Donenfeld's avatar Jason A. Donenfeld Committed by Lee Jones
Browse files

UPSTREAM: wireguard: allowedips: expand maximum node depth



In the allowedips self-test, nodes are inserted into the tree, but it
generated an even amount of nodes, but for checking maximum node depth,
there is of course the root node, which makes the total number
necessarily odd. With two few nodes added, it never triggered the
maximum depth check like it should have. So, add 129 nodes instead of
128 nodes, and do so with a more straightforward scheme, starting with
all the bits set, and shifting over one each time. Then increase the
maximum depth to 129, and choose a better name for that variable to
make it clear that it represents depth as opposed to bits.

Bug: 254441685
Cc: stable@vger.kernel.org
Fixes: e7096c131e51 ("net: WireGuard secure network tunnel")
Signed-off-by: default avatarJason A. Donenfeld <Jason@zx2c4.com>
Link: https://lore.kernel.org/r/20230807132146.2191597-2-Jason@zx2c4.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
(cherry picked from commit 46622219aae2b67813fe31a7b8cb7da5baff5c8a)
Signed-off-by: default avatarLee Jones <joneslee@google.com>
Change-Id: Ib18397ecea77df6e10802bd625a06c4dacb2cafd
parent a777b7b9
Loading
Loading
Loading
Loading
+4 −4
Original line number Original line Diff line number Diff line
@@ -6,7 +6,7 @@
#include "allowedips.h"
#include "allowedips.h"
#include "peer.h"
#include "peer.h"


enum { MAX_ALLOWEDIPS_BITS = 128 };
enum { MAX_ALLOWEDIPS_DEPTH = 129 };


static struct kmem_cache *node_cache;
static struct kmem_cache *node_cache;


@@ -42,7 +42,7 @@ static void push_rcu(struct allowedips_node **stack,
		     struct allowedips_node __rcu *p, unsigned int *len)
		     struct allowedips_node __rcu *p, unsigned int *len)
{
{
	if (rcu_access_pointer(p)) {
	if (rcu_access_pointer(p)) {
		if (WARN_ON(IS_ENABLED(DEBUG) && *len >= MAX_ALLOWEDIPS_BITS))
		if (WARN_ON(IS_ENABLED(DEBUG) && *len >= MAX_ALLOWEDIPS_DEPTH))
			return;
			return;
		stack[(*len)++] = rcu_dereference_raw(p);
		stack[(*len)++] = rcu_dereference_raw(p);
	}
	}
@@ -55,7 +55,7 @@ static void node_free_rcu(struct rcu_head *rcu)


static void root_free_rcu(struct rcu_head *rcu)
static void root_free_rcu(struct rcu_head *rcu)
{
{
	struct allowedips_node *node, *stack[MAX_ALLOWEDIPS_BITS] = {
	struct allowedips_node *node, *stack[MAX_ALLOWEDIPS_DEPTH] = {
		container_of(rcu, struct allowedips_node, rcu) };
		container_of(rcu, struct allowedips_node, rcu) };
	unsigned int len = 1;
	unsigned int len = 1;


@@ -68,7 +68,7 @@ static void root_free_rcu(struct rcu_head *rcu)


static void root_remove_peer_lists(struct allowedips_node *root)
static void root_remove_peer_lists(struct allowedips_node *root)
{
{
	struct allowedips_node *node, *stack[MAX_ALLOWEDIPS_BITS] = { root };
	struct allowedips_node *node, *stack[MAX_ALLOWEDIPS_DEPTH] = { root };
	unsigned int len = 1;
	unsigned int len = 1;


	while (len > 0 && (node = stack[--len])) {
	while (len > 0 && (node = stack[--len])) {
+10 −6
Original line number Original line Diff line number Diff line
@@ -593,16 +593,20 @@ bool __init wg_allowedips_selftest(void)
	wg_allowedips_remove_by_peer(&t, a, &mutex);
	wg_allowedips_remove_by_peer(&t, a, &mutex);
	test_negative(4, a, 192, 168, 0, 1);
	test_negative(4, a, 192, 168, 0, 1);


	/* These will hit the WARN_ON(len >= MAX_ALLOWEDIPS_BITS) in free_node
	/* These will hit the WARN_ON(len >= MAX_ALLOWEDIPS_DEPTH) in free_node
	 * if something goes wrong.
	 * if something goes wrong.
	 */
	 */
	for (i = 0; i < MAX_ALLOWEDIPS_BITS; ++i) {
	for (i = 0; i < 64; ++i) {
		part = cpu_to_be64(~(1LLU << (i % 64)));
		part = cpu_to_be64(~0LLU << i);
		memset(&ip, 0xff, 16);
		memset(&ip, 0xff, 8);
		memcpy((u8 *)&ip + (i < 64) * 8, &part, 8);
		memcpy((u8 *)&ip + 8, &part, 8);
		wg_allowedips_insert_v6(&t, &ip, 128, a, &mutex);
		memcpy(&ip, &part, 8);
		memset((u8 *)&ip + 8, 0, 8);
		wg_allowedips_insert_v6(&t, &ip, 128, a, &mutex);
		wg_allowedips_insert_v6(&t, &ip, 128, a, &mutex);
	}
	}

	memset(&ip, 0, 16);
	wg_allowedips_insert_v6(&t, &ip, 128, a, &mutex);
	wg_allowedips_free(&t, &mutex);
	wg_allowedips_free(&t, &mutex);


	wg_allowedips_init(&t);
	wg_allowedips_init(&t);