aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLorenzo Colitti <lorenzo@google.com>2017-11-20 05:26:02 -0500
committerSteffen Klassert <steffen.klassert@secunet.com>2017-11-30 04:53:06 -0500
commitbe8f8284cd897af2482d4e54fbc2bdfc15557259 (patch)
tree475780994a1c466defe7a869622517d29ed68dc2
parentb9151761021e25c024a6670df4e7c43ffbab0e1d (diff)
net: xfrm: allow clearing socket xfrm policies.
Currently it is possible to add or update socket policies, but not clear them. Therefore, once a socket policy has been applied, the socket cannot be used for unencrypted traffic. This patch allows (privileged) users to clear socket policies by passing in a NULL pointer and zero length argument to the {IP,IPV6}_{IPSEC,XFRM}_POLICY setsockopts. This results in both the incoming and outgoing policies being cleared. The simple approach taken in this patch cannot clear socket policies in only one direction. If desired this could be added in the future, for example by continuing to pass in a length of zero (which currently is guaranteed to return EMSGSIZE) and making the policy be a pointer to an integer that contains one of the XFRM_POLICY_{IN,OUT} enum values. An alternative would have been to interpret the length as a signed integer and use XFRM_POLICY_IN (i.e., 0) to clear the input policy and -XFRM_POLICY_OUT (i.e., -1) to clear the output policy. Tested: https://android-review.googlesource.com/539816 Signed-off-by: Lorenzo Colitti <lorenzo@google.com> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
-rw-r--r--net/xfrm/xfrm_policy.c2
-rw-r--r--net/xfrm/xfrm_state.c7
2 files changed, 8 insertions, 1 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 9542975eb2f9..3263662fb20a 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1251,7 +1251,7 @@ EXPORT_SYMBOL(xfrm_policy_delete);
1251 1251
1252int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol) 1252int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol)
1253{ 1253{
1254 struct net *net = xp_net(pol); 1254 struct net *net = sock_net(sk);
1255 struct xfrm_policy *old_pol; 1255 struct xfrm_policy *old_pol;
1256 1256
1257#ifdef CONFIG_XFRM_SUB_POLICY 1257#ifdef CONFIG_XFRM_SUB_POLICY
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 065d89606888..1b7856be3eeb 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -2048,6 +2048,13 @@ int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen
2048 struct xfrm_mgr *km; 2048 struct xfrm_mgr *km;
2049 struct xfrm_policy *pol = NULL; 2049 struct xfrm_policy *pol = NULL;
2050 2050
2051 if (!optval && !optlen) {
2052 xfrm_sk_policy_insert(sk, XFRM_POLICY_IN, NULL);
2053 xfrm_sk_policy_insert(sk, XFRM_POLICY_OUT, NULL);
2054 __sk_dst_reset(sk);
2055 return 0;
2056 }
2057
2051 if (optlen <= 0 || optlen > PAGE_SIZE) 2058 if (optlen <= 0 || optlen > PAGE_SIZE)
2052 return -EMSGSIZE; 2059 return -EMSGSIZE;
2053 2060