Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/
ipsec Steffen Klassert says: ==================== pull request (net): ipsec 2021-10-07 1) Fix a sysbot reported shift-out-of-bounds in xfrm_get_default. From Pavel Skripkin. 2) Fix XFRM_MSG_MAPPING ABI breakage. The new XFRM_MSG_MAPPING messages were accidentally not paced at the end. Fix by Eugene Syromiatnikov. 3) Fix the uapi for the default policy, use explicit field and macros and make it accessible to userland. From Nicolas Dichtel. 4) Fix a missing rcu lock in xfrm_notify_userpolicy(). From Nicolas Dichtel. Please pull or let me know if there are problems. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
578f393227
@ -213,13 +213,13 @@ enum {
|
||||
XFRM_MSG_GETSPDINFO,
|
||||
#define XFRM_MSG_GETSPDINFO XFRM_MSG_GETSPDINFO
|
||||
|
||||
XFRM_MSG_MAPPING,
|
||||
#define XFRM_MSG_MAPPING XFRM_MSG_MAPPING
|
||||
|
||||
XFRM_MSG_SETDEFAULT,
|
||||
#define XFRM_MSG_SETDEFAULT XFRM_MSG_SETDEFAULT
|
||||
XFRM_MSG_GETDEFAULT,
|
||||
#define XFRM_MSG_GETDEFAULT XFRM_MSG_GETDEFAULT
|
||||
|
||||
XFRM_MSG_MAPPING,
|
||||
#define XFRM_MSG_MAPPING XFRM_MSG_MAPPING
|
||||
__XFRM_MSG_MAX
|
||||
};
|
||||
#define XFRM_MSG_MAX (__XFRM_MSG_MAX - 1)
|
||||
@ -514,9 +514,12 @@ struct xfrm_user_offload {
|
||||
#define XFRM_OFFLOAD_INBOUND 2
|
||||
|
||||
struct xfrm_userpolicy_default {
|
||||
#define XFRM_USERPOLICY_DIRMASK_MAX (sizeof(__u8) * 8)
|
||||
__u8 dirmask;
|
||||
__u8 action;
|
||||
#define XFRM_USERPOLICY_UNSPEC 0
|
||||
#define XFRM_USERPOLICY_BLOCK 1
|
||||
#define XFRM_USERPOLICY_ACCEPT 2
|
||||
__u8 in;
|
||||
__u8 fwd;
|
||||
__u8 out;
|
||||
};
|
||||
|
||||
#ifndef __KERNEL__
|
||||
|
@ -1961,24 +1961,65 @@ static struct sk_buff *xfrm_policy_netlink(struct sk_buff *in_skb,
|
||||
return skb;
|
||||
}
|
||||
|
||||
static int xfrm_notify_userpolicy(struct net *net)
|
||||
{
|
||||
struct xfrm_userpolicy_default *up;
|
||||
int len = NLMSG_ALIGN(sizeof(*up));
|
||||
struct nlmsghdr *nlh;
|
||||
struct sk_buff *skb;
|
||||
int err;
|
||||
|
||||
skb = nlmsg_new(len, GFP_ATOMIC);
|
||||
if (skb == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
nlh = nlmsg_put(skb, 0, 0, XFRM_MSG_GETDEFAULT, sizeof(*up), 0);
|
||||
if (nlh == NULL) {
|
||||
kfree_skb(skb);
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
up = nlmsg_data(nlh);
|
||||
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);
|
||||
|
||||
rcu_read_lock();
|
||||
err = xfrm_nlmsg_multicast(net, skb, 0, XFRMNLGRP_POLICY);
|
||||
rcu_read_unlock();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
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);
|
||||
u8 dirmask;
|
||||
u8 old_default = net->xfrm.policy_default;
|
||||
|
||||
if (up->dirmask >= XFRM_USERPOLICY_DIRMASK_MAX)
|
||||
return -EINVAL;
|
||||
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;
|
||||
|
||||
dirmask = (1 << up->dirmask) & XFRM_POL_DEFAULT_MASK;
|
||||
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;
|
||||
|
||||
net->xfrm.policy_default = (old_default & (0xff ^ dirmask))
|
||||
| (up->action << up->dirmask);
|
||||
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);
|
||||
|
||||
xfrm_notify_userpolicy(net);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1988,13 +2029,11 @@ static int xfrm_get_default(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
struct sk_buff *r_skb;
|
||||
struct nlmsghdr *r_nlh;
|
||||
struct net *net = sock_net(skb->sk);
|
||||
struct xfrm_userpolicy_default *r_up, *up;
|
||||
struct xfrm_userpolicy_default *r_up;
|
||||
int len = NLMSG_ALIGN(sizeof(struct xfrm_userpolicy_default));
|
||||
u32 portid = NETLINK_CB(skb).portid;
|
||||
u32 seq = nlh->nlmsg_seq;
|
||||
|
||||
up = nlmsg_data(nlh);
|
||||
|
||||
r_skb = nlmsg_new(len, GFP_ATOMIC);
|
||||
if (!r_skb)
|
||||
return -ENOMEM;
|
||||
@ -2007,8 +2046,12 @@ static int xfrm_get_default(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
|
||||
r_up = nlmsg_data(r_nlh);
|
||||
|
||||
r_up->action = ((net->xfrm.policy_default & (1 << up->dirmask)) >> up->dirmask);
|
||||
r_up->dirmask = up->dirmask;
|
||||
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);
|
||||
|
@ -126,6 +126,8 @@ static const struct nlmsg_perm nlmsg_xfrm_perms[] =
|
||||
{ XFRM_MSG_NEWSPDINFO, NETLINK_XFRM_SOCKET__NLMSG_WRITE },
|
||||
{ XFRM_MSG_GETSPDINFO, NETLINK_XFRM_SOCKET__NLMSG_READ },
|
||||
{ XFRM_MSG_MAPPING, NETLINK_XFRM_SOCKET__NLMSG_READ },
|
||||
{ XFRM_MSG_SETDEFAULT, NETLINK_XFRM_SOCKET__NLMSG_WRITE },
|
||||
{ XFRM_MSG_GETDEFAULT, NETLINK_XFRM_SOCKET__NLMSG_READ },
|
||||
};
|
||||
|
||||
static const struct nlmsg_perm nlmsg_audit_perms[] =
|
||||
@ -189,7 +191,7 @@ int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm)
|
||||
* structures at the top of this file with the new mappings
|
||||
* before updating the BUILD_BUG_ON() macro!
|
||||
*/
|
||||
BUILD_BUG_ON(XFRM_MSG_MAX != XFRM_MSG_MAPPING);
|
||||
BUILD_BUG_ON(XFRM_MSG_MAX != XFRM_MSG_GETDEFAULT);
|
||||
err = nlmsg_perm(nlmsg_type, perm, nlmsg_xfrm_perms,
|
||||
sizeof(nlmsg_xfrm_perms));
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user