Skip to content

Commit 578f393

Browse files
committed
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 <[email protected]>
2 parents 65f280b + 93ec132 commit 578f393

File tree

3 files changed

+67
-19
lines changed

3 files changed

+67
-19
lines changed

include/uapi/linux/xfrm.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -213,13 +213,13 @@ enum {
213213
XFRM_MSG_GETSPDINFO,
214214
#define XFRM_MSG_GETSPDINFO XFRM_MSG_GETSPDINFO
215215

216+
XFRM_MSG_MAPPING,
217+
#define XFRM_MSG_MAPPING XFRM_MSG_MAPPING
218+
216219
XFRM_MSG_SETDEFAULT,
217220
#define XFRM_MSG_SETDEFAULT XFRM_MSG_SETDEFAULT
218221
XFRM_MSG_GETDEFAULT,
219222
#define XFRM_MSG_GETDEFAULT XFRM_MSG_GETDEFAULT
220-
221-
XFRM_MSG_MAPPING,
222-
#define XFRM_MSG_MAPPING XFRM_MSG_MAPPING
223223
__XFRM_MSG_MAX
224224
};
225225
#define XFRM_MSG_MAX (__XFRM_MSG_MAX - 1)
@@ -514,9 +514,12 @@ struct xfrm_user_offload {
514514
#define XFRM_OFFLOAD_INBOUND 2
515515

516516
struct xfrm_userpolicy_default {
517-
#define XFRM_USERPOLICY_DIRMASK_MAX (sizeof(__u8) * 8)
518-
__u8 dirmask;
519-
__u8 action;
517+
#define XFRM_USERPOLICY_UNSPEC 0
518+
#define XFRM_USERPOLICY_BLOCK 1
519+
#define XFRM_USERPOLICY_ACCEPT 2
520+
__u8 in;
521+
__u8 fwd;
522+
__u8 out;
520523
};
521524

522525
#ifndef __KERNEL__

net/xfrm/xfrm_user.c

Lines changed: 55 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1961,24 +1961,65 @@ static struct sk_buff *xfrm_policy_netlink(struct sk_buff *in_skb,
19611961
return skb;
19621962
}
19631963

1964+
static int xfrm_notify_userpolicy(struct net *net)
1965+
{
1966+
struct xfrm_userpolicy_default *up;
1967+
int len = NLMSG_ALIGN(sizeof(*up));
1968+
struct nlmsghdr *nlh;
1969+
struct sk_buff *skb;
1970+
int err;
1971+
1972+
skb = nlmsg_new(len, GFP_ATOMIC);
1973+
if (skb == NULL)
1974+
return -ENOMEM;
1975+
1976+
nlh = nlmsg_put(skb, 0, 0, XFRM_MSG_GETDEFAULT, sizeof(*up), 0);
1977+
if (nlh == NULL) {
1978+
kfree_skb(skb);
1979+
return -EMSGSIZE;
1980+
}
1981+
1982+
up = nlmsg_data(nlh);
1983+
up->in = net->xfrm.policy_default & XFRM_POL_DEFAULT_IN ?
1984+
XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
1985+
up->fwd = net->xfrm.policy_default & XFRM_POL_DEFAULT_FWD ?
1986+
XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
1987+
up->out = net->xfrm.policy_default & XFRM_POL_DEFAULT_OUT ?
1988+
XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
1989+
1990+
nlmsg_end(skb, nlh);
1991+
1992+
rcu_read_lock();
1993+
err = xfrm_nlmsg_multicast(net, skb, 0, XFRMNLGRP_POLICY);
1994+
rcu_read_unlock();
1995+
1996+
return err;
1997+
}
1998+
19641999
static int xfrm_set_default(struct sk_buff *skb, struct nlmsghdr *nlh,
19652000
struct nlattr **attrs)
19662001
{
19672002
struct net *net = sock_net(skb->sk);
19682003
struct xfrm_userpolicy_default *up = nlmsg_data(nlh);
1969-
u8 dirmask;
1970-
u8 old_default = net->xfrm.policy_default;
19712004

1972-
if (up->dirmask >= XFRM_USERPOLICY_DIRMASK_MAX)
1973-
return -EINVAL;
2005+
if (up->in == XFRM_USERPOLICY_BLOCK)
2006+
net->xfrm.policy_default |= XFRM_POL_DEFAULT_IN;
2007+
else if (up->in == XFRM_USERPOLICY_ACCEPT)
2008+
net->xfrm.policy_default &= ~XFRM_POL_DEFAULT_IN;
19742009

1975-
dirmask = (1 << up->dirmask) & XFRM_POL_DEFAULT_MASK;
2010+
if (up->fwd == XFRM_USERPOLICY_BLOCK)
2011+
net->xfrm.policy_default |= XFRM_POL_DEFAULT_FWD;
2012+
else if (up->fwd == XFRM_USERPOLICY_ACCEPT)
2013+
net->xfrm.policy_default &= ~XFRM_POL_DEFAULT_FWD;
19762014

1977-
net->xfrm.policy_default = (old_default & (0xff ^ dirmask))
1978-
| (up->action << up->dirmask);
2015+
if (up->out == XFRM_USERPOLICY_BLOCK)
2016+
net->xfrm.policy_default |= XFRM_POL_DEFAULT_OUT;
2017+
else if (up->out == XFRM_USERPOLICY_ACCEPT)
2018+
net->xfrm.policy_default &= ~XFRM_POL_DEFAULT_OUT;
19792019

19802020
rt_genid_bump_all(net);
19812021

2022+
xfrm_notify_userpolicy(net);
19822023
return 0;
19832024
}
19842025

@@ -1988,13 +2029,11 @@ static int xfrm_get_default(struct sk_buff *skb, struct nlmsghdr *nlh,
19882029
struct sk_buff *r_skb;
19892030
struct nlmsghdr *r_nlh;
19902031
struct net *net = sock_net(skb->sk);
1991-
struct xfrm_userpolicy_default *r_up, *up;
2032+
struct xfrm_userpolicy_default *r_up;
19922033
int len = NLMSG_ALIGN(sizeof(struct xfrm_userpolicy_default));
19932034
u32 portid = NETLINK_CB(skb).portid;
19942035
u32 seq = nlh->nlmsg_seq;
19952036

1996-
up = nlmsg_data(nlh);
1997-
19982037
r_skb = nlmsg_new(len, GFP_ATOMIC);
19992038
if (!r_skb)
20002039
return -ENOMEM;
@@ -2007,8 +2046,12 @@ static int xfrm_get_default(struct sk_buff *skb, struct nlmsghdr *nlh,
20072046

20082047
r_up = nlmsg_data(r_nlh);
20092048

2010-
r_up->action = ((net->xfrm.policy_default & (1 << up->dirmask)) >> up->dirmask);
2011-
r_up->dirmask = up->dirmask;
2049+
r_up->in = net->xfrm.policy_default & XFRM_POL_DEFAULT_IN ?
2050+
XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
2051+
r_up->fwd = net->xfrm.policy_default & XFRM_POL_DEFAULT_FWD ?
2052+
XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
2053+
r_up->out = net->xfrm.policy_default & XFRM_POL_DEFAULT_OUT ?
2054+
XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
20122055
nlmsg_end(r_skb, r_nlh);
20132056

20142057
return nlmsg_unicast(net->xfrm.nlsk, r_skb, portid);

security/selinux/nlmsgtab.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ static const struct nlmsg_perm nlmsg_xfrm_perms[] =
126126
{ XFRM_MSG_NEWSPDINFO, NETLINK_XFRM_SOCKET__NLMSG_WRITE },
127127
{ XFRM_MSG_GETSPDINFO, NETLINK_XFRM_SOCKET__NLMSG_READ },
128128
{ XFRM_MSG_MAPPING, NETLINK_XFRM_SOCKET__NLMSG_READ },
129+
{ XFRM_MSG_SETDEFAULT, NETLINK_XFRM_SOCKET__NLMSG_WRITE },
130+
{ XFRM_MSG_GETDEFAULT, NETLINK_XFRM_SOCKET__NLMSG_READ },
129131
};
130132

131133
static const struct nlmsg_perm nlmsg_audit_perms[] =
@@ -189,7 +191,7 @@ int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm)
189191
* structures at the top of this file with the new mappings
190192
* before updating the BUILD_BUG_ON() macro!
191193
*/
192-
BUILD_BUG_ON(XFRM_MSG_MAX != XFRM_MSG_MAPPING);
194+
BUILD_BUG_ON(XFRM_MSG_MAX != XFRM_MSG_GETDEFAULT);
193195
err = nlmsg_perm(nlmsg_type, perm, nlmsg_xfrm_perms,
194196
sizeof(nlmsg_xfrm_perms));
195197
break;

0 commit comments

Comments
 (0)