aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
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/mac80211/cfg.c5
-rw-r--r--net/mac80211/tx.c20
-rw-r--r--net/netfilter/ipvs/ip_vs_conn.c1
-rw-r--r--net/sctp/associola.c1
-rw-r--r--net/wireless/trace.h3
-rw-r--r--net/xfrm/xfrm_policy.c2
-rw-r--r--net/xfrm/xfrm_user.c7
12 files changed, 62 insertions, 28 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 cb9df0eb4023..45702b8cd141 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -545,6 +545,8 @@ static void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt)
545 net_get_random_once(&ip6_idents_hashrnd, sizeof(ip6_idents_hashrnd)); 545 net_get_random_once(&ip6_idents_hashrnd, sizeof(ip6_idents_hashrnd));
546 546
547 hash = __ipv6_addr_jhash(&rt->rt6i_dst.addr, ip6_idents_hashrnd); 547 hash = __ipv6_addr_jhash(&rt->rt6i_dst.addr, ip6_idents_hashrnd);
548 hash = __ipv6_addr_jhash(&rt->rt6i_src.addr, hash);
549
548 id = ip_idents_reserve(hash, 1); 550 id = ip_idents_reserve(hash, 1);
549 fhdr->identification = htonl(id); 551 fhdr->identification = htonl(id);
550} 552}
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index d7513a503be1..592f4b152ba8 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -472,12 +472,15 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
472{ 472{
473 struct ieee80211_sub_if_data *sdata = sta->sdata; 473 struct ieee80211_sub_if_data *sdata = sta->sdata;
474 struct ieee80211_local *local = sdata->local; 474 struct ieee80211_local *local = sdata->local;
475 struct rate_control_ref *ref = local->rate_ctrl; 475 struct rate_control_ref *ref = NULL;
476 struct timespec uptime; 476 struct timespec uptime;
477 u64 packets = 0; 477 u64 packets = 0;
478 u32 thr = 0; 478 u32 thr = 0;
479 int i, ac; 479 int i, ac;
480 480
481 if (test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
482 ref = local->rate_ctrl;
483
481 sinfo->generation = sdata->local->sta_generation; 484 sinfo->generation = sdata->local->sta_generation;
482 485
483 sinfo->filled = STATION_INFO_INACTIVE_TIME | 486 sinfo->filled = STATION_INFO_INACTIVE_TIME |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 5214686d9fd1..1a252c606ad0 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -414,6 +414,9 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx)
414 if (ieee80211_has_order(hdr->frame_control)) 414 if (ieee80211_has_order(hdr->frame_control))
415 return TX_CONTINUE; 415 return TX_CONTINUE;
416 416
417 if (ieee80211_is_probe_req(hdr->frame_control))
418 return TX_CONTINUE;
419
417 if (tx->local->hw.flags & IEEE80211_HW_QUEUE_CONTROL) 420 if (tx->local->hw.flags & IEEE80211_HW_QUEUE_CONTROL)
418 info->hw_queue = tx->sdata->vif.cab_queue; 421 info->hw_queue = tx->sdata->vif.cab_queue;
419 422
@@ -463,6 +466,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
463{ 466{
464 struct sta_info *sta = tx->sta; 467 struct sta_info *sta = tx->sta;
465 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); 468 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
469 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
466 struct ieee80211_local *local = tx->local; 470 struct ieee80211_local *local = tx->local;
467 471
468 if (unlikely(!sta)) 472 if (unlikely(!sta))
@@ -473,6 +477,12 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
473 !(info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER))) { 477 !(info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER))) {
474 int ac = skb_get_queue_mapping(tx->skb); 478 int ac = skb_get_queue_mapping(tx->skb);
475 479
480 if (ieee80211_is_mgmt(hdr->frame_control) &&
481 !ieee80211_is_bufferable_mmpdu(hdr->frame_control)) {
482 info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER;
483 return TX_CONTINUE;
484 }
485
476 ps_dbg(sta->sdata, "STA %pM aid %d: PS buffer for AC %d\n", 486 ps_dbg(sta->sdata, "STA %pM aid %d: PS buffer for AC %d\n",
477 sta->sta.addr, sta->sta.aid, ac); 487 sta->sta.addr, sta->sta.aid, ac);
478 if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) 488 if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER)
@@ -531,19 +541,9 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
531static ieee80211_tx_result debug_noinline 541static ieee80211_tx_result debug_noinline
532ieee80211_tx_h_ps_buf(struct ieee80211_tx_data *tx) 542ieee80211_tx_h_ps_buf(struct ieee80211_tx_data *tx)
533{ 543{
534 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
535 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
536
537 if (unlikely(tx->flags & IEEE80211_TX_PS_BUFFERED)) 544 if (unlikely(tx->flags & IEEE80211_TX_PS_BUFFERED))
538 return TX_CONTINUE; 545 return TX_CONTINUE;
539 546
540 if (ieee80211_is_mgmt(hdr->frame_control) &&
541 !ieee80211_is_bufferable_mmpdu(hdr->frame_control)) {
542 if (tx->flags & IEEE80211_TX_UNICAST)
543 info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER;
544 return TX_CONTINUE;
545 }
546
547 if (tx->flags & IEEE80211_TX_UNICAST) 547 if (tx->flags & IEEE80211_TX_UNICAST)
548 return ieee80211_tx_h_unicast_ps_buf(tx); 548 return ieee80211_tx_h_unicast_ps_buf(tx);
549 else 549 else
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/wireless/trace.h b/net/wireless/trace.h
index 560ed77084e9..7cc887f9da11 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -2094,7 +2094,8 @@ TRACE_EVENT(cfg80211_michael_mic_failure,
2094 MAC_ASSIGN(addr, addr); 2094 MAC_ASSIGN(addr, addr);
2095 __entry->key_type = key_type; 2095 __entry->key_type = key_type;
2096 __entry->key_id = key_id; 2096 __entry->key_id = key_id;
2097 memcpy(__entry->tsc, tsc, 6); 2097 if (tsc)
2098 memcpy(__entry->tsc, tsc, 6);
2098 ), 2099 ),
2099 TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT ", key type: %d, key id: %d, tsc: %pm", 2100 TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT ", key type: %d, key id: %d, tsc: %pm",
2100 NETDEV_PR_ARG, MAC_PR_ARG(addr), __entry->key_type, 2101 NETDEV_PR_ARG, MAC_PR_ARG(addr), __entry->key_type,
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