diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/compat.c | 9 | ||||
-rw-r--r-- | net/core/iovec.c | 6 | ||||
-rw-r--r-- | net/core/neighbour.c | 2 | ||||
-rw-r--r-- | net/ipv4/route.c | 32 | ||||
-rw-r--r-- | net/ipv6/ip6_output.c | 2 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 5 | ||||
-rw-r--r-- | net/mac80211/tx.c | 20 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_conn.c | 1 | ||||
-rw-r--r-- | net/sctp/associola.c | 1 | ||||
-rw-r--r-- | net/wireless/trace.h | 3 | ||||
-rw-r--r-- | net/xfrm/xfrm_policy.c | 2 | ||||
-rw-r--r-- | net/xfrm/xfrm_user.c | 7 |
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 | ||
460 | atomic_t *ip_idents __read_mostly; | 460 | #define IP_IDENTS_SZ 2048u |
461 | EXPORT_SYMBOL(ip_idents); | 461 | struct ip_ident_bucket { |
462 | atomic_t id; | ||
463 | u32 stamp32; | ||
464 | }; | ||
465 | |||
466 | static 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 | */ | ||
472 | u32 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 | } | ||
484 | EXPORT_SYMBOL(ip_idents_reserve); | ||
462 | 485 | ||
463 | void __ip_select_ident(struct iphdr *iph, int segs) | 486 | void __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) | |||
531 | static ieee80211_tx_result debug_noinline | 541 | static ieee80211_tx_result debug_noinline |
532 | ieee80211_tx_h_ps_buf(struct ieee80211_tx_data *tx) | 542 | ieee80211_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 | ||