Commit e40569cb authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso Committed by Liu Jian
Browse files

netfilter: nft_flow_offload: reset dst in route object after setting up flow

mainline inclusion
from mainline-v6.8-rc6
commit 9e0f0430389be7696396c62f037be4bf72cf93e3
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9Q8LQ
CVE: CVE-2024-27403

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=9e0f0430389be7696396c62f037be4bf72cf93e3



---------------------------

dst is transferred to the flow object, route object does not own it
anymore.  Reset dst in route object, otherwise if flow_offload_add()
fails, error path releases dst twice, leading to a refcount underflow.

Fixes: a3c90f7a ("netfilter: nf_tables: flow offload expression")
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>

Conflicts:
	include/net/netfilter/nf_flow_table.h
	net/netfilter/nf_flow_table_core.c
[This is because we did not backport f1363e05, fa502c86,
8b9229d1, 7a27f6ab]
Signed-off-by: default avatarLiu Jian <liujian56@huawei.com>
parent 5bab8a92
Loading
Loading
Loading
Loading
+11 −1
Original line number Original line Diff line number Diff line
@@ -21,6 +21,16 @@ struct flow_offload_entry {
static DEFINE_MUTEX(flowtable_lock);
static DEFINE_MUTEX(flowtable_lock);
static LIST_HEAD(flowtables);
static LIST_HEAD(flowtables);


static struct dst_entry *nft_route_dst_fetch(struct nf_flow_route *route,
					     enum flow_offload_tuple_dir dir)
{
	struct dst_entry *dst = route->tuple[dir].dst;

	route->tuple[dir].dst = NULL;

	return dst;
}

static void
static void
flow_offload_fill_dir(struct flow_offload *flow, struct nf_conn *ct,
flow_offload_fill_dir(struct flow_offload *flow, struct nf_conn *ct,
		      struct nf_flow_route *route,
		      struct nf_flow_route *route,
@@ -29,7 +39,7 @@ flow_offload_fill_dir(struct flow_offload *flow, struct nf_conn *ct,
	struct flow_offload_tuple *ft = &flow->tuplehash[dir].tuple;
	struct flow_offload_tuple *ft = &flow->tuplehash[dir].tuple;
	struct nf_conntrack_tuple *ctt = &ct->tuplehash[dir].tuple;
	struct nf_conntrack_tuple *ctt = &ct->tuplehash[dir].tuple;
	struct dst_entry *other_dst = route->tuple[!dir].dst;
	struct dst_entry *other_dst = route->tuple[!dir].dst;
	struct dst_entry *dst = route->tuple[dir].dst;
	struct dst_entry *dst = nft_route_dst_fetch(route, dir);


	ft->dir = dir;
	ft->dir = dir;