Revert "xfrm: rework default policy structure"
This reverts commit 0d2e9d8000
which is
b58b1f563ab78955d37e9e43e02790a85c66ac05 commit upstream.
It breaks the Android kernel ABI and if this really needs to be added to
Android, it must come back in a format in the future that does not break
the abi.
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Change-Id: I0a8403a202b21cda7f856ea143c5b01b78346078
This commit is contained in:
@@ -66,7 +66,11 @@ struct netns_xfrm {
|
||||
int sysctl_larval_drop;
|
||||
u32 sysctl_acq_expires;
|
||||
|
||||
u8 policy_default[XFRM_POLICY_MAX];
|
||||
u8 policy_default;
|
||||
#define XFRM_POL_DEFAULT_IN 1
|
||||
#define XFRM_POL_DEFAULT_OUT 2
|
||||
#define XFRM_POL_DEFAULT_FWD 4
|
||||
#define XFRM_POL_DEFAULT_MASK 7
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
struct ctl_table_header *sysctl_hdr;
|
||||
|
@@ -1083,18 +1083,25 @@ xfrm_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x, un
|
||||
}
|
||||
|
||||
#ifdef CONFIG_XFRM
|
||||
int __xfrm_policy_check(struct sock *, int dir, struct sk_buff *skb,
|
||||
unsigned short family);
|
||||
|
||||
static inline bool __xfrm_check_nopolicy(struct net *net, struct sk_buff *skb,
|
||||
int dir)
|
||||
static inline bool
|
||||
xfrm_default_allow(struct net *net, int dir)
|
||||
{
|
||||
if (!net->xfrm.policy_count[dir] && !secpath_exists(skb))
|
||||
return net->xfrm.policy_default[dir] == XFRM_USERPOLICY_ACCEPT;
|
||||
u8 def = net->xfrm.policy_default;
|
||||
|
||||
switch (dir) {
|
||||
case XFRM_POLICY_IN:
|
||||
return def & XFRM_POL_DEFAULT_IN ? false : true;
|
||||
case XFRM_POLICY_OUT:
|
||||
return def & XFRM_POL_DEFAULT_OUT ? false : true;
|
||||
case XFRM_POLICY_FWD:
|
||||
return def & XFRM_POL_DEFAULT_FWD ? false : true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int __xfrm_policy_check(struct sock *, int dir, struct sk_buff *skb,
|
||||
unsigned short family);
|
||||
|
||||
static inline int __xfrm_policy_check2(struct sock *sk, int dir,
|
||||
struct sk_buff *skb,
|
||||
unsigned int family, int reverse)
|
||||
@@ -1105,9 +1112,13 @@ static inline int __xfrm_policy_check2(struct sock *sk, int dir,
|
||||
if (sk && sk->sk_policy[XFRM_POLICY_IN])
|
||||
return __xfrm_policy_check(sk, ndir, skb, family);
|
||||
|
||||
return __xfrm_check_nopolicy(net, skb, dir) ||
|
||||
if (xfrm_default_allow(net, dir))
|
||||
return (!net->xfrm.policy_count[dir] && !secpath_exists(skb)) ||
|
||||
(skb_dst(skb) && (skb_dst(skb)->flags & DST_NOPOLICY)) ||
|
||||
__xfrm_policy_check(sk, ndir, skb, family);
|
||||
else
|
||||
return (skb_dst(skb) && (skb_dst(skb)->flags & DST_NOPOLICY)) ||
|
||||
__xfrm_policy_check(sk, ndir, skb, family);
|
||||
}
|
||||
|
||||
static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
|
||||
@@ -1159,10 +1170,11 @@ static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family)
|
||||
{
|
||||
struct net *net = dev_net(skb->dev);
|
||||
|
||||
if (!net->xfrm.policy_count[XFRM_POLICY_OUT] &&
|
||||
net->xfrm.policy_default[XFRM_POLICY_OUT] == XFRM_USERPOLICY_ACCEPT)
|
||||
return true;
|
||||
|
||||
if (xfrm_default_allow(net, XFRM_POLICY_OUT))
|
||||
return !net->xfrm.policy_count[XFRM_POLICY_OUT] ||
|
||||
(skb_dst(skb)->flags & DST_NOXFRM) ||
|
||||
__xfrm_route_forward(skb, family);
|
||||
else
|
||||
return (skb_dst(skb)->flags & DST_NOXFRM) ||
|
||||
__xfrm_route_forward(skb, family);
|
||||
}
|
||||
|
@@ -3167,7 +3167,7 @@ ok:
|
||||
|
||||
nopol:
|
||||
if (!(dst_orig->dev->flags & IFF_LOOPBACK) &&
|
||||
net->xfrm.policy_default[dir] == XFRM_USERPOLICY_BLOCK) {
|
||||
!xfrm_default_allow(net, dir)) {
|
||||
err = -EPERM;
|
||||
goto error;
|
||||
}
|
||||
@@ -3618,7 +3618,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
|
||||
}
|
||||
|
||||
if (!pol) {
|
||||
if (net->xfrm.policy_default[dir] == XFRM_USERPOLICY_BLOCK) {
|
||||
if (!xfrm_default_allow(net, dir)) {
|
||||
XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOPOLS);
|
||||
return 0;
|
||||
}
|
||||
@@ -3678,8 +3678,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
|
||||
}
|
||||
xfrm_nr = ti;
|
||||
|
||||
if (net->xfrm.policy_default[dir] == XFRM_USERPOLICY_BLOCK &&
|
||||
!xfrm_nr) {
|
||||
if (!xfrm_default_allow(net, dir) && !xfrm_nr) {
|
||||
XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOSTATES);
|
||||
goto reject;
|
||||
}
|
||||
@@ -4167,9 +4166,6 @@ static int __net_init xfrm_net_init(struct net *net)
|
||||
spin_lock_init(&net->xfrm.xfrm_state_lock);
|
||||
spin_lock_init(&net->xfrm.xfrm_policy_lock);
|
||||
mutex_init(&net->xfrm.xfrm_cfg_mutex);
|
||||
net->xfrm.policy_default[XFRM_POLICY_IN] = XFRM_USERPOLICY_ACCEPT;
|
||||
net->xfrm.policy_default[XFRM_POLICY_FWD] = XFRM_USERPOLICY_ACCEPT;
|
||||
net->xfrm.policy_default[XFRM_POLICY_OUT] = XFRM_USERPOLICY_ACCEPT;
|
||||
|
||||
rv = xfrm_statistics_init(net);
|
||||
if (rv < 0)
|
||||
|
@@ -1919,35 +1919,38 @@ static int xfrm_notify_userpolicy(struct net *net)
|
||||
}
|
||||
|
||||
up = nlmsg_data(nlh);
|
||||
up->in = net->xfrm.policy_default[XFRM_POLICY_IN];
|
||||
up->fwd = net->xfrm.policy_default[XFRM_POLICY_FWD];
|
||||
up->out = net->xfrm.policy_default[XFRM_POLICY_OUT];
|
||||
up->in = net->xfrm.policy_default & XFRM_POL_DEFAULT_IN ?
|
||||
XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
|
||||
up->fwd = net->xfrm.policy_default & XFRM_POL_DEFAULT_FWD ?
|
||||
XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
|
||||
up->out = net->xfrm.policy_default & XFRM_POL_DEFAULT_OUT ?
|
||||
XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
|
||||
|
||||
nlmsg_end(skb, nlh);
|
||||
|
||||
return xfrm_nlmsg_multicast(net, skb, 0, XFRMNLGRP_POLICY);
|
||||
}
|
||||
|
||||
static bool xfrm_userpolicy_is_valid(__u8 policy)
|
||||
{
|
||||
return policy == XFRM_USERPOLICY_BLOCK ||
|
||||
policy == XFRM_USERPOLICY_ACCEPT;
|
||||
}
|
||||
|
||||
static int xfrm_set_default(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
struct nlattr **attrs)
|
||||
{
|
||||
struct net *net = sock_net(skb->sk);
|
||||
struct xfrm_userpolicy_default *up = nlmsg_data(nlh);
|
||||
|
||||
if (xfrm_userpolicy_is_valid(up->in))
|
||||
net->xfrm.policy_default[XFRM_POLICY_IN] = up->in;
|
||||
if (up->in == XFRM_USERPOLICY_BLOCK)
|
||||
net->xfrm.policy_default |= XFRM_POL_DEFAULT_IN;
|
||||
else if (up->in == XFRM_USERPOLICY_ACCEPT)
|
||||
net->xfrm.policy_default &= ~XFRM_POL_DEFAULT_IN;
|
||||
|
||||
if (xfrm_userpolicy_is_valid(up->fwd))
|
||||
net->xfrm.policy_default[XFRM_POLICY_FWD] = up->fwd;
|
||||
if (up->fwd == XFRM_USERPOLICY_BLOCK)
|
||||
net->xfrm.policy_default |= XFRM_POL_DEFAULT_FWD;
|
||||
else if (up->fwd == XFRM_USERPOLICY_ACCEPT)
|
||||
net->xfrm.policy_default &= ~XFRM_POL_DEFAULT_FWD;
|
||||
|
||||
if (xfrm_userpolicy_is_valid(up->out))
|
||||
net->xfrm.policy_default[XFRM_POLICY_OUT] = up->out;
|
||||
if (up->out == XFRM_USERPOLICY_BLOCK)
|
||||
net->xfrm.policy_default |= XFRM_POL_DEFAULT_OUT;
|
||||
else if (up->out == XFRM_USERPOLICY_ACCEPT)
|
||||
net->xfrm.policy_default &= ~XFRM_POL_DEFAULT_OUT;
|
||||
|
||||
rt_genid_bump_all(net);
|
||||
|
||||
@@ -1977,9 +1980,13 @@ static int xfrm_get_default(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
}
|
||||
|
||||
r_up = nlmsg_data(r_nlh);
|
||||
r_up->in = net->xfrm.policy_default[XFRM_POLICY_IN];
|
||||
r_up->fwd = net->xfrm.policy_default[XFRM_POLICY_FWD];
|
||||
r_up->out = net->xfrm.policy_default[XFRM_POLICY_OUT];
|
||||
|
||||
r_up->in = net->xfrm.policy_default & XFRM_POL_DEFAULT_IN ?
|
||||
XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
|
||||
r_up->fwd = net->xfrm.policy_default & XFRM_POL_DEFAULT_FWD ?
|
||||
XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
|
||||
r_up->out = net->xfrm.policy_default & XFRM_POL_DEFAULT_OUT ?
|
||||
XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
|
||||
nlmsg_end(r_skb, r_nlh);
|
||||
|
||||
return nlmsg_unicast(net->xfrm.nlsk, r_skb, portid);
|
||||
|
Reference in New Issue
Block a user