提交 d809ec89 编写于 作者: T Timo Teräs 提交者: David S. Miller

xfrm: do not assume that template resolving always returns xfrms

xfrm_resolve_and_create_bundle() assumed that, if policies indicated
presence of xfrms, bundle template resolution would always return
some xfrms. This is not true for 'use' level policies which can
result in no xfrm's being applied if there is no suitable xfrm states.
This fixes a crash by this incorrect assumption.
Reported-by: NGeorge Spelvin <linux@horizon.com>
Bisected-by: NGeorge Spelvin <linux@horizon.com>
Tested-by: NGeorge Spelvin <linux@horizon.com>
Signed-off-by: NTimo Teräs <timo.teras@iki.fi>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 ab83a389
...@@ -1594,8 +1594,8 @@ xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols, ...@@ -1594,8 +1594,8 @@ xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols,
/* Try to instantiate a bundle */ /* Try to instantiate a bundle */
err = xfrm_tmpl_resolve(pols, num_pols, fl, xfrm, family); err = xfrm_tmpl_resolve(pols, num_pols, fl, xfrm, family);
if (err < 0) { if (err <= 0) {
if (err != -EAGAIN) if (err != 0 && err != -EAGAIN)
XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLERROR); XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLERROR);
return ERR_PTR(err); return ERR_PTR(err);
} }
...@@ -1678,6 +1678,13 @@ xfrm_bundle_lookup(struct net *net, struct flowi *fl, u16 family, u8 dir, ...@@ -1678,6 +1678,13 @@ xfrm_bundle_lookup(struct net *net, struct flowi *fl, u16 family, u8 dir,
goto make_dummy_bundle; goto make_dummy_bundle;
dst_hold(&xdst->u.dst); dst_hold(&xdst->u.dst);
return oldflo; return oldflo;
} else if (new_xdst == NULL) {
num_xfrms = 0;
if (oldflo == NULL)
goto make_dummy_bundle;
xdst->num_xfrms = 0;
dst_hold(&xdst->u.dst);
return oldflo;
} }
/* Kill the previous bundle */ /* Kill the previous bundle */
...@@ -1760,6 +1767,10 @@ int __xfrm_lookup(struct net *net, struct dst_entry **dst_p, struct flowi *fl, ...@@ -1760,6 +1767,10 @@ int __xfrm_lookup(struct net *net, struct dst_entry **dst_p, struct flowi *fl,
xfrm_pols_put(pols, num_pols); xfrm_pols_put(pols, num_pols);
err = PTR_ERR(xdst); err = PTR_ERR(xdst);
goto dropdst; goto dropdst;
} else if (xdst == NULL) {
num_xfrms = 0;
drop_pols = num_pols;
goto no_transform;
} }
spin_lock_bh(&xfrm_policy_sk_bundle_lock); spin_lock_bh(&xfrm_policy_sk_bundle_lock);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册