Re: [PATCH ipsec-next] net: xfrm: allow clearing socket xfrm policies.

2017-11-30 Thread Steffen Klassert
On Mon, Nov 20, 2017 at 07:26:02PM +0900, Lorenzo Colitti wrote:
> 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 

Applied to ipsec-next, thanks Lorenzo!


[PATCH ipsec-next] net: xfrm: allow clearing socket xfrm policies.

2017-11-20 Thread Lorenzo Colitti
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 
---
 net/xfrm/xfrm_policy.c | 2 +-
 net/xfrm/xfrm_state.c  | 7 +++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index f02b1743b2..d5ef584642 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1251,7 +1251,7 @@ EXPORT_SYMBOL(xfrm_policy_delete);
 
 int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol)
 {
-   struct net *net = xp_net(pol);
+   struct net *net = sock_net(sk);
struct xfrm_policy *old_pol;
 
 #ifdef CONFIG_XFRM_SUB_POLICY
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 1f5cee2269..ec0c738c4d 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -2049,6 +2049,13 @@ int xfrm_user_policy(struct sock *sk, int optname, u8 
__user *optval, int optlen
struct xfrm_mgr *km;
struct xfrm_policy *pol = NULL;
 
+   if (!optval && !optlen) {
+   xfrm_sk_policy_insert(sk, XFRM_POLICY_IN, NULL);
+   xfrm_sk_policy_insert(sk, XFRM_POLICY_OUT, NULL);
+   __sk_dst_reset(sk);
+   return 0;
+   }
+
if (optlen <= 0 || optlen > PAGE_SIZE)
return -EMSGSIZE;
 
-- 
2.15.0.448.gf294e3d99a-goog