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

Commit 5aff12fa authored by Hangyu Hua's avatar Hangyu Hua Committed by Greg Kroah-Hartman
Browse files

xfrm: xfrm_policy: fix a possible double xfrm_pols_put() in xfrm_bundle_lookup()



[ Upstream commit f85daf0e725358be78dfd208dea5fd665d8cb901 ]

xfrm_policy_lookup() will call xfrm_pol_hold_rcu() to get a refcount of
pols[0]. This refcount can be dropped in xfrm_expand_policies() when
xfrm_expand_policies() return error. pols[0]'s refcount is balanced in
here. But xfrm_bundle_lookup() will also call xfrm_pols_put() with
num_pols == 1 to drop this refcount when xfrm_expand_policies() return
error.

This patch also fix an illegal address access. pols[0] will save a error
point when xfrm_policy_lookup fails. This lead to xfrm_pols_put to resolve
an illegal address in xfrm_bundle_lookup's error path.

Fix these by setting num_pols = 0 in xfrm_expand_policies()'s error path.

Fixes: 80c802f3 ("xfrm: cache bundles instead of policies for outgoing flows")
Signed-off-by: default avatarHangyu Hua <hbh25y@gmail.com>
Signed-off-by: default avatarSteffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 2994afca
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -1819,8 +1819,10 @@ static int xfrm_expand_policies(const struct flowi *fl, u16 family,
		*num_xfrms = 0;
		return 0;
	}
	if (IS_ERR(pols[0]))
	if (IS_ERR(pols[0])) {
		*num_pols = 0;
		return PTR_ERR(pols[0]);
	}

	*num_xfrms = pols[0]->xfrm_nr;

@@ -1834,6 +1836,7 @@ static int xfrm_expand_policies(const struct flowi *fl, u16 family,
		if (pols[1]) {
			if (IS_ERR(pols[1])) {
				xfrm_pols_put(pols, *num_pols);
				*num_pols = 0;
				return PTR_ERR(pols[1]);
			}
			(*num_pols)++;