Commit fa41884c authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'wireguard-fixes-for-6-5-rc6'

Jason A. Donenfeld says:

====================
wireguard fixes for 6.5-rc6

Just one patch this time, somewhat late in the cycle:

1) Fix an off-by-one calculation for the maximum node depth size in the
   allowedips trie data structure, and also adjust the self-tests to hit
   this case so it doesn't regress again in the future.
====================

Link: https://lore.kernel.org/r/20230807132146.2191597-1-Jason@zx2c4.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 01f4fd27 46622219
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -6,7 +6,7 @@
#include "allowedips.h"
#include "peer.h"

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

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)
{
	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;
		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)
{
	struct allowedips_node *node, *stack[MAX_ALLOWEDIPS_BITS] = {
	struct allowedips_node *node, *stack[MAX_ALLOWEDIPS_DEPTH] = {
		container_of(rcu, struct allowedips_node, rcu) };
	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)
{
	struct allowedips_node *node, *stack[MAX_ALLOWEDIPS_BITS] = { root };
	struct allowedips_node *node, *stack[MAX_ALLOWEDIPS_DEPTH] = { root };
	unsigned int len = 1;

	while (len > 0 && (node = stack[--len])) {
+10 −6
Original line number Diff line number Diff line
@@ -593,16 +593,20 @@ bool __init wg_allowedips_selftest(void)
	wg_allowedips_remove_by_peer(&t, a, &mutex);
	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.
	 */
	for (i = 0; i < MAX_ALLOWEDIPS_BITS; ++i) {
		part = cpu_to_be64(~(1LLU << (i % 64)));
		memset(&ip, 0xff, 16);
		memcpy((u8 *)&ip + (i < 64) * 8, &part, 8);
	for (i = 0; i < 64; ++i) {
		part = cpu_to_be64(~0LLU << i);
		memset(&ip, 0xff, 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);
	}

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

	wg_allowedips_init(&t);