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 2015-10-30

1) The flow cache is limited by the flow cache limit which
depends on the number of cpus and the xfrm garbage collector
threshold which is independent of the number of cpus. This
leads to the fact that on systems with more than 16 cpus
we hit the xfrm garbage collector limit and refuse new
allocations, so new flows are dropped. On systems with 16
or less cpus, we hit the flowcache limit. In this case, we
shrink the flow cache instead of refusing new flows.

We increase the xfrm garbage collector threshold to INT_MAX
to get the same behaviour, independent of the number of cpus.

2) Fix some unaligned accesses on sparc systems.
From Sowmini Varadhan.

3) Fix some header checks in _decode_session4. We may call
pskb_may_pull with a negative value converted to unsigened
int from pskb_may_pull. This can lead to incorrect policy
lookups. We fix this by a check of the data pointer position
before we call pskb_may_pull.

4) Reload skb header pointers after calling pskb_may_pull
in _decode_session4 as this may change the pointers into
the packet.

5) Add a missing statistic counter on inner mode errors.

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

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

+49 -18
+4 -2
Documentation/networking/ip-sysctl.txt
··· 1216 1216 xfrm4_gc_thresh - INTEGER 1217 1217 The threshold at which we will start garbage collecting for IPv4 1218 1218 destination cache entries. At twice this value the system will 1219 - refuse new allocations. 1219 + refuse new allocations. The value must be set below the flowcache 1220 + limit (4096 * number of online cpus) to take effect. 1220 1221 1221 1222 igmp_link_local_mcast_reports - BOOLEAN 1222 1223 Enable IGMP reports for link local multicast groups in the ··· 1663 1662 xfrm6_gc_thresh - INTEGER 1664 1663 The threshold at which we will start garbage collecting for IPv6 1665 1664 destination cache entries. At twice this value the system will 1666 - refuse new allocations. 1665 + refuse new allocations. The value must be set below the flowcache 1666 + limit (4096 * number of online cpus) to take effect. 1667 1667 1668 1668 1669 1669 IPv6 Update by:
+37 -13
net/ipv4/xfrm4_policy.c
··· 127 127 case IPPROTO_DCCP: 128 128 if (xprth + 4 < skb->data || 129 129 pskb_may_pull(skb, xprth + 4 - skb->data)) { 130 - __be16 *ports = (__be16 *)xprth; 130 + __be16 *ports; 131 + 132 + xprth = skb_network_header(skb) + iph->ihl * 4; 133 + ports = (__be16 *)xprth; 131 134 132 135 fl4->fl4_sport = ports[!!reverse]; 133 136 fl4->fl4_dport = ports[!reverse]; ··· 138 135 break; 139 136 140 137 case IPPROTO_ICMP: 141 - if (pskb_may_pull(skb, xprth + 2 - skb->data)) { 142 - u8 *icmp = xprth; 138 + if (xprth + 2 < skb->data || 139 + pskb_may_pull(skb, xprth + 2 - skb->data)) { 140 + u8 *icmp; 141 + 142 + xprth = skb_network_header(skb) + iph->ihl * 4; 143 + icmp = xprth; 143 144 144 145 fl4->fl4_icmp_type = icmp[0]; 145 146 fl4->fl4_icmp_code = icmp[1]; ··· 151 144 break; 152 145 153 146 case IPPROTO_ESP: 154 - if (pskb_may_pull(skb, xprth + 4 - skb->data)) { 155 - __be32 *ehdr = (__be32 *)xprth; 147 + if (xprth + 4 < skb->data || 148 + pskb_may_pull(skb, xprth + 4 - skb->data)) { 149 + __be32 *ehdr; 150 + 151 + xprth = skb_network_header(skb) + iph->ihl * 4; 152 + ehdr = (__be32 *)xprth; 156 153 157 154 fl4->fl4_ipsec_spi = ehdr[0]; 158 155 } 159 156 break; 160 157 161 158 case IPPROTO_AH: 162 - if (pskb_may_pull(skb, xprth + 8 - skb->data)) { 163 - __be32 *ah_hdr = (__be32 *)xprth; 159 + if (xprth + 8 < skb->data || 160 + pskb_may_pull(skb, xprth + 8 - skb->data)) { 161 + __be32 *ah_hdr; 162 + 163 + xprth = skb_network_header(skb) + iph->ihl * 4; 164 + ah_hdr = (__be32 *)xprth; 164 165 165 166 fl4->fl4_ipsec_spi = ah_hdr[1]; 166 167 } 167 168 break; 168 169 169 170 case IPPROTO_COMP: 170 - if (pskb_may_pull(skb, xprth + 4 - skb->data)) { 171 - __be16 *ipcomp_hdr = (__be16 *)xprth; 171 + if (xprth + 4 < skb->data || 172 + pskb_may_pull(skb, xprth + 4 - skb->data)) { 173 + __be16 *ipcomp_hdr; 174 + 175 + xprth = skb_network_header(skb) + iph->ihl * 4; 176 + ipcomp_hdr = (__be16 *)xprth; 172 177 173 178 fl4->fl4_ipsec_spi = htonl(ntohs(ipcomp_hdr[1])); 174 179 } 175 180 break; 176 181 177 182 case IPPROTO_GRE: 178 - if (pskb_may_pull(skb, xprth + 12 - skb->data)) { 179 - __be16 *greflags = (__be16 *)xprth; 180 - __be32 *gre_hdr = (__be32 *)xprth; 183 + if (xprth + 12 < skb->data || 184 + pskb_may_pull(skb, xprth + 12 - skb->data)) { 185 + __be16 *greflags; 186 + __be32 *gre_hdr; 187 + 188 + xprth = skb_network_header(skb) + iph->ihl * 4; 189 + greflags = (__be16 *)xprth; 190 + gre_hdr = (__be32 *)xprth; 181 191 182 192 if (greflags[0] & GRE_KEY) { 183 193 if (greflags[0] & GRE_CSUM) ··· 268 244 .destroy = xfrm4_dst_destroy, 269 245 .ifdown = xfrm4_dst_ifdown, 270 246 .local_out = __ip_local_out, 271 - .gc_thresh = 32768, 247 + .gc_thresh = INT_MAX, 272 248 }; 273 249 274 250 static struct xfrm_policy_afinfo xfrm4_policy_afinfo = {
+1 -1
net/ipv6/xfrm6_policy.c
··· 288 288 .destroy = xfrm6_dst_destroy, 289 289 .ifdown = xfrm6_dst_ifdown, 290 290 .local_out = __ip6_local_out, 291 - .gc_thresh = 32768, 291 + .gc_thresh = INT_MAX, 292 292 }; 293 293 294 294 static struct xfrm_policy_afinfo xfrm6_policy_afinfo = {
+3 -1
net/xfrm/xfrm_input.c
··· 330 330 331 331 if (x->sel.family == AF_UNSPEC) { 332 332 inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol); 333 - if (inner_mode == NULL) 333 + if (inner_mode == NULL) { 334 + XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEMODEERROR); 334 335 goto drop; 336 + } 335 337 } 336 338 337 339 if (inner_mode->input(x, skb)) {
+4 -1
net/xfrm/xfrm_user.c
··· 31 31 #if IS_ENABLED(CONFIG_IPV6) 32 32 #include <linux/in6.h> 33 33 #endif 34 + #include <asm/unaligned.h> 34 35 35 36 static int verify_one_alg(struct nlattr **attrs, enum xfrm_attr_type_t type) 36 37 { ··· 729 728 memcpy(&p->sel, &x->sel, sizeof(p->sel)); 730 729 memcpy(&p->lft, &x->lft, sizeof(p->lft)); 731 730 memcpy(&p->curlft, &x->curlft, sizeof(p->curlft)); 732 - memcpy(&p->stats, &x->stats, sizeof(p->stats)); 731 + put_unaligned(x->stats.replay_window, &p->stats.replay_window); 732 + put_unaligned(x->stats.replay, &p->stats.replay); 733 + put_unaligned(x->stats.integrity_failed, &p->stats.integrity_failed); 733 734 memcpy(&p->saddr, &x->props.saddr, sizeof(p->saddr)); 734 735 p->mode = x->props.mode; 735 736 p->replay_window = x->props.replay_window;