aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-07-30 16:25:49 -0400
committerDavid S. Miller <davem@davemloft.net>2014-07-30 16:25:49 -0400
commitf139c74a8df071217dcd63f3ef06ae7be7071c4d (patch)
tree5711f695577a18a06dbcd0101956e97b388ffa1a /net
parentbd695a5f0ccf7b38982c426d86055ff3591c9b5b (diff)
parent26bcd8b72563b4c54892c4c2a409f6656fb8ae8b (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/compat.c9
-rw-r--r--net/core/iovec.c6
-rw-r--r--net/core/neighbour.c2
-rw-r--r--net/ipv4/route.c32
-rw-r--r--net/ipv6/ip6_output.c2
-rw-r--r--net/netfilter/ipvs/ip_vs_conn.c1
-rw-r--r--net/sctp/associola.c1
-rw-r--r--net/xfrm/xfrm_policy.c2
-rw-r--r--net/xfrm/xfrm_user.c7
9 files changed, 46 insertions, 16 deletions
diff --git a/net/compat.c b/net/compat.c
index 9a76eaf63184..bc8aeefddf3f 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -85,7 +85,7 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov,
85{ 85{
86 int tot_len; 86 int tot_len;
87 87
88 if (kern_msg->msg_namelen) { 88 if (kern_msg->msg_name && kern_msg->msg_namelen) {
89 if (mode == VERIFY_READ) { 89 if (mode == VERIFY_READ) {
90 int err = move_addr_to_kernel(kern_msg->msg_name, 90 int err = move_addr_to_kernel(kern_msg->msg_name,
91 kern_msg->msg_namelen, 91 kern_msg->msg_namelen,
@@ -93,10 +93,11 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov,
93 if (err < 0) 93 if (err < 0)
94 return err; 94 return err;
95 } 95 }
96 if (kern_msg->msg_name) 96 kern_msg->msg_name = kern_address;
97 kern_msg->msg_name = kern_address; 97 } else {
98 } else
99 kern_msg->msg_name = NULL; 98 kern_msg->msg_name = NULL;
99 kern_msg->msg_namelen = 0;
100 }
100 101
101 tot_len = iov_from_user_compat_to_kern(kern_iov, 102 tot_len = iov_from_user_compat_to_kern(kern_iov,
102 (struct compat_iovec __user *)kern_msg->msg_iov, 103 (struct compat_iovec __user *)kern_msg->msg_iov,
diff --git a/net/core/iovec.c b/net/core/iovec.c
index 827dd6beb49c..e1ec45ab1e63 100644
--- a/net/core/iovec.c
+++ b/net/core/iovec.c
@@ -39,7 +39,7 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr_storage *a
39{ 39{
40 int size, ct, err; 40 int size, ct, err;
41 41
42 if (m->msg_namelen) { 42 if (m->msg_name && m->msg_namelen) {
43 if (mode == VERIFY_READ) { 43 if (mode == VERIFY_READ) {
44 void __user *namep; 44 void __user *namep;
45 namep = (void __user __force *) m->msg_name; 45 namep = (void __user __force *) m->msg_name;
@@ -48,10 +48,10 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr_storage *a
48 if (err < 0) 48 if (err < 0)
49 return err; 49 return err;
50 } 50 }
51 if (m->msg_name) 51 m->msg_name = address;
52 m->msg_name = address;
53 } else { 52 } else {
54 m->msg_name = NULL; 53 m->msg_name = NULL;
54 m->msg_namelen = 0;
55 } 55 }
56 56
57 size = m->msg_iovlen * sizeof(struct iovec); 57 size = m->msg_iovlen * sizeof(struct iovec);
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 559890b0f0a2..ef31fef25e5a 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -2249,7 +2249,7 @@ static int pneigh_fill_info(struct sk_buff *skb, struct pneigh_entry *pn,
2249 ndm->ndm_pad1 = 0; 2249 ndm->ndm_pad1 = 0;
2250 ndm->ndm_pad2 = 0; 2250 ndm->ndm_pad2 = 0;
2251 ndm->ndm_flags = pn->flags | NTF_PROXY; 2251 ndm->ndm_flags = pn->flags | NTF_PROXY;
2252 ndm->ndm_type = NDA_DST; 2252 ndm->ndm_type = RTN_UNICAST;
2253 ndm->ndm_ifindex = pn->dev->ifindex; 2253 ndm->ndm_ifindex = pn->dev->ifindex;
2254 ndm->ndm_state = NUD_NONE; 2254 ndm->ndm_state = NUD_NONE;
2255 2255
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 3162ea923ded..190199851c9a 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -457,8 +457,31 @@ static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst,
457 return neigh_create(&arp_tbl, pkey, dev); 457 return neigh_create(&arp_tbl, pkey, dev);
458} 458}
459 459
460atomic_t *ip_idents __read_mostly; 460#define IP_IDENTS_SZ 2048u
461EXPORT_SYMBOL(ip_idents); 461struct ip_ident_bucket {
462 atomic_t id;
463 u32 stamp32;
464};
465
466static struct ip_ident_bucket *ip_idents __read_mostly;
467
468/* In order to protect privacy, we add a perturbation to identifiers
469 * if one generator is seldom used. This makes hard for an attacker
470 * to infer how many packets were sent between two points in time.
471 */
472u32 ip_idents_reserve(u32 hash, int segs)
473{
474 struct ip_ident_bucket *bucket = ip_idents + hash % IP_IDENTS_SZ;
475 u32 old = ACCESS_ONCE(bucket->stamp32);
476 u32 now = (u32)jiffies;
477 u32 delta = 0;
478
479 if (old != now && cmpxchg(&bucket->stamp32, old, now) == old)
480 delta = prandom_u32_max(now - old);
481
482 return atomic_add_return(segs + delta, &bucket->id) - segs;
483}
484EXPORT_SYMBOL(ip_idents_reserve);
462 485
463void __ip_select_ident(struct iphdr *iph, int segs) 486void __ip_select_ident(struct iphdr *iph, int segs)
464{ 487{
@@ -467,7 +490,10 @@ void __ip_select_ident(struct iphdr *iph, int segs)
467 490
468 net_get_random_once(&ip_idents_hashrnd, sizeof(ip_idents_hashrnd)); 491 net_get_random_once(&ip_idents_hashrnd, sizeof(ip_idents_hashrnd));
469 492
470 hash = jhash_1word((__force u32)iph->daddr, ip_idents_hashrnd); 493 hash = jhash_3words((__force u32)iph->daddr,
494 (__force u32)iph->saddr,
495 iph->protocol,
496 ip_idents_hashrnd);
471 id = ip_idents_reserve(hash, segs); 497 id = ip_idents_reserve(hash, segs);
472 iph->id = htons(id); 498 iph->id = htons(id);
473} 499}
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 2e339d241b69..f5dafe609f8b 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -546,6 +546,8 @@ static void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt)
546 net_get_random_once(&ip6_idents_hashrnd, sizeof(ip6_idents_hashrnd)); 546 net_get_random_once(&ip6_idents_hashrnd, sizeof(ip6_idents_hashrnd));
547 547
548 hash = __ipv6_addr_jhash(&rt->rt6i_dst.addr, ip6_idents_hashrnd); 548 hash = __ipv6_addr_jhash(&rt->rt6i_dst.addr, ip6_idents_hashrnd);
549 hash = __ipv6_addr_jhash(&rt->rt6i_src.addr, hash);
550
549 id = ip_idents_reserve(hash, 1); 551 id = ip_idents_reserve(hash, 1);
550 fhdr->identification = htonl(id); 552 fhdr->identification = htonl(id);
551} 553}
diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
index a8eb0a89326a..610e19c0e13f 100644
--- a/net/netfilter/ipvs/ip_vs_conn.c
+++ b/net/netfilter/ipvs/ip_vs_conn.c
@@ -797,7 +797,6 @@ static void ip_vs_conn_expire(unsigned long data)
797 ip_vs_control_del(cp); 797 ip_vs_control_del(cp);
798 798
799 if (cp->flags & IP_VS_CONN_F_NFCT) { 799 if (cp->flags & IP_VS_CONN_F_NFCT) {
800 ip_vs_conn_drop_conntrack(cp);
801 /* Do not access conntracks during subsys cleanup 800 /* Do not access conntracks during subsys cleanup
802 * because nf_conntrack_find_get can not be used after 801 * because nf_conntrack_find_get can not be used after
803 * conntrack cleanup for the net. 802 * conntrack cleanup for the net.
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 9de23a222d3f..06a9ee6b2d3a 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -1097,6 +1097,7 @@ void sctp_assoc_update(struct sctp_association *asoc,
1097 asoc->c = new->c; 1097 asoc->c = new->c;
1098 asoc->peer.rwnd = new->peer.rwnd; 1098 asoc->peer.rwnd = new->peer.rwnd;
1099 asoc->peer.sack_needed = new->peer.sack_needed; 1099 asoc->peer.sack_needed = new->peer.sack_needed;
1100 asoc->peer.auth_capable = new->peer.auth_capable;
1100 asoc->peer.i = new->peer.i; 1101 asoc->peer.i = new->peer.i;
1101 sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_INITIAL, 1102 sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_INITIAL,
1102 asoc->peer.i.initial_tsn, GFP_ATOMIC); 1103 asoc->peer.i.initial_tsn, GFP_ATOMIC);
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index a8ef5108e0d8..0525d78ba328 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -2097,6 +2097,8 @@ struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig,
2097 goto no_transform; 2097 goto no_transform;
2098 } 2098 }
2099 2099
2100 dst_hold(&xdst->u.dst);
2101 xdst->u.dst.flags |= DST_NOCACHE;
2100 route = xdst->route; 2102 route = xdst->route;
2101 } 2103 }
2102 } 2104 }
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 412d9dc3a873..d4db6ebb089d 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -177,9 +177,7 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
177 attrs[XFRMA_ALG_AEAD] || 177 attrs[XFRMA_ALG_AEAD] ||
178 attrs[XFRMA_ALG_CRYPT] || 178 attrs[XFRMA_ALG_CRYPT] ||
179 attrs[XFRMA_ALG_COMP] || 179 attrs[XFRMA_ALG_COMP] ||
180 attrs[XFRMA_TFCPAD] || 180 attrs[XFRMA_TFCPAD])
181 (ntohl(p->id.spi) >= 0x10000))
182
183 goto out; 181 goto out;
184 break; 182 break;
185 183
@@ -207,7 +205,8 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
207 attrs[XFRMA_ALG_AUTH] || 205 attrs[XFRMA_ALG_AUTH] ||
208 attrs[XFRMA_ALG_AUTH_TRUNC] || 206 attrs[XFRMA_ALG_AUTH_TRUNC] ||
209 attrs[XFRMA_ALG_CRYPT] || 207 attrs[XFRMA_ALG_CRYPT] ||
210 attrs[XFRMA_TFCPAD]) 208 attrs[XFRMA_TFCPAD] ||
209 (ntohl(p->id.spi) >= 0x10000))
211 goto out; 210 goto out;
212 break; 211 break;
213 212