|
@@ -1016,12 +1016,16 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struc
|
|
|
sk->sk_family);
|
|
|
int err = 0;
|
|
|
|
|
|
- if (match)
|
|
|
- err = security_xfrm_policy_lookup(pol, fl->secid, policy_to_flow_dir(dir));
|
|
|
-
|
|
|
- if (match && !err)
|
|
|
- xfrm_pol_hold(pol);
|
|
|
- else
|
|
|
+ if (match) {
|
|
|
+ err = security_xfrm_policy_lookup(pol, fl->secid,
|
|
|
+ policy_to_flow_dir(dir));
|
|
|
+ if (!err)
|
|
|
+ xfrm_pol_hold(pol);
|
|
|
+ else if (err == -ESRCH)
|
|
|
+ pol = NULL;
|
|
|
+ else
|
|
|
+ pol = ERR_PTR(err);
|
|
|
+ } else
|
|
|
pol = NULL;
|
|
|
}
|
|
|
read_unlock_bh(&xfrm_policy_lock);
|
|
@@ -1313,8 +1317,11 @@ restart:
|
|
|
pol_dead = 0;
|
|
|
xfrm_nr = 0;
|
|
|
|
|
|
- if (sk && sk->sk_policy[1])
|
|
|
+ if (sk && sk->sk_policy[1]) {
|
|
|
policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl);
|
|
|
+ if (IS_ERR(policy))
|
|
|
+ return PTR_ERR(policy);
|
|
|
+ }
|
|
|
|
|
|
if (!policy) {
|
|
|
/* To accelerate a bit... */
|
|
@@ -1607,8 +1614,11 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
|
|
|
}
|
|
|
|
|
|
pol = NULL;
|
|
|
- if (sk && sk->sk_policy[dir])
|
|
|
+ if (sk && sk->sk_policy[dir]) {
|
|
|
pol = xfrm_sk_policy_lookup(sk, dir, &fl);
|
|
|
+ if (IS_ERR(pol))
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
|
|
|
if (!pol)
|
|
|
pol = flow_cache_lookup(&fl, family, fl_dir,
|