提交 2f8e496f 编写于 作者: H Hangyu Hua 提交者: Zheng Zengkai

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

stable inclusion
from stable-v5.10.134
commit 47b696dd654450cdec3103a833e5bf29c4b83bfa
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I5JMHA
CVE: CVE-2022-36879

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=linux-5.10.y&id=47b696dd654450cdec3103a833e5bf29c4b83bfa

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

[ Upstream commit f85daf0e ]

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: NHangyu Hua <hbh25y@gmail.com>
Signed-off-by: NSteffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: NSasha Levin <sashal@kernel.org>
Signed-off-by: NZhengchao Shao <shaozhengchao@huawei.com>
Reviewed-by: NWei Yongjun <weiyongjun1@huawei.com>
Reviewed-by: NXiu Jianfeng <xiujianfeng@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 429afa67
...@@ -2680,8 +2680,10 @@ static int xfrm_expand_policies(const struct flowi *fl, u16 family, ...@@ -2680,8 +2680,10 @@ static int xfrm_expand_policies(const struct flowi *fl, u16 family,
*num_xfrms = 0; *num_xfrms = 0;
return 0; return 0;
} }
if (IS_ERR(pols[0])) if (IS_ERR(pols[0])) {
*num_pols = 0;
return PTR_ERR(pols[0]); return PTR_ERR(pols[0]);
}
*num_xfrms = pols[0]->xfrm_nr; *num_xfrms = pols[0]->xfrm_nr;
...@@ -2696,6 +2698,7 @@ static int xfrm_expand_policies(const struct flowi *fl, u16 family, ...@@ -2696,6 +2698,7 @@ static int xfrm_expand_policies(const struct flowi *fl, u16 family,
if (pols[1]) { if (pols[1]) {
if (IS_ERR(pols[1])) { if (IS_ERR(pols[1])) {
xfrm_pols_put(pols, *num_pols); xfrm_pols_put(pols, *num_pols);
*num_pols = 0;
return PTR_ERR(pols[1]); return PTR_ERR(pols[1]);
} }
(*num_pols)++; (*num_pols)++;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册