aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-04-06 11:34:06 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-04-06 11:34:06 -0400
commitcb4361c1dc29cd870f664c004b1817106fbce0fa (patch)
treec31533210d738c9074b21b8f31fe0399b39545f0 /net
parent309361e09ca9e9670dc8664e5d14125bf82078af (diff)
parentfb9e2d887243499b8d28efcf80821c4f6a092395 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (37 commits) smc91c92_cs: fix the problem of "Unable to find hardware address" r8169: clean up my printk uglyness net: Hook up cxgb4 to Kconfig and Makefile cxgb4: Add main driver file and driver Makefile cxgb4: Add remaining driver headers and L2T management cxgb4: Add packet queues and packet DMA code cxgb4: Add HW and FW support code cxgb4: Add register, message, and FW definitions netlabel: Fix several rcu_dereference() calls used without RCU read locks bonding: fix potential deadlock in bond_uninit() net: check the length of the socket address passed to connect(2) stmmac: add documentation for the driver. stmmac: fix kconfig for crc32 build error be2net: fix bug in vlan rx path for big endian architecture be2net: fix flashing on big endian architectures be2net: fix a bug in flashing the redboot section bonding: bond_xmit_roundrobin() fix drivers/net: Add missing unlock net: gianfar - align BD ring size console messages net: gianfar - initialize per-queue statistics ...
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/l2cap.c3
-rw-r--r--net/bluetooth/rfcomm/sock.c3
-rw-r--r--net/bluetooth/sco.c3
-rw-r--r--net/can/bcm.c3
-rw-r--r--net/ieee802154/af_ieee802154.c3
-rw-r--r--net/ipv4/af_inet.c5
-rw-r--r--net/ipv4/tcp.c1
-rw-r--r--net/mac80211/mesh_hwmp.c4
-rw-r--r--net/mac80211/tx.c6
-rw-r--r--net/mac80211/util.c18
-rw-r--r--net/netlabel/netlabel_domainhash.c28
-rw-r--r--net/netlabel/netlabel_unlabeled.c66
-rw-r--r--net/netlink/af_netlink.c3
-rw-r--r--net/wireless/reg.c12
14 files changed, 80 insertions, 78 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 7794a2e2adce..99d68c34e4f1 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1002,7 +1002,8 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
1002 1002
1003 BT_DBG("sk %p", sk); 1003 BT_DBG("sk %p", sk);
1004 1004
1005 if (!addr || addr->sa_family != AF_BLUETOOTH) 1005 if (!addr || alen < sizeof(addr->sa_family) ||
1006 addr->sa_family != AF_BLUETOOTH)
1006 return -EINVAL; 1007 return -EINVAL;
1007 1008
1008 memset(&la, 0, sizeof(la)); 1009 memset(&la, 0, sizeof(la));
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 7f439765403d..8ed3c37684fa 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -397,7 +397,8 @@ static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int a
397 397
398 BT_DBG("sk %p", sk); 398 BT_DBG("sk %p", sk);
399 399
400 if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_rc)) 400 if (alen < sizeof(struct sockaddr_rc) ||
401 addr->sa_family != AF_BLUETOOTH)
401 return -EINVAL; 402 return -EINVAL;
402 403
403 lock_sock(sk); 404 lock_sock(sk);
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index e5b16b76b22e..ca6b2ad1c3fc 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -499,7 +499,8 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen
499 499
500 BT_DBG("sk %p", sk); 500 BT_DBG("sk %p", sk);
501 501
502 if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_sco)) 502 if (alen < sizeof(struct sockaddr_sco) ||
503 addr->sa_family != AF_BLUETOOTH)
503 return -EINVAL; 504 return -EINVAL;
504 505
505 if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND) 506 if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND)
diff --git a/net/can/bcm.c b/net/can/bcm.c
index a2dee522b43e..907dc871fac8 100644
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -1479,6 +1479,9 @@ static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len,
1479 struct sock *sk = sock->sk; 1479 struct sock *sk = sock->sk;
1480 struct bcm_sock *bo = bcm_sk(sk); 1480 struct bcm_sock *bo = bcm_sk(sk);
1481 1481
1482 if (len < sizeof(*addr))
1483 return -EINVAL;
1484
1482 if (bo->bound) 1485 if (bo->bound)
1483 return -EISCONN; 1486 return -EISCONN;
1484 1487
diff --git a/net/ieee802154/af_ieee802154.c b/net/ieee802154/af_ieee802154.c
index 79886d546bab..c7da600750bb 100644
--- a/net/ieee802154/af_ieee802154.c
+++ b/net/ieee802154/af_ieee802154.c
@@ -127,6 +127,9 @@ static int ieee802154_sock_connect(struct socket *sock, struct sockaddr *uaddr,
127{ 127{
128 struct sock *sk = sock->sk; 128 struct sock *sk = sock->sk;
129 129
130 if (addr_len < sizeof(uaddr->sa_family))
131 return -EINVAL;
132
130 if (uaddr->sa_family == AF_UNSPEC) 133 if (uaddr->sa_family == AF_UNSPEC)
131 return sk->sk_prot->disconnect(sk, flags); 134 return sk->sk_prot->disconnect(sk, flags);
132 135
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 2ed85714540f..f71357422380 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -531,6 +531,8 @@ int inet_dgram_connect(struct socket *sock, struct sockaddr * uaddr,
531{ 531{
532 struct sock *sk = sock->sk; 532 struct sock *sk = sock->sk;
533 533
534 if (addr_len < sizeof(uaddr->sa_family))
535 return -EINVAL;
534 if (uaddr->sa_family == AF_UNSPEC) 536 if (uaddr->sa_family == AF_UNSPEC)
535 return sk->sk_prot->disconnect(sk, flags); 537 return sk->sk_prot->disconnect(sk, flags);
536 538
@@ -574,6 +576,9 @@ int inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,
574 int err; 576 int err;
575 long timeo; 577 long timeo;
576 578
579 if (addr_len < sizeof(uaddr->sa_family))
580 return -EINVAL;
581
577 lock_sock(sk); 582 lock_sock(sk);
578 583
579 if (uaddr->sa_family == AF_UNSPEC) { 584 if (uaddr->sa_family == AF_UNSPEC) {
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 7a1f1d78893f..0f8caf64caa3 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1369,6 +1369,7 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc,
1369 sk_eat_skb(sk, skb, 0); 1369 sk_eat_skb(sk, skb, 0);
1370 if (!desc->count) 1370 if (!desc->count)
1371 break; 1371 break;
1372 tp->copied_seq = seq;
1372 } 1373 }
1373 tp->copied_seq = seq; 1374 tp->copied_seq = seq;
1374 1375
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 122c11380ffe..fefc45c4b4e8 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -392,7 +392,7 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
392 if (SN_GT(mpath->sn, orig_sn) || 392 if (SN_GT(mpath->sn, orig_sn) ||
393 (mpath->sn == orig_sn && 393 (mpath->sn == orig_sn &&
394 action == MPATH_PREQ && 394 action == MPATH_PREQ &&
395 new_metric > mpath->metric)) { 395 new_metric >= mpath->metric)) {
396 process = false; 396 process = false;
397 fresh_info = false; 397 fresh_info = false;
398 } 398 }
@@ -612,7 +612,7 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
612 612
613 mesh_path_sel_frame_tx(MPATH_PREP, flags, orig_addr, 613 mesh_path_sel_frame_tx(MPATH_PREP, flags, orig_addr,
614 cpu_to_le32(orig_sn), 0, target_addr, 614 cpu_to_le32(orig_sn), 0, target_addr,
615 cpu_to_le32(target_sn), mpath->next_hop->sta.addr, hopcount, 615 cpu_to_le32(target_sn), next_hop, hopcount,
616 ttl, cpu_to_le32(lifetime), cpu_to_le32(metric), 616 ttl, cpu_to_le32(lifetime), cpu_to_le32(metric),
617 0, sdata); 617 0, sdata);
618 rcu_read_unlock(); 618 rcu_read_unlock();
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index cbe53ed4fb0b..cfc473e1b050 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1991,6 +1991,7 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local,
1991void ieee80211_tx_pending(unsigned long data) 1991void ieee80211_tx_pending(unsigned long data)
1992{ 1992{
1993 struct ieee80211_local *local = (struct ieee80211_local *)data; 1993 struct ieee80211_local *local = (struct ieee80211_local *)data;
1994 struct ieee80211_sub_if_data *sdata;
1994 unsigned long flags; 1995 unsigned long flags;
1995 int i; 1996 int i;
1996 bool txok; 1997 bool txok;
@@ -2029,6 +2030,11 @@ void ieee80211_tx_pending(unsigned long data)
2029 if (!txok) 2030 if (!txok)
2030 break; 2031 break;
2031 } 2032 }
2033
2034 if (skb_queue_empty(&local->pending[i]))
2035 list_for_each_entry_rcu(sdata, &local->interfaces, list)
2036 netif_tx_wake_queue(
2037 netdev_get_tx_queue(sdata->dev, i));
2032 } 2038 }
2033 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 2039 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
2034 2040
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index c453226f06b2..53af57047435 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -279,13 +279,13 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
279 /* someone still has this queue stopped */ 279 /* someone still has this queue stopped */
280 return; 280 return;
281 281
282 if (!skb_queue_empty(&local->pending[queue])) 282 if (skb_queue_empty(&local->pending[queue])) {
283 rcu_read_lock();
284 list_for_each_entry_rcu(sdata, &local->interfaces, list)
285 netif_tx_wake_queue(netdev_get_tx_queue(sdata->dev, queue));
286 rcu_read_unlock();
287 } else
283 tasklet_schedule(&local->tx_pending_tasklet); 288 tasklet_schedule(&local->tx_pending_tasklet);
284
285 rcu_read_lock();
286 list_for_each_entry_rcu(sdata, &local->interfaces, list)
287 netif_tx_wake_queue(netdev_get_tx_queue(sdata->dev, queue));
288 rcu_read_unlock();
289} 289}
290 290
291void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, 291void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
@@ -1097,9 +1097,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1097 */ 1097 */
1098 res = drv_start(local); 1098 res = drv_start(local);
1099 if (res) { 1099 if (res) {
1100 WARN(local->suspended, "Harware became unavailable " 1100 WARN(local->suspended, "Hardware became unavailable "
1101 "upon resume. This is could be a software issue" 1101 "upon resume. This could be a software issue "
1102 "prior to suspend or a hardware issue\n"); 1102 "prior to suspend or a hardware issue.\n");
1103 return res; 1103 return res;
1104 } 1104 }
1105 1105
diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c
index 016ab9c75ebd..d37b7f80fa37 100644
--- a/net/netlabel/netlabel_domainhash.c
+++ b/net/netlabel/netlabel_domainhash.c
@@ -51,9 +51,12 @@ struct netlbl_domhsh_tbl {
51}; 51};
52 52
53/* Domain hash table */ 53/* Domain hash table */
54/* XXX - updates should be so rare that having one spinlock for the entire 54/* updates should be so rare that having one spinlock for the entire hash table
55 * hash table should be okay */ 55 * should be okay */
56static DEFINE_SPINLOCK(netlbl_domhsh_lock); 56static DEFINE_SPINLOCK(netlbl_domhsh_lock);
57#define netlbl_domhsh_rcu_deref(p) \
58 rcu_dereference_check(p, rcu_read_lock_held() || \
59 lockdep_is_held(&netlbl_domhsh_lock))
57static struct netlbl_domhsh_tbl *netlbl_domhsh = NULL; 60static struct netlbl_domhsh_tbl *netlbl_domhsh = NULL;
58static struct netlbl_dom_map *netlbl_domhsh_def = NULL; 61static struct netlbl_dom_map *netlbl_domhsh_def = NULL;
59 62
@@ -107,7 +110,8 @@ static void netlbl_domhsh_free_entry(struct rcu_head *entry)
107 * Description: 110 * Description:
108 * This is the hashing function for the domain hash table, it returns the 111 * This is the hashing function for the domain hash table, it returns the
109 * correct bucket number for the domain. The caller is responsibile for 112 * correct bucket number for the domain. The caller is responsibile for
110 * calling the rcu_read_[un]lock() functions. 113 * ensuring that the hash table is protected with either a RCU read lock or the
114 * hash table lock.
111 * 115 *
112 */ 116 */
113static u32 netlbl_domhsh_hash(const char *key) 117static u32 netlbl_domhsh_hash(const char *key)
@@ -121,7 +125,7 @@ static u32 netlbl_domhsh_hash(const char *key)
121 125
122 for (iter = 0, val = 0, len = strlen(key); iter < len; iter++) 126 for (iter = 0, val = 0, len = strlen(key); iter < len; iter++)
123 val = (val << 4 | (val >> (8 * sizeof(u32) - 4))) ^ key[iter]; 127 val = (val << 4 | (val >> (8 * sizeof(u32) - 4))) ^ key[iter];
124 return val & (rcu_dereference(netlbl_domhsh)->size - 1); 128 return val & (netlbl_domhsh_rcu_deref(netlbl_domhsh)->size - 1);
125} 129}
126 130
127/** 131/**
@@ -131,7 +135,8 @@ static u32 netlbl_domhsh_hash(const char *key)
131 * Description: 135 * Description:
132 * Searches the domain hash table and returns a pointer to the hash table 136 * Searches the domain hash table and returns a pointer to the hash table
133 * entry if found, otherwise NULL is returned. The caller is responsibile for 137 * entry if found, otherwise NULL is returned. The caller is responsibile for
134 * the rcu hash table locks (i.e. the caller much call rcu_read_[un]lock()). 138 * ensuring that the hash table is protected with either a RCU read lock or the
139 * hash table lock.
135 * 140 *
136 */ 141 */
137static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain) 142static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain)
@@ -142,7 +147,7 @@ static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain)
142 147
143 if (domain != NULL) { 148 if (domain != NULL) {
144 bkt = netlbl_domhsh_hash(domain); 149 bkt = netlbl_domhsh_hash(domain);
145 bkt_list = &rcu_dereference(netlbl_domhsh)->tbl[bkt]; 150 bkt_list = &netlbl_domhsh_rcu_deref(netlbl_domhsh)->tbl[bkt];
146 list_for_each_entry_rcu(iter, bkt_list, list) 151 list_for_each_entry_rcu(iter, bkt_list, list)
147 if (iter->valid && strcmp(iter->domain, domain) == 0) 152 if (iter->valid && strcmp(iter->domain, domain) == 0)
148 return iter; 153 return iter;
@@ -160,8 +165,8 @@ static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain)
160 * Searches the domain hash table and returns a pointer to the hash table 165 * Searches the domain hash table and returns a pointer to the hash table
161 * entry if an exact match is found, if an exact match is not present in the 166 * entry if an exact match is found, if an exact match is not present in the
162 * hash table then the default entry is returned if valid otherwise NULL is 167 * hash table then the default entry is returned if valid otherwise NULL is
163 * returned. The caller is responsibile for the rcu hash table locks 168 * returned. The caller is responsibile ensuring that the hash table is
164 * (i.e. the caller much call rcu_read_[un]lock()). 169 * protected with either a RCU read lock or the hash table lock.
165 * 170 *
166 */ 171 */
167static struct netlbl_dom_map *netlbl_domhsh_search_def(const char *domain) 172static struct netlbl_dom_map *netlbl_domhsh_search_def(const char *domain)
@@ -170,7 +175,7 @@ static struct netlbl_dom_map *netlbl_domhsh_search_def(const char *domain)
170 175
171 entry = netlbl_domhsh_search(domain); 176 entry = netlbl_domhsh_search(domain);
172 if (entry == NULL) { 177 if (entry == NULL) {
173 entry = rcu_dereference(netlbl_domhsh_def); 178 entry = netlbl_domhsh_rcu_deref(netlbl_domhsh_def);
174 if (entry != NULL && !entry->valid) 179 if (entry != NULL && !entry->valid)
175 entry = NULL; 180 entry = NULL;
176 } 181 }
@@ -307,8 +312,11 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
307 struct netlbl_af6list *tmp6; 312 struct netlbl_af6list *tmp6;
308#endif /* IPv6 */ 313#endif /* IPv6 */
309 314
315 /* XXX - we can remove this RCU read lock as the spinlock protects the
316 * entire function, but before we do we need to fixup the
317 * netlbl_af[4,6]list RCU functions to do "the right thing" with
318 * respect to rcu_dereference() when only a spinlock is held. */
310 rcu_read_lock(); 319 rcu_read_lock();
311
312 spin_lock(&netlbl_domhsh_lock); 320 spin_lock(&netlbl_domhsh_lock);
313 if (entry->domain != NULL) 321 if (entry->domain != NULL)
314 entry_old = netlbl_domhsh_search(entry->domain); 322 entry_old = netlbl_domhsh_search(entry->domain);
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index d7ea2cf390b7..a3d64aabe2f7 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -115,6 +115,9 @@ struct netlbl_unlhsh_walk_arg {
115/* updates should be so rare that having one spinlock for the entire 115/* updates should be so rare that having one spinlock for the entire
116 * hash table should be okay */ 116 * hash table should be okay */
117static DEFINE_SPINLOCK(netlbl_unlhsh_lock); 117static DEFINE_SPINLOCK(netlbl_unlhsh_lock);
118#define netlbl_unlhsh_rcu_deref(p) \
119 rcu_dereference_check(p, rcu_read_lock_held() || \
120 lockdep_is_held(&netlbl_unlhsh_lock))
118static struct netlbl_unlhsh_tbl *netlbl_unlhsh = NULL; 121static struct netlbl_unlhsh_tbl *netlbl_unlhsh = NULL;
119static struct netlbl_unlhsh_iface *netlbl_unlhsh_def = NULL; 122static struct netlbl_unlhsh_iface *netlbl_unlhsh_def = NULL;
120 123
@@ -236,15 +239,13 @@ static void netlbl_unlhsh_free_iface(struct rcu_head *entry)
236 * Description: 239 * Description:
237 * This is the hashing function for the unlabeled hash table, it returns the 240 * This is the hashing function for the unlabeled hash table, it returns the
238 * bucket number for the given device/interface. The caller is responsible for 241 * bucket number for the given device/interface. The caller is responsible for
239 * calling the rcu_read_[un]lock() functions. 242 * ensuring that the hash table is protected with either a RCU read lock or
243 * the hash table lock.
240 * 244 *
241 */ 245 */
242static u32 netlbl_unlhsh_hash(int ifindex) 246static u32 netlbl_unlhsh_hash(int ifindex)
243{ 247{
244 /* this is taken _almost_ directly from 248 return ifindex & (netlbl_unlhsh_rcu_deref(netlbl_unlhsh)->size - 1);
245 * security/selinux/netif.c:sel_netif_hasfn() as they do pretty much
246 * the same thing */
247 return ifindex & (rcu_dereference(netlbl_unlhsh)->size - 1);
248} 249}
249 250
250/** 251/**
@@ -254,7 +255,8 @@ static u32 netlbl_unlhsh_hash(int ifindex)
254 * Description: 255 * Description:
255 * Searches the unlabeled connection hash table and returns a pointer to the 256 * Searches the unlabeled connection hash table and returns a pointer to the
256 * interface entry which matches @ifindex, otherwise NULL is returned. The 257 * interface entry which matches @ifindex, otherwise NULL is returned. The
257 * caller is responsible for calling the rcu_read_[un]lock() functions. 258 * caller is responsible for ensuring that the hash table is protected with
259 * either a RCU read lock or the hash table lock.
258 * 260 *
259 */ 261 */
260static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex) 262static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex)
@@ -264,7 +266,7 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex)
264 struct netlbl_unlhsh_iface *iter; 266 struct netlbl_unlhsh_iface *iter;
265 267
266 bkt = netlbl_unlhsh_hash(ifindex); 268 bkt = netlbl_unlhsh_hash(ifindex);
267 bkt_list = &rcu_dereference(netlbl_unlhsh)->tbl[bkt]; 269 bkt_list = &netlbl_unlhsh_rcu_deref(netlbl_unlhsh)->tbl[bkt];
268 list_for_each_entry_rcu(iter, bkt_list, list) 270 list_for_each_entry_rcu(iter, bkt_list, list)
269 if (iter->valid && iter->ifindex == ifindex) 271 if (iter->valid && iter->ifindex == ifindex)
270 return iter; 272 return iter;
@@ -273,33 +275,6 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex)
273} 275}
274 276
275/** 277/**
276 * netlbl_unlhsh_search_iface_def - Search for a matching interface entry
277 * @ifindex: the network interface
278 *
279 * Description:
280 * Searches the unlabeled connection hash table and returns a pointer to the
281 * interface entry which matches @ifindex. If an exact match can not be found
282 * and there is a valid default entry, the default entry is returned, otherwise
283 * NULL is returned. The caller is responsible for calling the
284 * rcu_read_[un]lock() functions.
285 *
286 */
287static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface_def(int ifindex)
288{
289 struct netlbl_unlhsh_iface *entry;
290
291 entry = netlbl_unlhsh_search_iface(ifindex);
292 if (entry != NULL)
293 return entry;
294
295 entry = rcu_dereference(netlbl_unlhsh_def);
296 if (entry != NULL && entry->valid)
297 return entry;
298
299 return NULL;
300}
301
302/**
303 * netlbl_unlhsh_add_addr4 - Add a new IPv4 address entry to the hash table 278 * netlbl_unlhsh_add_addr4 - Add a new IPv4 address entry to the hash table
304 * @iface: the associated interface entry 279 * @iface: the associated interface entry
305 * @addr: IPv4 address in network byte order 280 * @addr: IPv4 address in network byte order
@@ -309,8 +284,7 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface_def(int ifindex)
309 * Description: 284 * Description:
310 * Add a new address entry into the unlabeled connection hash table using the 285 * Add a new address entry into the unlabeled connection hash table using the
311 * interface entry specified by @iface. On success zero is returned, otherwise 286 * interface entry specified by @iface. On success zero is returned, otherwise
312 * a negative value is returned. The caller is responsible for calling the 287 * a negative value is returned.
313 * rcu_read_[un]lock() functions.
314 * 288 *
315 */ 289 */
316static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface, 290static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface,
@@ -350,8 +324,7 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface,
350 * Description: 324 * Description:
351 * Add a new address entry into the unlabeled connection hash table using the 325 * Add a new address entry into the unlabeled connection hash table using the
352 * interface entry specified by @iface. On success zero is returned, otherwise 326 * interface entry specified by @iface. On success zero is returned, otherwise
353 * a negative value is returned. The caller is responsible for calling the 327 * a negative value is returned.
354 * rcu_read_[un]lock() functions.
355 * 328 *
356 */ 329 */
357static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface, 330static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface,
@@ -392,8 +365,7 @@ static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface,
392 * Description: 365 * Description:
393 * Add a new, empty, interface entry into the unlabeled connection hash table. 366 * Add a new, empty, interface entry into the unlabeled connection hash table.
394 * On success a pointer to the new interface entry is returned, on failure NULL 367 * On success a pointer to the new interface entry is returned, on failure NULL
395 * is returned. The caller is responsible for calling the rcu_read_[un]lock() 368 * is returned.
396 * functions.
397 * 369 *
398 */ 370 */
399static struct netlbl_unlhsh_iface *netlbl_unlhsh_add_iface(int ifindex) 371static struct netlbl_unlhsh_iface *netlbl_unlhsh_add_iface(int ifindex)
@@ -416,10 +388,10 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_add_iface(int ifindex)
416 if (netlbl_unlhsh_search_iface(ifindex) != NULL) 388 if (netlbl_unlhsh_search_iface(ifindex) != NULL)
417 goto add_iface_failure; 389 goto add_iface_failure;
418 list_add_tail_rcu(&iface->list, 390 list_add_tail_rcu(&iface->list,
419 &rcu_dereference(netlbl_unlhsh)->tbl[bkt]); 391 &netlbl_unlhsh_rcu_deref(netlbl_unlhsh)->tbl[bkt]);
420 } else { 392 } else {
421 INIT_LIST_HEAD(&iface->list); 393 INIT_LIST_HEAD(&iface->list);
422 if (rcu_dereference(netlbl_unlhsh_def) != NULL) 394 if (netlbl_unlhsh_rcu_deref(netlbl_unlhsh_def) != NULL)
423 goto add_iface_failure; 395 goto add_iface_failure;
424 rcu_assign_pointer(netlbl_unlhsh_def, iface); 396 rcu_assign_pointer(netlbl_unlhsh_def, iface);
425 } 397 }
@@ -549,8 +521,7 @@ unlhsh_add_return:
549 * 521 *
550 * Description: 522 * Description:
551 * Remove an IP address entry from the unlabeled connection hash table. 523 * Remove an IP address entry from the unlabeled connection hash table.
552 * Returns zero on success, negative values on failure. The caller is 524 * Returns zero on success, negative values on failure.
553 * responsible for calling the rcu_read_[un]lock() functions.
554 * 525 *
555 */ 526 */
556static int netlbl_unlhsh_remove_addr4(struct net *net, 527static int netlbl_unlhsh_remove_addr4(struct net *net,
@@ -612,8 +583,7 @@ static int netlbl_unlhsh_remove_addr4(struct net *net,
612 * 583 *
613 * Description: 584 * Description:
614 * Remove an IP address entry from the unlabeled connection hash table. 585 * Remove an IP address entry from the unlabeled connection hash table.
615 * Returns zero on success, negative values on failure. The caller is 586 * Returns zero on success, negative values on failure.
616 * responsible for calling the rcu_read_[un]lock() functions.
617 * 587 *
618 */ 588 */
619static int netlbl_unlhsh_remove_addr6(struct net *net, 589static int netlbl_unlhsh_remove_addr6(struct net *net,
@@ -1548,8 +1518,10 @@ int netlbl_unlabel_getattr(const struct sk_buff *skb,
1548 struct netlbl_unlhsh_iface *iface; 1518 struct netlbl_unlhsh_iface *iface;
1549 1519
1550 rcu_read_lock(); 1520 rcu_read_lock();
1551 iface = netlbl_unlhsh_search_iface_def(skb->skb_iif); 1521 iface = netlbl_unlhsh_search_iface(skb->skb_iif);
1552 if (iface == NULL) 1522 if (iface == NULL)
1523 iface = rcu_dereference(netlbl_unlhsh_def);
1524 if (iface == NULL || !iface->valid)
1553 goto unlabel_getattr_nolabel; 1525 goto unlabel_getattr_nolabel;
1554 switch (family) { 1526 switch (family) {
1555 case PF_INET: { 1527 case PF_INET: {
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index acbbae1e89b5..795424396aff 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -683,6 +683,9 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
683 struct netlink_sock *nlk = nlk_sk(sk); 683 struct netlink_sock *nlk = nlk_sk(sk);
684 struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr; 684 struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr;
685 685
686 if (alen < sizeof(addr->sa_family))
687 return -EINVAL;
688
686 if (addr->sa_family == AF_UNSPEC) { 689 if (addr->sa_family == AF_UNSPEC) {
687 sk->sk_state = NETLINK_UNCONNECTED; 690 sk->sk_state = NETLINK_UNCONNECTED;
688 nlk->dst_pid = 0; 691 nlk->dst_pid = 0;
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index b7604b823f46..422da20d1e5b 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -325,7 +325,7 @@ struct reg_regdb_search_request {
325}; 325};
326 326
327static LIST_HEAD(reg_regdb_search_list); 327static LIST_HEAD(reg_regdb_search_list);
328static DEFINE_SPINLOCK(reg_regdb_search_lock); 328static DEFINE_MUTEX(reg_regdb_search_mutex);
329 329
330static void reg_regdb_search(struct work_struct *work) 330static void reg_regdb_search(struct work_struct *work)
331{ 331{
@@ -333,7 +333,7 @@ static void reg_regdb_search(struct work_struct *work)
333 const struct ieee80211_regdomain *curdom, *regdom; 333 const struct ieee80211_regdomain *curdom, *regdom;
334 int i, r; 334 int i, r;
335 335
336 spin_lock(&reg_regdb_search_lock); 336 mutex_lock(&reg_regdb_search_mutex);
337 while (!list_empty(&reg_regdb_search_list)) { 337 while (!list_empty(&reg_regdb_search_list)) {
338 request = list_first_entry(&reg_regdb_search_list, 338 request = list_first_entry(&reg_regdb_search_list,
339 struct reg_regdb_search_request, 339 struct reg_regdb_search_request,
@@ -347,18 +347,16 @@ static void reg_regdb_search(struct work_struct *work)
347 r = reg_copy_regd(&regdom, curdom); 347 r = reg_copy_regd(&regdom, curdom);
348 if (r) 348 if (r)
349 break; 349 break;
350 spin_unlock(&reg_regdb_search_lock);
351 mutex_lock(&cfg80211_mutex); 350 mutex_lock(&cfg80211_mutex);
352 set_regdom(regdom); 351 set_regdom(regdom);
353 mutex_unlock(&cfg80211_mutex); 352 mutex_unlock(&cfg80211_mutex);
354 spin_lock(&reg_regdb_search_lock);
355 break; 353 break;
356 } 354 }
357 } 355 }
358 356
359 kfree(request); 357 kfree(request);
360 } 358 }
361 spin_unlock(&reg_regdb_search_lock); 359 mutex_unlock(&reg_regdb_search_mutex);
362} 360}
363 361
364static DECLARE_WORK(reg_regdb_work, reg_regdb_search); 362static DECLARE_WORK(reg_regdb_work, reg_regdb_search);
@@ -376,9 +374,9 @@ static void reg_regdb_query(const char *alpha2)
376 374
377 memcpy(request->alpha2, alpha2, 2); 375 memcpy(request->alpha2, alpha2, 2);
378 376
379 spin_lock(&reg_regdb_search_lock); 377 mutex_lock(&reg_regdb_search_mutex);
380 list_add_tail(&request->list, &reg_regdb_search_list); 378 list_add_tail(&request->list, &reg_regdb_search_list);
381 spin_unlock(&reg_regdb_search_lock); 379 mutex_unlock(&reg_regdb_search_mutex);
382 380
383 schedule_work(&reg_regdb_work); 381 schedule_work(&reg_regdb_work);
384} 382}