Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+67 -19
+9 -6
include/uapi/linux/xfrm.h
··· 213 213 XFRM_MSG_GETSPDINFO, 214 214 #define XFRM_MSG_GETSPDINFO XFRM_MSG_GETSPDINFO 215 215 216 + XFRM_MSG_MAPPING, 217 + #define XFRM_MSG_MAPPING XFRM_MSG_MAPPING 218 + 216 219 XFRM_MSG_SETDEFAULT, 217 220 #define XFRM_MSG_SETDEFAULT XFRM_MSG_SETDEFAULT 218 221 XFRM_MSG_GETDEFAULT, 219 222 #define XFRM_MSG_GETDEFAULT XFRM_MSG_GETDEFAULT 220 - 221 - XFRM_MSG_MAPPING, 222 - #define XFRM_MSG_MAPPING XFRM_MSG_MAPPING 223 223 __XFRM_MSG_MAX 224 224 }; 225 225 #define XFRM_MSG_MAX (__XFRM_MSG_MAX - 1) ··· 514 514 #define XFRM_OFFLOAD_INBOUND 2 515 515 516 516 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; 520 523 }; 521 524 522 525 #ifndef __KERNEL__
+55 -12
net/xfrm/xfrm_user.c
··· 1961 1961 return skb; 1962 1962 } 1963 1963 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 + 1964 1999 static int xfrm_set_default(struct sk_buff *skb, struct nlmsghdr *nlh, 1965 2000 struct nlattr **attrs) 1966 2001 { 1967 2002 struct net *net = sock_net(skb->sk); 1968 2003 struct xfrm_userpolicy_default *up = nlmsg_data(nlh); 1969 - u8 dirmask; 1970 - u8 old_default = net->xfrm.policy_default; 1971 2004 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; 1974 2009 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; 1976 2014 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; 1979 2019 1980 2020 rt_genid_bump_all(net); 1981 2021 2022 + xfrm_notify_userpolicy(net); 1982 2023 return 0; 1983 2024 } 1984 2025 ··· 2029 1988 struct sk_buff *r_skb; 2030 1989 struct nlmsghdr *r_nlh; 2031 1990 struct net *net = sock_net(skb->sk); 2032 - struct xfrm_userpolicy_default *r_up, *up; 1991 + struct xfrm_userpolicy_default *r_up; 2033 1992 int len = NLMSG_ALIGN(sizeof(struct xfrm_userpolicy_default)); 2034 1993 u32 portid = NETLINK_CB(skb).portid; 2035 1994 u32 seq = nlh->nlmsg_seq; 2036 - 2037 - up = nlmsg_data(nlh); 2038 1995 2039 1996 r_skb = nlmsg_new(len, GFP_ATOMIC); 2040 1997 if (!r_skb) ··· 2046 2007 2047 2008 r_up = nlmsg_data(r_nlh); 2048 2009 2049 - r_up->action = ((net->xfrm.policy_default & (1 << up->dirmask)) >> up->dirmask); 2050 - r_up->dirmask = up->dirmask; 2010 + r_up->in = net->xfrm.policy_default & XFRM_POL_DEFAULT_IN ? 2011 + XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT; 2012 + r_up->fwd = net->xfrm.policy_default & XFRM_POL_DEFAULT_FWD ? 2013 + XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT; 2014 + r_up->out = net->xfrm.policy_default & XFRM_POL_DEFAULT_OUT ? 2015 + XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT; 2051 2016 nlmsg_end(r_skb, r_nlh); 2052 2017 2053 2018 return nlmsg_unicast(net->xfrm.nlsk, r_skb, portid);
+3 -1
security/selinux/nlmsgtab.c
··· 126 126 { XFRM_MSG_NEWSPDINFO, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, 127 127 { XFRM_MSG_GETSPDINFO, NETLINK_XFRM_SOCKET__NLMSG_READ }, 128 128 { 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 }, 129 131 }; 130 132 131 133 static const struct nlmsg_perm nlmsg_audit_perms[] = ··· 191 189 * structures at the top of this file with the new mappings 192 190 * before updating the BUILD_BUG_ON() macro! 193 191 */ 194 - BUILD_BUG_ON(XFRM_MSG_MAX != XFRM_MSG_MAPPING); 192 + BUILD_BUG_ON(XFRM_MSG_MAX != XFRM_MSG_GETDEFAULT); 195 193 err = nlmsg_perm(nlmsg_type, perm, nlmsg_xfrm_perms, 196 194 sizeof(nlmsg_xfrm_perms)); 197 195 break;