From 35f5149ead73e8e635b417b6c3aece43ffdfe5bc Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 31 Oct 2012 15:50:34 +0100 Subject: mac80211: do not call ieee80211_configure_filter if no interfaces are up Drivers are not expected to handle it before drv_start has been called. It will be called again after an interface has been brought up. Signed-off-by: Felix Fietkau Signed-off-by: Johannes Berg --- net/mac80211/cfg.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'net') diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 05f3a313db88..7371f676cf41 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -2594,6 +2594,9 @@ static void ieee80211_mgmt_frame_register(struct wiphy *wiphy, else local->probe_req_reg--; + if (!local->open_count) + break; + ieee80211_queue_work(&local->hw, &local->reconfig_filter); break; default: -- cgit v1.2.2 From bca1e29fb54c51856dda6772d488d41b10ed91da Mon Sep 17 00:00:00 2001 From: David Spinadel Date: Mon, 29 Oct 2012 14:49:41 +0200 Subject: mac80211: init sched_scan_ies In case that there is an unsupported band, the ie will be unallocated and the free will crash. Cc: stable@vger.kernel.org Signed-off-by: David Spinadel Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- net/mac80211/scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index c4cdbde24fd3..43e60b5a7546 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -917,7 +917,7 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, struct cfg80211_sched_scan_request *req) { struct ieee80211_local *local = sdata->local; - struct ieee80211_sched_scan_ies sched_scan_ies; + struct ieee80211_sched_scan_ies sched_scan_ies = {}; int ret, i; mutex_lock(&local->mtx); -- cgit v1.2.2 From 987c285c2ae2e4e32aca3a9b3252d28171c75711 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Mon, 5 Nov 2012 10:27:52 +0200 Subject: mac80211: sync acccess to tx_filtered/ps_tx_buf queues These are accessed without a lock when ending STA PSM. If the sta_cleanup timer accesses these lists at the same time, we might crash. This may fix some mysterious crashes we had during ieee80211_sta_ps_deliver_wakeup. Cc: stable@vger.kernel.org Signed-off-by: Arik Nemtsov Signed-off-by: Ido Yariv Signed-off-by: Johannes Berg --- net/mac80211/sta_info.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'net') diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 797dd36a220d..89ccd3ec7eb8 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -961,6 +961,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) struct ieee80211_local *local = sdata->local; struct sk_buff_head pending; int filtered = 0, buffered = 0, ac; + unsigned long flags; clear_sta_flag(sta, WLAN_STA_SP); @@ -976,12 +977,16 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { int count = skb_queue_len(&pending), tmp; + spin_lock_irqsave(&sta->tx_filtered[ac].lock, flags); skb_queue_splice_tail_init(&sta->tx_filtered[ac], &pending); + spin_unlock_irqrestore(&sta->tx_filtered[ac].lock, flags); tmp = skb_queue_len(&pending); filtered += tmp - count; count = tmp; + spin_lock_irqsave(&sta->ps_tx_buf[ac].lock, flags); skb_queue_splice_tail_init(&sta->ps_tx_buf[ac], &pending); + spin_unlock_irqrestore(&sta->ps_tx_buf[ac].lock, flags); tmp = skb_queue_len(&pending); buffered += tmp - count; } -- cgit v1.2.2 From cfff2f999d9baa561f20d999c8b83b03f078fb8f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 9 Nov 2012 09:47:27 +0100 Subject: mac80211: fix memory leak in device registration error path If the cipher suites need to be allocated, but this allocation fails, this leaks the internal scan request. Fix that by going to the correct error handling label. Signed-off-by: Johannes Berg --- net/mac80211/main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'net') diff --git a/net/mac80211/main.c b/net/mac80211/main.c index c80c4490351c..f57f597972f8 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -871,8 +871,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) local->hw.wiphy->cipher_suites, sizeof(u32) * local->hw.wiphy->n_cipher_suites, GFP_KERNEL); - if (!suites) - return -ENOMEM; + if (!suites) { + result = -ENOMEM; + goto fail_wiphy_register; + } for (r = 0; r < local->hw.wiphy->n_cipher_suites; r++) { u32 suite = local->hw.wiphy->cipher_suites[r]; if (suite == WLAN_CIPHER_SUITE_WEP40 || -- cgit v1.2.2 From 476e44cb19f1fbf2d5883dddcc0ce31b33b45915 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 19 Oct 2012 20:10:46 +0300 Subject: Bluetooth: Fix having bogus entries in mgmt_read_index_list reply The mgmt_read_index_list uses one loop to calculate the max needed size of its response with the help of an upper-bound of the controller count. The second loop is more strict as it checks for HCI_SETUP (which might have gotten set after the first loop) and could result in some indexes being skipped. Because of this the function needs to readjust the event length and index count after filling in the response array. Signed-off-by: Johan Hedberg Cc: stable@vger.kernel.org Acked-by: Marcel Holtmann Signed-off-by: Gustavo Padovan --- net/bluetooth/mgmt.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'net') diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index aa2ea0a8142c..2cfabe27d3e0 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -326,7 +326,7 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data, struct hci_dev *d; size_t rp_len; u16 count; - int i, err; + int err; BT_DBG("sock %p", sk); @@ -347,9 +347,7 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data, return -ENOMEM; } - rp->num_controllers = cpu_to_le16(count); - - i = 0; + count = 0; list_for_each_entry(d, &hci_dev_list, list) { if (test_bit(HCI_SETUP, &d->dev_flags)) continue; @@ -357,10 +355,13 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data, if (!mgmt_valid_hdev(d)) continue; - rp->index[i++] = cpu_to_le16(d->id); + rp->index[count++] = cpu_to_le16(d->id); BT_DBG("Added hci%u", d->id); } + rp->num_controllers = cpu_to_le16(count); + rp_len = sizeof(*rp) + (2 * count); + read_unlock(&hci_dev_list_lock); err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_INDEX_LIST, 0, rp, -- cgit v1.2.2 From 896ea28ea824d49671fc7e9315d9c5be491a644f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paulo=20S=C3=A9rgio?= Date: Thu, 25 Oct 2012 16:55:51 -0300 Subject: Bluetooth: Fix error status when pairing fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When pairing fails due to wrong confirm value, the management layer doesn't report a proper error status. It sends MGMT_STATUS_CONNECT_FAILED instead of MGMT_STATUS_AUTH_FAILED. Most of management functions that receive a status as a parameter expects for it to be encoded as a HCI status. But when a SMP pairing fails, the SMP layer sends the SMP reason as the error status to the management layer. This commit maps all SMP reasons to HCI_ERROR_AUTH_FAILURE, which will be converted to MGMT_STATUS_AUTH_FAILED in the management layer. Reported-by: Claudio Takahasi Reviewed-by: João Paulo Rechi Vita Signed-off-by: Paulo Sérgio Signed-off-by: Gustavo Padovan --- net/bluetooth/smp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 2ac8d50861e0..a5923378bdf0 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -267,7 +267,7 @@ static void smp_failure(struct l2cap_conn *conn, u8 reason, u8 send) clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->hcon->flags); mgmt_auth_failed(conn->hcon->hdev, conn->dst, hcon->type, - hcon->dst_type, reason); + hcon->dst_type, HCI_ERROR_AUTH_FAILURE); cancel_delayed_work_sync(&conn->security_timer); -- cgit v1.2.2 From fbe96d6ff9f4e361e1b2ec0a30140e17af7e3854 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 30 Oct 2012 01:35:40 -0700 Subject: Bluetooth: Notify about device registration before power on It is important that the monitor interface gets notified about a new device before its power on procedure has been started. For some reason that is no longer working as expected and the power on procedure runs first. It is safe to just notify about device registration and trigger the power on procedure afterwards. Signed-off-by: Marcel Holtmann Acked-by: Johan Hedberg Signed-off-by: Gustavo Padovan --- net/bluetooth/hci_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'net') diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 8a0ce706aebd..a0a2f97b9c62 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1754,11 +1754,11 @@ int hci_register_dev(struct hci_dev *hdev) if (hdev->dev_type != HCI_AMP) set_bit(HCI_AUTO_OFF, &hdev->dev_flags); - schedule_work(&hdev->power_on); - hci_notify(hdev, HCI_DEV_REG); hci_dev_hold(hdev); + schedule_work(&hdev->power_on); + return id; err_wqueue: -- cgit v1.2.2 From 482049f75750d73358e65236b933417b69f9cc25 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 8 Nov 2012 10:25:26 +0100 Subject: Bluetooth: Fix memory leak when removing a UUID When removing a UUID from the list in the remove_uuid() function we must also kfree the entry in addition to removing it from the list. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann Signed-off-by: Gustavo Padovan --- net/bluetooth/mgmt.c | 1 + 1 file changed, 1 insertion(+) (limited to 'net') diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 2cfabe27d3e0..91de4239da66 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -1367,6 +1367,7 @@ static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data, continue; list_del(&match->list); + kfree(match); found++; } -- cgit v1.2.2 From 20f544eea03db4b498942558b882d463ce575c3e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 8 Nov 2012 14:06:28 +0100 Subject: mac80211: don't send null data packet when not associated On resume or firmware recovery, mac80211 sends a null data packet to see if the AP is still around and hasn't disconnected us. However, it always does this even if it wasn't even connected before, leading to a warning in the new channel context code. Fix this by checking that it's associated. Cc: stable@vger.kernel.org Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- net/mac80211/util.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'net') diff --git a/net/mac80211/util.c b/net/mac80211/util.c index e6e4bda0528e..fa1d343faa4b 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1491,6 +1491,8 @@ int ieee80211_reconfig(struct ieee80211_local *local) list_for_each_entry(sdata, &local->interfaces, list) { if (sdata->vif.type != NL80211_IFTYPE_STATION) continue; + if (!sdata->u.mgd.associated) + continue; ieee80211_send_nullfunc(local, sdata, 0); } -- cgit v1.2.2 From 1f98ab7fef48a2968f37f422c256c9fbd978c3f0 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 10 Nov 2012 03:44:14 +0100 Subject: mac80211: call skb_dequeue/ieee80211_free_txskb instead of __skb_queue_purge Fixes more wifi status skb leaks, leading to hostapd/wpa_supplicant hangs. Signed-off-by: Felix Fietkau Cc: stable@vger.kernel.org Signed-off-by: Johannes Berg --- net/mac80211/ieee80211_i.h | 2 ++ net/mac80211/sta_info.c | 6 +++--- net/mac80211/status.c | 9 +++++++++ net/mac80211/tx.c | 9 ++++++--- 4 files changed, 20 insertions(+), 6 deletions(-) (limited to 'net') diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 8c804550465b..156e5835e37f 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1314,6 +1314,8 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev); netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); +void ieee80211_purge_tx_queue(struct ieee80211_hw *hw, + struct sk_buff_head *skbs); /* HT */ void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 89ccd3ec7eb8..3b5911ed4312 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -117,8 +117,8 @@ static void free_sta_work(struct work_struct *wk) for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { local->total_ps_buffered -= skb_queue_len(&sta->ps_tx_buf[ac]); - __skb_queue_purge(&sta->ps_tx_buf[ac]); - __skb_queue_purge(&sta->tx_filtered[ac]); + ieee80211_purge_tx_queue(&local->hw, &sta->ps_tx_buf[ac]); + ieee80211_purge_tx_queue(&local->hw, &sta->tx_filtered[ac]); } #ifdef CONFIG_MAC80211_MESH @@ -141,7 +141,7 @@ static void free_sta_work(struct work_struct *wk) tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]); if (!tid_tx) continue; - __skb_queue_purge(&tid_tx->pending); + ieee80211_purge_tx_queue(&local->hw, &tid_tx->pending); kfree(tid_tx); } diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 3af0cc4130f1..101eb88a2b78 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -668,3 +668,12 @@ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb) dev_kfree_skb_any(skb); } EXPORT_SYMBOL(ieee80211_free_txskb); + +void ieee80211_purge_tx_queue(struct ieee80211_hw *hw, + struct sk_buff_head *skbs) +{ + struct sk_buff *skb; + + while ((skb = __skb_dequeue(skbs))) + ieee80211_free_txskb(hw, skb); +} diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index c9bf83f36657..b858ebe41fda 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1358,7 +1358,7 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx) if (tx->skb) ieee80211_free_txskb(&tx->local->hw, tx->skb); else - __skb_queue_purge(&tx->skbs); + ieee80211_purge_tx_queue(&tx->local->hw, &tx->skbs); return -1; } else if (unlikely(res == TX_QUEUED)) { I802_DEBUG_INC(tx->local->tx_handlers_queued); @@ -2120,10 +2120,13 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, */ void ieee80211_clear_tx_pending(struct ieee80211_local *local) { + struct sk_buff *skb; int i; - for (i = 0; i < local->hw.queues; i++) - skb_queue_purge(&local->pending[i]); + for (i = 0; i < local->hw.queues; i++) { + while ((skb = skb_dequeue(&local->pending[i])) != NULL) + ieee80211_free_txskb(&local->hw, skb); + } } /* -- cgit v1.2.2 From 0c9f79be295c99ac7e4b569ca493d75fdcc19e4e Mon Sep 17 00:00:00 2001 From: Xi Wang Date: Sun, 11 Nov 2012 11:20:01 +0000 Subject: ipv4: avoid undefined behavior in do_ip_setsockopt() (1< Signed-off-by: David S. Miller --- net/ipv4/ip_sockglue.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) (limited to 'net') diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 5eea4a811042..14bbfcf717ac 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -457,19 +457,28 @@ static int do_ip_setsockopt(struct sock *sk, int level, struct inet_sock *inet = inet_sk(sk); int val = 0, err; - if (((1<= sizeof(int)) { if (get_user(val, (int __user *) optval)) return -EFAULT; -- cgit v1.2.2 From 43c771a1963ab461a2f194e3c97fded1d5fe262f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 12 Nov 2012 10:51:34 +0100 Subject: wireless: allow 40 MHz on world roaming channels 12/13 When in world roaming mode, allow 40 MHz to be used on channels 12 and 13 so that an AP that is, e.g., using HT40+ on channel 9 (in the UK) can be used. Cc: stable@vger.kernel.org Reported-by: Eddie Chapman Tested-by: Eddie Chapman Acked-by: Luis R. Rodriguez Signed-off-by: Johannes Berg --- net/wireless/reg.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'net') diff --git a/net/wireless/reg.c b/net/wireless/reg.c index bcc7d7ee5a51..b75756b05af7 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -141,9 +141,8 @@ static const struct ieee80211_regdomain world_regdom = { .reg_rules = { /* IEEE 802.11b/g, channels 1..11 */ REG_RULE(2412-10, 2462+10, 40, 6, 20, 0), - /* IEEE 802.11b/g, channels 12..13. No HT40 - * channel fits here. */ - REG_RULE(2467-10, 2472+10, 20, 6, 20, + /* IEEE 802.11b/g, channels 12..13. */ + REG_RULE(2467-10, 2472+10, 40, 6, 20, NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS), /* IEEE 802.11 channel 14 - Only JP enables -- cgit v1.2.2 From 703fb94ec58e0e8769380c2877a8a34aeb5b6c97 Mon Sep 17 00:00:00 2001 From: Steffen Klassert Date: Tue, 13 Nov 2012 08:52:24 +0100 Subject: xfrm: Fix the gc threshold value for ipv4 The xfrm gc threshold value depends on ip_rt_max_size. This value was set to INT_MAX with the routing cache removal patch, so we start doing garbage collecting when we have INT_MAX/2 IPsec routes cached. Fix this by going back to the static threshold of 1024 routes. Signed-off-by: Steffen Klassert --- net/ipv4/route.c | 2 +- net/ipv4/xfrm4_policy.c | 13 +------------ 2 files changed, 2 insertions(+), 13 deletions(-) (limited to 'net') diff --git a/net/ipv4/route.c b/net/ipv4/route.c index a8c651216fa6..200d287e49f5 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2597,7 +2597,7 @@ int __init ip_rt_init(void) pr_err("Unable to create route proc files\n"); #ifdef CONFIG_XFRM xfrm_init(); - xfrm4_init(ip_rt_max_size); + xfrm4_init(); #endif rtnl_register(PF_INET, RTM_GETROUTE, inet_rtm_getroute, NULL, NULL); diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 05c5ab8d983c..3be0ac2c1920 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -279,19 +279,8 @@ static void __exit xfrm4_policy_fini(void) xfrm_policy_unregister_afinfo(&xfrm4_policy_afinfo); } -void __init xfrm4_init(int rt_max_size) +void __init xfrm4_init(void) { - /* - * Select a default value for the gc_thresh based on the main route - * table hash size. It seems to me the worst case scenario is when - * we have ipsec operating in transport mode, in which we create a - * dst_entry per socket. The xfrm gc algorithm starts trying to remove - * entries at gc_thresh, and prevents new allocations as 2*gc_thresh - * so lets set an initial xfrm gc_thresh value at the rt_max_size/2. - * That will let us store an ipsec connection per route table entry, - * and start cleaning when were 1/2 full - */ - xfrm4_dst_ops.gc_thresh = rt_max_size/2; dst_entries_init(&xfrm4_dst_ops); xfrm4_state_init(); -- cgit v1.2.2 From bd090dfc634ddd711a5fbd0cadc6e0ab4977bcaf Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 13 Nov 2012 05:37:18 +0000 Subject: tcp: tcp_replace_ts_recent() should not be called from tcp_validate_incoming() We added support for RFC 5961 in latest kernels but TCP fails to perform exhaustive check of ACK sequence. We can update our view of peer tsval from a frame that is later discarded by tcp_ack() This makes timestamps enabled sessions vulnerable to injection of a high tsval : peers start an ACK storm, since the victim sends a dupack each time it receives an ACK from the other peer. As tcp_validate_incoming() is called before tcp_ack(), we should not peform tcp_replace_ts_recent() from it, and let callers do it at the right time. Signed-off-by: Eric Dumazet Cc: Neal Cardwell Cc: Yuchung Cheng Cc: Nandita Dukkipati Cc: H.K. Jerry Chu Cc: Romain Francoise Signed-off-by: David S. Miller --- net/ipv4/tcp_input.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'net') diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 2c2b13a999ea..609ff98aeb47 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -5313,11 +5313,6 @@ static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb, goto discard; } - /* ts_recent update must be made after we are sure that the packet - * is in window. - */ - tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); - /* step 3: check security and precedence [ignored] */ /* step 4: Check for a SYN @@ -5552,6 +5547,11 @@ step5: if (th->ack && tcp_ack(sk, skb, FLAG_SLOWPATH) < 0) goto discard; + /* ts_recent update must be made after we are sure that the packet + * is in window. + */ + tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); + tcp_rcv_rtt_measure_ts(sk, skb); /* Process urgent data. */ @@ -6130,6 +6130,11 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, } else goto discard; + /* ts_recent update must be made after we are sure that the packet + * is in window. + */ + tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); + /* step 6: check the URG bit */ tcp_urg(sk, skb, th); -- cgit v1.2.2 From d4596bad2a713fcd0def492b1960e6d899d5baa8 Mon Sep 17 00:00:00 2001 From: Hannes Frederic Sowa Date: Sat, 10 Nov 2012 19:52:34 +0000 Subject: ipv6: setsockopt(IPIPPROTO_IPV6, IPV6_MINHOPCOUNT) forgot to set return value Cc: Stephen Hemminger Signed-off-by: Hannes Frederic Sowa Signed-off-by: David S. Miller --- net/ipv6/ipv6_sockglue.c | 1 + 1 file changed, 1 insertion(+) (limited to 'net') diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index ba6d13d1f1e1..e02faed6d17e 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -827,6 +827,7 @@ pref_skip_coa: if (val < 0 || val > 255) goto e_inval; np->min_hopcount = val; + retv = 0; break; case IPV6_DONTFRAG: np->dontfrag = valbool; -- cgit v1.2.2 From b78a4932f5fb11fadf41e69c606a33fa6787574c Mon Sep 17 00:00:00 2001 From: Simon Wunderlich Date: Tue, 13 Nov 2012 18:43:03 +0100 Subject: mac80211: deinitialize ibss-internals after emptiness check The check whether the IBSS is active and can be removed should be performed before deinitializing the fields used for the check/search. Otherwise, the configured BSS will not be found and removed properly. To make it more clear for the future, rename sdata->u.ibss to the local pointer ifibss which is used within the checks. This behaviour was introduced by f3209bea110cade12e2b133da8b8499689cb0e2e ("mac80211: fix IBSS teardown race") Cc: stable@vger.kernel.org Cc: Ignacy Gawedzki Signed-off-by: Simon Wunderlich Signed-off-by: Johannes Berg --- net/mac80211/ibss.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'net') diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index bf87c70ac6c5..c21e33d1abd0 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -1151,10 +1151,6 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) mutex_lock(&sdata->u.ibss.mtx); - sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH; - memset(sdata->u.ibss.bssid, 0, ETH_ALEN); - sdata->u.ibss.ssid_len = 0; - active_ibss = ieee80211_sta_active_ibss(sdata); if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) { @@ -1175,6 +1171,10 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) } } + ifibss->state = IEEE80211_IBSS_MLME_SEARCH; + memset(ifibss->bssid, 0, ETH_ALEN); + ifibss->ssid_len = 0; + sta_info_flush(sdata->local, sdata); spin_lock_bh(&ifibss->incomplete_lock); -- cgit v1.2.2 From b2942004fb5c9f3304b77e187b8a1977b3626c9b Mon Sep 17 00:00:00 2001 From: Saurabh Mohan Date: Wed, 14 Nov 2012 18:08:15 -0800 Subject: ipv4/ip_vti.c: VTI fix post-decryption forwarding With the latest kernel there are two things that must be done post decryption so that the packet are forwarded. 1. Remove the mark from the packet. This will cause the packet to not match the ipsec-policy again. However doing this causes the post-decryption check to fail also and the packet will get dropped. (cat /proc/net/xfrm_stat). 2. Remove the sp association in the skbuff so that no policy check is done on the packet for VTI tunnels. Due to #2 above we must now do a security-policy check in the vti rcv path prior to resetting the mark in the skbuff. Signed-off-by: Saurabh Mohan Reported-by: Ruben Herold Signed-off-by: David S. Miller --- net/ipv4/ip_vti.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'net') diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index 1831092f999f..858fddf6482a 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c @@ -338,12 +338,17 @@ static int vti_rcv(struct sk_buff *skb) if (tunnel != NULL) { struct pcpu_tstats *tstats; + if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) + return -1; + tstats = this_cpu_ptr(tunnel->dev->tstats); u64_stats_update_begin(&tstats->syncp); tstats->rx_packets++; tstats->rx_bytes += skb->len; u64_stats_update_end(&tstats->syncp); + skb->mark = 0; + secpath_reset(skb); skb->dev = tunnel->dev; return 1; } -- cgit v1.2.2 From 0da9a0c2638c8476b4a5021841912f249e3187dc Mon Sep 17 00:00:00 2001 From: Tommi Rantala Date: Thu, 15 Nov 2012 03:49:05 +0000 Subject: sctp: fix /proc/net/sctp/ memory leak Commit 13d782f ("sctp: Make the proc files per network namespace.") changed the /proc/net/sctp/ struct file_operations opener functions to use single_open_net() and seq_open_net(). Avoid leaking memory by using single_release_net() and seq_release_net() as the release functions. Discovered with Trinity (the syscall fuzzer). Signed-off-by: Tommi Rantala Acked-by: Neil Horman Cc: "Eric W. Biederman" Signed-off-by: David S. Miller --- net/sctp/proc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'net') diff --git a/net/sctp/proc.c b/net/sctp/proc.c index c3bea269faf4..9966e7b16451 100644 --- a/net/sctp/proc.c +++ b/net/sctp/proc.c @@ -102,7 +102,7 @@ static const struct file_operations sctp_snmp_seq_fops = { .open = sctp_snmp_seq_open, .read = seq_read, .llseek = seq_lseek, - .release = single_release, + .release = single_release_net, }; /* Set up the proc fs entry for 'snmp' object. */ @@ -251,7 +251,7 @@ static const struct file_operations sctp_eps_seq_fops = { .open = sctp_eps_seq_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release, + .release = seq_release_net, }; /* Set up the proc fs entry for 'eps' object. */ @@ -372,7 +372,7 @@ static const struct file_operations sctp_assocs_seq_fops = { .open = sctp_assocs_seq_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release, + .release = seq_release_net, }; /* Set up the proc fs entry for 'assocs' object. */ @@ -517,7 +517,7 @@ static const struct file_operations sctp_remaddr_seq_fops = { .open = sctp_remaddr_seq_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release, + .release = seq_release_net, }; int __net_init sctp_remaddr_proc_init(struct net *net) -- cgit v1.2.2 From ec34232575083fd0f43d3a101e8ebb041b203761 Mon Sep 17 00:00:00 2001 From: Andrew Vagin Date: Thu, 15 Nov 2012 04:03:17 +0000 Subject: tcp: fix retransmission in repair mode Currently if a socket was repaired with a few packet in a write queue, a kernel bug may be triggered: kernel BUG at net/ipv4/tcp_output.c:2330! RIP: 0010:[] tcp_retransmit_skb+0x5ff/0x610 According to the initial realization v3.4-rc2-963-gc0e88ff, all skb-s should look like already posted. This patch fixes code according with this sentence. Here are three points, which were not done in the initial patch: 1. A tcp send head should not be changed 2. Initialize TSO state of a skb 3. Reset the retransmission time This patch moves logic from tcp_sendmsg to tcp_write_xmit. A packet passes the ussual way, but isn't sent to network. This patch solves all described problems and handles tcp_sendpages. Cc: Pavel Emelyanov Cc: "David S. Miller" Cc: Alexey Kuznetsov Cc: James Morris Cc: Hideaki YOSHIFUJI Cc: Patrick McHardy Signed-off-by: Andrey Vagin Acked-by: Pavel Emelyanov Signed-off-by: David S. Miller --- net/ipv4/tcp.c | 4 ++-- net/ipv4/tcp_output.c | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'net') diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 197c0008503c..083092e3aed6 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -1212,7 +1212,7 @@ new_segment: wait_for_sndbuf: set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); wait_for_memory: - if (copied && likely(!tp->repair)) + if (copied) tcp_push(sk, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH); if ((err = sk_stream_wait_memory(sk, &timeo)) != 0) @@ -1223,7 +1223,7 @@ wait_for_memory: } out: - if (copied && likely(!tp->repair)) + if (copied) tcp_push(sk, flags, mss_now, tp->nonagle); release_sock(sk); return copied + copied_syn; diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index cfe6ffe1c177..2798706cb063 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1986,6 +1986,9 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, tso_segs = tcp_init_tso_segs(sk, skb, mss_now); BUG_ON(!tso_segs); + if (unlikely(tp->repair) && tp->repair_queue == TCP_SEND_QUEUE) + goto repair; /* Skip network transmission */ + cwnd_quota = tcp_cwnd_test(tp, skb); if (!cwnd_quota) break; @@ -2026,6 +2029,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, if (unlikely(tcp_transmit_skb(sk, skb, 1, gfp))) break; +repair: /* Advance the send_head. This one is sent out. * This call will increment packets_out. */ -- cgit v1.2.2 From a652208e0b52c190e57f2a075ffb5e897fe31c3b Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 14 Nov 2012 02:51:04 +0000 Subject: net: correct check in dev_addr_del() Check (ha->addr == dev->dev_addr) is always true because dev_addr_init() sets this. Correct the check to behave properly on addr removal. Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- net/core/dev_addr_lists.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'net') diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c index 87cc17db2d56..b079c7bbc157 100644 --- a/net/core/dev_addr_lists.c +++ b/net/core/dev_addr_lists.c @@ -319,7 +319,8 @@ int dev_addr_del(struct net_device *dev, const unsigned char *addr, */ ha = list_first_entry(&dev->dev_addrs.list, struct netdev_hw_addr, list); - if (ha->addr == dev->dev_addr && ha->refcount == 1) + if (!memcmp(ha->addr, addr, dev->addr_len) && + ha->type == addr_type && ha->refcount == 1) return -ENOENT; err = __hw_addr_del(&dev->dev_addrs, addr, dev->addr_len, -- cgit v1.2.2 From e9c00136a4754829faf885cf966c9754c7734660 Mon Sep 17 00:00:00 2001 From: Antonio Quartulli Date: Wed, 7 Nov 2012 15:05:33 +0100 Subject: batman-adv: fix tt_global_entries flags update Flags carried by a change_entry have to be always copied into the client entry as they may contain important attributes (e.g. TT_CLIENT_WIFI). For instance, a client added by means of the "early detection mechanism" has no flag set at the beginning, so they must be updated once the proper ADD event is received. This was introduced by 30cfd02b60e1cb16f5effb0a01f826c5bb7e4c59 ("batman-adv: detect not yet announced clients") Signed-off-by: Antonio Quartulli Signed-off-by: Marek Lindner --- net/batman-adv/translation-table.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'net') diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 112edd371b2f..64c00120c9f0 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -769,6 +769,12 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv, */ tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_TEMP; + /* the change can carry possible "attribute" flags like the + * TT_CLIENT_WIFI, therefore they have to be copied in the + * client entry + */ + tt_global_entry->common.flags |= flags; + /* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only * one originator left in the list and we previously received a * delete + roaming change for this originator. -- cgit v1.2.2 From 27b37ebfa2d2a1b6acef6f2d21c497475c9b9709 Mon Sep 17 00:00:00 2001 From: Antonio Quartulli Date: Thu, 8 Nov 2012 14:21:11 +0100 Subject: batman-adv: correctly pass the client flag on tt_response When a TT response with the full table is sent, the client flags should be sent as well. This patch fix the flags assignment when populating the tt_response to send back This was introduced by 30cfd02b60e1cb16f5effb0a01f826c5bb7e4c59 ("batman-adv: detect not yet announced clients") Signed-off-by: Antonio Quartulli Signed-off-by: Marek Lindner --- net/batman-adv/translation-table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 64c00120c9f0..fec1a00a0699 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -1502,7 +1502,7 @@ batadv_tt_response_fill_table(uint16_t tt_len, uint8_t ttvn, memcpy(tt_change->addr, tt_common_entry->addr, ETH_ALEN); - tt_change->flags = BATADV_NO_FLAGS; + tt_change->flags = tt_common_entry->flags; tt_count++; tt_change++; -- cgit v1.2.2 From 1f36aebcc5fa53c5d98f3329186466b5eb76a168 Mon Sep 17 00:00:00 2001 From: Antonio Quartulli Date: Thu, 8 Nov 2012 21:55:29 +0100 Subject: batman-adv: don't add TEMP clients belonging to other backbone nodes The "early client detection" mechanism must not add clients belonging to other backbone nodes. Such clients must be reached by directly using the LAN instead of the mesh. This was introduced by 30cfd02b60e1cb16f5effb0a01f826c5bb7e4c59 ("batman-adv: detect not yet announced clients") Reported-by: Glen Page Signed-off-by: Antonio Quartulli Signed-off-by: Marek Lindner --- net/batman-adv/translation-table.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'net') diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index fec1a00a0699..baae71585804 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -2456,6 +2456,13 @@ bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv, { bool ret = false; + /* if the originator is a backbone node (meaning it belongs to the same + * LAN of this node) the temporary client must not be added because to + * reach such destination the node must use the LAN instead of the mesh + */ + if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig)) + goto out; + if (!batadv_tt_global_add(bat_priv, orig_node, addr, BATADV_TT_CLIENT_TEMP, atomic_read(&orig_node->last_ttvn))) -- cgit v1.2.2 From 74490f969155caf1ec945ad2d35d3a8eec6be71d Mon Sep 17 00:00:00 2001 From: Antonio Quartulli Date: Thu, 8 Nov 2012 21:55:30 +0100 Subject: batman-adv: process broadcast packets in BLA earlier The logic in the BLA mechanism may decide to drop broadcast packets because the node may still be in the setup phase. For this reason, further broadcast processing like the early client detection mechanism must be done only after the BLA check. This patches moves the invocation to BLA before any other broadcast processing. This was introduced 30cfd02b60e1cb16f5effb0a01f826c5bb7e4c59 ("batman-adv: detect not yet announced clients") Reported-by: Glen Page Signed-off-by: Simon Wunderlich Signed-off-by: Antonio Quartulli Signed-off-by: Marek Lindner --- net/batman-adv/soft-interface.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'net') diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index b9a28d2dd3e8..ce0684a1fc83 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -325,6 +325,12 @@ void batadv_interface_rx(struct net_device *soft_iface, soft_iface->last_rx = jiffies; + /* Let the bridge loop avoidance check the packet. If will + * not handle it, we can safely push it up. + */ + if (batadv_bla_rx(bat_priv, skb, vid, is_bcast)) + goto out; + if (orig_node) batadv_tt_add_temporary_global_entry(bat_priv, orig_node, ethhdr->h_source); @@ -332,12 +338,6 @@ void batadv_interface_rx(struct net_device *soft_iface, if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest)) goto dropped; - /* Let the bridge loop avoidance check the packet. If will - * not handle it, we can safely push it up. - */ - if (batadv_bla_rx(bat_priv, skb, vid, is_bcast)) - goto out; - netif_rx(skb); goto out; -- cgit v1.2.2 From 976a702ac9eeacea09e588456ab165dc06f9ee83 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 16 Nov 2012 05:31:53 +0000 Subject: tcp: handle tcp_net_metrics_init() order-5 memory allocation failures order-5 allocations can fail with current kernels, we should try vmalloc() as well. Reported-by: Julien Tinnes Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/tcp_metrics.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'net') diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c index 53bc5847bfa8..f696d7c2e9fa 100644 --- a/net/ipv4/tcp_metrics.c +++ b/net/ipv4/tcp_metrics.c @@ -1,7 +1,6 @@ #include #include #include -#include #include #include #include @@ -9,6 +8,7 @@ #include #include #include +#include #include #include @@ -1034,7 +1034,10 @@ static int __net_init tcp_net_metrics_init(struct net *net) net->ipv4.tcp_metrics_hash_log = order_base_2(slots); size = sizeof(struct tcpm_hash_bucket) << net->ipv4.tcp_metrics_hash_log; - net->ipv4.tcp_metrics_hash = kzalloc(size, GFP_KERNEL); + net->ipv4.tcp_metrics_hash = kzalloc(size, GFP_KERNEL | __GFP_NOWARN); + if (!net->ipv4.tcp_metrics_hash) + net->ipv4.tcp_metrics_hash = vzalloc(size); + if (!net->ipv4.tcp_metrics_hash) return -ENOMEM; @@ -1055,7 +1058,10 @@ static void __net_exit tcp_net_metrics_exit(struct net *net) tm = next; } } - kfree(net->ipv4.tcp_metrics_hash); + if (is_vmalloc_addr(net->ipv4.tcp_metrics_hash)) + vfree(net->ipv4.tcp_metrics_hash); + else + kfree(net->ipv4.tcp_metrics_hash); } static __net_initdata struct pernet_operations tcp_net_metrics_ops = { -- cgit v1.2.2 From baefa31db2f2b13a05d1b81bdf2d20d487f58b0a Mon Sep 17 00:00:00 2001 From: Tom Herbert Date: Fri, 16 Nov 2012 09:04:15 +0000 Subject: net-rps: Fix brokeness causing OOO packets In commit c445477d74ab3779 which adds aRFS to the kernel, the CPU selected for RFS is not set correctly when CPU is changing. This is causing OOO packets and probably other issues. Signed-off-by: Tom Herbert Acked-by: Eric Dumazet Acked-by: Ben Hutchings Signed-off-by: David S. Miller --- net/core/dev.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'net') diff --git a/net/core/dev.c b/net/core/dev.c index bda6d004f9f0..c0946cb2b354 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2818,8 +2818,10 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, if (unlikely(tcpu != next_cpu) && (tcpu == RPS_NO_CPU || !cpu_online(tcpu) || ((int)(per_cpu(softnet_data, tcpu).input_queue_head - - rflow->last_qtail)) >= 0)) + rflow->last_qtail)) >= 0)) { + tcpu = next_cpu; rflow = set_rps_cpu(dev, skb, rflow, next_cpu); + } if (tcpu != RPS_NO_CPU && cpu_online(tcpu)) { *rflowp = rflow; -- cgit v1.2.2 From 38c1a01cf10c6e4049b4ffbd4a6af655df2a46e1 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 16 Nov 2012 20:46:19 +0100 Subject: wireless: add back sysfs directory commit 35b2a113cb0298d4f9a1263338b456094a414057 broke (at least) Fedora's networking scripts, they check for the existence of the wireless directory. As the files aren't used, add the directory back and not the files. Also do it for both drivers based on the old wireless extensions and cfg80211, regardless of whether the compat code for wext is built into cfg80211 or not. Cc: stable@vger.kernel.org [3.6] Reported-by: Dave Airlie Reported-by: Bill Nottingham Signed-off-by: Johannes Berg --- net/core/net-sysfs.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'net') diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index bcf02f608cbf..017a8bacfb27 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -429,6 +429,17 @@ static struct attribute_group netstat_group = { .name = "statistics", .attrs = netstat_attrs, }; + +#if IS_ENABLED(CONFIG_WIRELESS_EXT) || IS_ENABLED(CONFIG_CFG80211) +static struct attribute *wireless_attrs[] = { + NULL +}; + +static struct attribute_group wireless_group = { + .name = "wireless", + .attrs = wireless_attrs, +}; +#endif #endif /* CONFIG_SYSFS */ #ifdef CONFIG_RPS @@ -1409,6 +1420,15 @@ int netdev_register_kobject(struct net_device *net) groups++; *groups++ = &netstat_group; + +#if IS_ENABLED(CONFIG_WIRELESS_EXT) || IS_ENABLED(CONFIG_CFG80211) + if (net->ieee80211_ptr) + *groups++ = &wireless_group; +#if IS_ENABLED(CONFIG_WIRELESS_EXT) + else if (net->wireless_handlers) + *groups++ = &wireless_group; +#endif +#endif #endif /* CONFIG_SYSFS */ error = device_add(dev); -- cgit v1.2.2 From 16a78e9fed5e8baa8480ae3413f4328c4537c599 Mon Sep 17 00:00:00 2001 From: Thierry Escande Date: Fri, 12 Oct 2012 15:25:43 +0200 Subject: NFC: Fix nfc_llcp_local chained list insertion list_add was called with swapped parameters Signed-off-by: Thierry Escande Signed-off-by: Samuel Ortiz --- net/nfc/llcp/llcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c index cc10d073c338..9e8f4b2801f6 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp/llcp.c @@ -1210,7 +1210,7 @@ int nfc_llcp_register_device(struct nfc_dev *ndev) local->remote_miu = LLCP_DEFAULT_MIU; local->remote_lto = LLCP_DEFAULT_LTO; - list_add(&llcp_devices, &local->list); + list_add(&local->list, &llcp_devices); return 0; } -- cgit v1.2.2 From b4dd006760d671337b62532277b0296bcee8dfd4 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 20 Nov 2012 15:14:51 -0500 Subject: ipv6: fix inet6_csk_update_pmtu() return value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In case of error, inet6_csk_update_pmtu() should consistently return NULL. Bug added in commit 35ad9b9cf7d8a (ipv6: Add helper inet6_csk_update_pmtu().) Reported-by: Lluís Batlle i Rossell Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv6/inet6_connection_sock.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'net') diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index c4f934176cab..30647857a375 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c @@ -252,6 +252,7 @@ struct dst_entry *inet6_csk_update_pmtu(struct sock *sk, u32 mtu) return NULL; dst->ops->update_pmtu(dst, sk, NULL, mtu); - return inet6_csk_route_socket(sk, &fl6); + dst = inet6_csk_route_socket(sk, &fl6); + return IS_ERR(dst) ? NULL : dst; } EXPORT_SYMBOL_GPL(inet6_csk_update_pmtu); -- cgit v1.2.2 From 4fe198e6b136c516df493ec325ab8f70d470f477 Mon Sep 17 00:00:00 2001 From: Jozsef Kadlecsik Date: Mon, 19 Nov 2012 06:42:21 +0000 Subject: netfilter: ipset: Fix range bug in hash:ip,port,net Due to the missing ininitalization at adding/deleting entries, when a plain_ip,port,net element was the object, multiple elements were added/deleted instead. The bug came from the missing dangling default initialization. The error-prone default initialization is corrected in all hash:* types. Signed-off-by: Jozsef Kadlecsik Signed-off-by: Pablo Neira Ayuso --- net/netfilter/ipset/ip_set_hash_ip.c | 4 ++-- net/netfilter/ipset/ip_set_hash_ipport.c | 7 +++---- net/netfilter/ipset/ip_set_hash_ipportip.c | 7 +++---- net/netfilter/ipset/ip_set_hash_ipportnet.c | 7 +++++-- 4 files changed, 13 insertions(+), 12 deletions(-) (limited to 'net') diff --git a/net/netfilter/ipset/ip_set_hash_ip.c b/net/netfilter/ipset/ip_set_hash_ip.c index ec3dba5dcd62..5c0b78528e55 100644 --- a/net/netfilter/ipset/ip_set_hash_ip.c +++ b/net/netfilter/ipset/ip_set_hash_ip.c @@ -173,6 +173,7 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[], return adtfn(set, &nip, timeout, flags); } + ip_to = ip; if (tb[IPSET_ATTR_IP_TO]) { ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); if (ret) @@ -185,8 +186,7 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[], if (!cidr || cidr > 32) return -IPSET_ERR_INVALID_CIDR; ip_set_mask_from_to(ip, ip_to, cidr); - } else - ip_to = ip; + } hosts = h->netmask == 32 ? 1 : 2 << (32 - h->netmask - 1); diff --git a/net/netfilter/ipset/ip_set_hash_ipport.c b/net/netfilter/ipset/ip_set_hash_ipport.c index 0171f7502fa5..6283351f4eeb 100644 --- a/net/netfilter/ipset/ip_set_hash_ipport.c +++ b/net/netfilter/ipset/ip_set_hash_ipport.c @@ -162,7 +162,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[], const struct ip_set_hash *h = set->data; ipset_adtfn adtfn = set->variant->adt[adt]; struct hash_ipport4_elem data = { }; - u32 ip, ip_to = 0, p = 0, port, port_to; + u32 ip, ip_to, p = 0, port, port_to; u32 timeout = h->timeout; bool with_ports = false; int ret; @@ -210,7 +210,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[], return ip_set_eexist(ret, flags) ? 0 : ret; } - ip = ntohl(data.ip); + ip_to = ip = ntohl(data.ip); if (tb[IPSET_ATTR_IP_TO]) { ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); if (ret) @@ -223,8 +223,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[], if (!cidr || cidr > 32) return -IPSET_ERR_INVALID_CIDR; ip_set_mask_from_to(ip, ip_to, cidr); - } else - ip_to = ip; + } port_to = port = ntohs(data.port); if (with_ports && tb[IPSET_ATTR_PORT_TO]) { diff --git a/net/netfilter/ipset/ip_set_hash_ipportip.c b/net/netfilter/ipset/ip_set_hash_ipportip.c index 6344ef551ec8..6a21271c8d5a 100644 --- a/net/netfilter/ipset/ip_set_hash_ipportip.c +++ b/net/netfilter/ipset/ip_set_hash_ipportip.c @@ -166,7 +166,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[], const struct ip_set_hash *h = set->data; ipset_adtfn adtfn = set->variant->adt[adt]; struct hash_ipportip4_elem data = { }; - u32 ip, ip_to = 0, p = 0, port, port_to; + u32 ip, ip_to, p = 0, port, port_to; u32 timeout = h->timeout; bool with_ports = false; int ret; @@ -218,7 +218,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[], return ip_set_eexist(ret, flags) ? 0 : ret; } - ip = ntohl(data.ip); + ip_to = ip = ntohl(data.ip); if (tb[IPSET_ATTR_IP_TO]) { ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); if (ret) @@ -231,8 +231,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[], if (!cidr || cidr > 32) return -IPSET_ERR_INVALID_CIDR; ip_set_mask_from_to(ip, ip_to, cidr); - } else - ip_to = ip; + } port_to = port = ntohs(data.port); if (with_ports && tb[IPSET_ATTR_PORT_TO]) { diff --git a/net/netfilter/ipset/ip_set_hash_ipportnet.c b/net/netfilter/ipset/ip_set_hash_ipportnet.c index cb71f9a774e7..2d5cd4ee30eb 100644 --- a/net/netfilter/ipset/ip_set_hash_ipportnet.c +++ b/net/netfilter/ipset/ip_set_hash_ipportnet.c @@ -215,8 +215,8 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], const struct ip_set_hash *h = set->data; ipset_adtfn adtfn = set->variant->adt[adt]; struct hash_ipportnet4_elem data = { .cidr = HOST_MASK - 1 }; - u32 ip, ip_to = 0, p = 0, port, port_to; - u32 ip2_from = 0, ip2_to, ip2_last, ip2; + u32 ip, ip_to, p = 0, port, port_to; + u32 ip2_from, ip2_to, ip2_last, ip2; u32 timeout = h->timeout; bool with_ports = false; u8 cidr; @@ -286,6 +286,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], return ip_set_eexist(ret, flags) ? 0 : ret; } + ip_to = ip; if (tb[IPSET_ATTR_IP_TO]) { ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); if (ret) @@ -306,6 +307,8 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], if (port > port_to) swap(port, port_to); } + + ip2_to = ip2_from; if (tb[IPSET_ATTR_IP2_TO]) { ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP2_TO], &ip2_to); if (ret) -- cgit v1.2.2 From e93b5f9f320db431ec8623a4c667811007e07fd7 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Wed, 21 Nov 2012 01:37:38 +0000 Subject: netfilter: cttimeout: fix buffer overflow Chen Gang reports: the length of nla_data(cda[CTA_TIMEOUT_NAME]) is not limited in server side. And indeed, its used to strcpy to a fixed-sized buffer. Fortunately, nfnetlink users need CAP_NET_ADMIN. Reported-by: Chen Gang Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nfnetlink_cttimeout.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'net') diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c index 8847b4d8be06..701c88a20fea 100644 --- a/net/netfilter/nfnetlink_cttimeout.c +++ b/net/netfilter/nfnetlink_cttimeout.c @@ -41,7 +41,8 @@ MODULE_DESCRIPTION("cttimeout: Extended Netfilter Connection Tracking timeout tu static LIST_HEAD(cttimeout_list); static const struct nla_policy cttimeout_nla_policy[CTA_TIMEOUT_MAX+1] = { - [CTA_TIMEOUT_NAME] = { .type = NLA_NUL_STRING }, + [CTA_TIMEOUT_NAME] = { .type = NLA_NUL_STRING, + .len = CTNL_TIMEOUT_NAME_MAX - 1}, [CTA_TIMEOUT_L3PROTO] = { .type = NLA_U16 }, [CTA_TIMEOUT_L4PROTO] = { .type = NLA_U8 }, [CTA_TIMEOUT_DATA] = { .type = NLA_NESTED }, -- cgit v1.2.2 From 636174219b52b5a8bc51bc23bbcba97cd30a65e3 Mon Sep 17 00:00:00 2001 From: Julian Anastasov Date: Thu, 22 Nov 2012 23:04:14 +0200 Subject: ipv4: do not cache looped multicasts Starting from 3.6 we cache output routes for multicasts only when using route to 224/4. For local receivers we can set RTCF_LOCAL flag depending on the membership but in such case we use maddr and saddr which are not caching keys as before. Additionally, we can not use same place to cache routes that differ in RTCF_LOCAL flag value. Fix it by caching only RTCF_MULTICAST entries without RTCF_LOCAL (send-only, no loopback). As a side effect, we avoid unneeded lookup for fnhe when not caching because multicasts are not redirected and they do not learn PMTU. Thanks to Maxime Bizon for showing the caching problems in __mkroute_output for 3.6 kernels: different RTCF_LOCAL flag in cache can lead to wrong ip_mc_output or ip_output call and the visible problem is that traffic can not reach local receivers via loopback. Reported-by: Maxime Bizon Tested-by: Maxime Bizon Signed-off-by: Julian Anastasov Signed-off-by: David S. Miller --- net/ipv4/route.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'net') diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 200d287e49f5..df251424d816 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1785,6 +1785,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res, if (dev_out->flags & IFF_LOOPBACK) flags |= RTCF_LOCAL; + do_cache = true; if (type == RTN_BROADCAST) { flags |= RTCF_BROADCAST | RTCF_LOCAL; fi = NULL; @@ -1793,6 +1794,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res, if (!ip_check_mc_rcu(in_dev, fl4->daddr, fl4->saddr, fl4->flowi4_proto)) flags &= ~RTCF_LOCAL; + else + do_cache = false; /* If multicast route do not exist use * default one, but do not gateway in this case. * Yes, it is hack. @@ -1802,8 +1805,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res, } fnhe = NULL; - do_cache = fi != NULL; - if (fi) { + do_cache &= fi != NULL; + if (do_cache) { struct rtable __rcu **prth; struct fib_nh *nh = &FIB_RES_NH(*res); -- cgit v1.2.2