aboutsummaryrefslogtreecommitdiffstats
path: root/net/netlabel
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/netlabel
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/netlabel')
-rw-r--r--net/netlabel/netlabel_domainhash.c28
-rw-r--r--net/netlabel/netlabel_unlabeled.c66
2 files changed, 37 insertions, 57 deletions
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: {