xfrm: xfrm_policy: fix a possible double xfrm_pols_put() in xfrm_bundle_lookup()
ANBZ: #2007 commitf85daf0e72
upstream. 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:80c802f307
("xfrm: cache bundles instead of policies for outgoing flows") Signed-off-by: Hangyu Hua <hbh25y@gmail.com> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com> Acked-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Link: https://gitee.com/anolis/cloud-kernel/pulls/678
This commit is contained in:
parent
f35a9b6d6a
commit
3f80c7374e
|
@ -1706,8 +1706,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;
|
||||
|
||||
|
@ -1722,6 +1724,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)++;
|
||||
|
|
Loading…
Reference in New Issue