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-next

Steffen Klassert says:

====================
pull request (net-next): ipsec-next 2021-08-27

1) Remove an unneeded extra variable in esp4 esp_ssg_unref.
From Corey Minyard.

2) Add a configuration option to change the default behaviour
to block traffic if there is no matching policy.
Joint work with Christian Langrock and Antony Antony.

3) Fix a shift-out-of-bounce bug reported from syzbot.
From Pavel Skripkin.

Please pull or let me know if there are problems.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+122 -9
+7
include/net/netns/xfrm.h
··· 65 65 u32 sysctl_aevent_rseqth; 66 66 int sysctl_larval_drop; 67 67 u32 sysctl_acq_expires; 68 + 69 + u8 policy_default; 70 + #define XFRM_POL_DEFAULT_IN 1 71 + #define XFRM_POL_DEFAULT_OUT 2 72 + #define XFRM_POL_DEFAULT_FWD 4 73 + #define XFRM_POL_DEFAULT_MASK 7 74 + 68 75 #ifdef CONFIG_SYSCTL 69 76 struct ctl_table_header *sysctl_hdr; 70 77 #endif
+30 -6
include/net/xfrm.h
··· 1075 1075 } 1076 1076 1077 1077 #ifdef CONFIG_XFRM 1078 + static inline bool 1079 + xfrm_default_allow(struct net *net, int dir) 1080 + { 1081 + u8 def = net->xfrm.policy_default; 1082 + 1083 + switch (dir) { 1084 + case XFRM_POLICY_IN: 1085 + return def & XFRM_POL_DEFAULT_IN ? false : true; 1086 + case XFRM_POLICY_OUT: 1087 + return def & XFRM_POL_DEFAULT_OUT ? false : true; 1088 + case XFRM_POLICY_FWD: 1089 + return def & XFRM_POL_DEFAULT_FWD ? false : true; 1090 + } 1091 + return false; 1092 + } 1093 + 1078 1094 int __xfrm_policy_check(struct sock *, int dir, struct sk_buff *skb, 1079 1095 unsigned short family); 1080 1096 ··· 1104 1088 if (sk && sk->sk_policy[XFRM_POLICY_IN]) 1105 1089 return __xfrm_policy_check(sk, ndir, skb, family); 1106 1090 1107 - return (!net->xfrm.policy_count[dir] && !secpath_exists(skb)) || 1108 - (skb_dst(skb) && (skb_dst(skb)->flags & DST_NOPOLICY)) || 1109 - __xfrm_policy_check(sk, ndir, skb, family); 1091 + if (xfrm_default_allow(net, dir)) 1092 + return (!net->xfrm.policy_count[dir] && !secpath_exists(skb)) || 1093 + (skb_dst(skb) && (skb_dst(skb)->flags & DST_NOPOLICY)) || 1094 + __xfrm_policy_check(sk, ndir, skb, family); 1095 + else 1096 + return (skb_dst(skb) && (skb_dst(skb)->flags & DST_NOPOLICY)) || 1097 + __xfrm_policy_check(sk, ndir, skb, family); 1110 1098 } 1111 1099 1112 1100 static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family) ··· 1162 1142 { 1163 1143 struct net *net = dev_net(skb->dev); 1164 1144 1165 - return !net->xfrm.policy_count[XFRM_POLICY_OUT] || 1166 - (skb_dst(skb)->flags & DST_NOXFRM) || 1167 - __xfrm_route_forward(skb, family); 1145 + if (xfrm_default_allow(net, XFRM_POLICY_FWD)) 1146 + return !net->xfrm.policy_count[XFRM_POLICY_OUT] || 1147 + (skb_dst(skb)->flags & DST_NOXFRM) || 1148 + __xfrm_route_forward(skb, family); 1149 + else 1150 + return (skb_dst(skb)->flags & DST_NOXFRM) || 1151 + __xfrm_route_forward(skb, family); 1168 1152 } 1169 1153 1170 1154 static inline int xfrm4_route_forward(struct sk_buff *skb)
+11
include/uapi/linux/xfrm.h
··· 213 213 XFRM_MSG_GETSPDINFO, 214 214 #define XFRM_MSG_GETSPDINFO XFRM_MSG_GETSPDINFO 215 215 216 + XFRM_MSG_SETDEFAULT, 217 + #define XFRM_MSG_SETDEFAULT XFRM_MSG_SETDEFAULT 218 + XFRM_MSG_GETDEFAULT, 219 + #define XFRM_MSG_GETDEFAULT XFRM_MSG_GETDEFAULT 220 + 216 221 XFRM_MSG_MAPPING, 217 222 #define XFRM_MSG_MAPPING XFRM_MSG_MAPPING 218 223 __XFRM_MSG_MAX ··· 512 507 }; 513 508 #define XFRM_OFFLOAD_IPV6 1 514 509 #define XFRM_OFFLOAD_INBOUND 2 510 + 511 + struct xfrm_userpolicy_default { 512 + #define XFRM_USERPOLICY_DIRMASK_MAX (sizeof(__u8) * 8) 513 + __u8 dirmask; 514 + __u8 action; 515 + }; 515 516 516 517 #ifndef __KERNEL__ 517 518 /* backwards compatibility for userspace */
+1 -3
net/ipv4/esp4.c
··· 97 97 98 98 static void esp_ssg_unref(struct xfrm_state *x, void *tmp) 99 99 { 100 - struct esp_output_extra *extra = esp_tmp_extra(tmp); 101 100 struct crypto_aead *aead = x->data; 102 101 int extralen = 0; 103 102 u8 *iv; ··· 104 105 struct scatterlist *sg; 105 106 106 107 if (x->props.flags & XFRM_STATE_ESN) 107 - extralen += sizeof(*extra); 108 + extralen += sizeof(struct esp_output_extra); 108 109 109 - extra = esp_tmp_extra(tmp); 110 110 iv = esp_tmp_iv(aead, tmp, extralen); 111 111 req = esp_tmp_req(aead, iv); 112 112
+16
net/xfrm/xfrm_policy.c
··· 3157 3157 return dst; 3158 3158 3159 3159 nopol: 3160 + if (!(dst_orig->dev->flags & IFF_LOOPBACK) && 3161 + !xfrm_default_allow(net, dir)) { 3162 + err = -EPERM; 3163 + goto error; 3164 + } 3160 3165 if (!(flags & XFRM_LOOKUP_ICMP)) { 3161 3166 dst = dst_orig; 3162 3167 goto ok; ··· 3550 3545 } 3551 3546 3552 3547 if (!pol) { 3548 + if (!xfrm_default_allow(net, dir)) { 3549 + XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOPOLS); 3550 + return 0; 3551 + } 3552 + 3553 3553 if (sp && secpath_has_nontransport(sp, 0, &xerr_idx)) { 3554 3554 xfrm_secpath_reject(xerr_idx, skb, &fl); 3555 3555 XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOPOLS); ··· 3609 3599 tpp[ti++] = &pols[pi]->xfrm_vec[i]; 3610 3600 } 3611 3601 xfrm_nr = ti; 3602 + 3603 + if (!xfrm_default_allow(net, dir) && !xfrm_nr) { 3604 + XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOSTATES); 3605 + goto reject; 3606 + } 3607 + 3612 3608 if (npols > 1) { 3613 3609 xfrm_tmpl_sort(stp, tpp, xfrm_nr, family); 3614 3610 tpp = stp;
+57
net/xfrm/xfrm_user.c
··· 1961 1961 return skb; 1962 1962 } 1963 1963 1964 + static int xfrm_set_default(struct sk_buff *skb, struct nlmsghdr *nlh, 1965 + struct nlattr **attrs) 1966 + { 1967 + struct net *net = sock_net(skb->sk); 1968 + struct xfrm_userpolicy_default *up = nlmsg_data(nlh); 1969 + u8 dirmask; 1970 + u8 old_default = net->xfrm.policy_default; 1971 + 1972 + if (up->dirmask >= XFRM_USERPOLICY_DIRMASK_MAX) 1973 + return -EINVAL; 1974 + 1975 + dirmask = (1 << up->dirmask) & XFRM_POL_DEFAULT_MASK; 1976 + 1977 + net->xfrm.policy_default = (old_default & (0xff ^ dirmask)) 1978 + | (up->action << up->dirmask); 1979 + 1980 + rt_genid_bump_all(net); 1981 + 1982 + return 0; 1983 + } 1984 + 1985 + static int xfrm_get_default(struct sk_buff *skb, struct nlmsghdr *nlh, 1986 + struct nlattr **attrs) 1987 + { 1988 + struct sk_buff *r_skb; 1989 + struct nlmsghdr *r_nlh; 1990 + struct net *net = sock_net(skb->sk); 1991 + struct xfrm_userpolicy_default *r_up, *up; 1992 + int len = NLMSG_ALIGN(sizeof(struct xfrm_userpolicy_default)); 1993 + u32 portid = NETLINK_CB(skb).portid; 1994 + u32 seq = nlh->nlmsg_seq; 1995 + 1996 + up = nlmsg_data(nlh); 1997 + 1998 + r_skb = nlmsg_new(len, GFP_ATOMIC); 1999 + if (!r_skb) 2000 + return -ENOMEM; 2001 + 2002 + r_nlh = nlmsg_put(r_skb, portid, seq, XFRM_MSG_GETDEFAULT, sizeof(*r_up), 0); 2003 + if (!r_nlh) { 2004 + kfree_skb(r_skb); 2005 + return -EMSGSIZE; 2006 + } 2007 + 2008 + r_up = nlmsg_data(r_nlh); 2009 + 2010 + r_up->action = ((net->xfrm.policy_default & (1 << up->dirmask)) >> up->dirmask); 2011 + r_up->dirmask = up->dirmask; 2012 + nlmsg_end(r_skb, r_nlh); 2013 + 2014 + return nlmsg_unicast(net->xfrm.nlsk, r_skb, portid); 2015 + } 2016 + 1964 2017 static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, 1965 2018 struct nlattr **attrs) 1966 2019 { ··· 2717 2664 [XFRM_MSG_GETSADINFO - XFRM_MSG_BASE] = sizeof(u32), 2718 2665 [XFRM_MSG_NEWSPDINFO - XFRM_MSG_BASE] = sizeof(u32), 2719 2666 [XFRM_MSG_GETSPDINFO - XFRM_MSG_BASE] = sizeof(u32), 2667 + [XFRM_MSG_SETDEFAULT - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_default), 2668 + [XFRM_MSG_GETDEFAULT - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_default), 2720 2669 }; 2721 2670 EXPORT_SYMBOL_GPL(xfrm_msg_min); 2722 2671 ··· 2798 2743 .nla_pol = xfrma_spd_policy, 2799 2744 .nla_max = XFRMA_SPD_MAX }, 2800 2745 [XFRM_MSG_GETSPDINFO - XFRM_MSG_BASE] = { .doit = xfrm_get_spdinfo }, 2746 + [XFRM_MSG_SETDEFAULT - XFRM_MSG_BASE] = { .doit = xfrm_set_default }, 2747 + [XFRM_MSG_GETDEFAULT - XFRM_MSG_BASE] = { .doit = xfrm_get_default }, 2801 2748 }; 2802 2749 2803 2750 static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,