diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /net/netlabel | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'net/netlabel')
-rw-r--r-- | net/netlabel/netlabel_cipso_v4.c | 1 | ||||
-rw-r--r-- | net/netlabel/netlabel_domainhash.c | 32 | ||||
-rw-r--r-- | net/netlabel/netlabel_kapi.c | 1 | ||||
-rw-r--r-- | net/netlabel/netlabel_mgmt.c | 1 | ||||
-rw-r--r-- | net/netlabel/netlabel_unlabeled.c | 76 | ||||
-rw-r--r-- | net/netlabel/netlabel_user.c | 1 |
6 files changed, 46 insertions, 66 deletions
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c index e639298bc9c8..5f14c8462e30 100644 --- a/net/netlabel/netlabel_cipso_v4.c +++ b/net/netlabel/netlabel_cipso_v4.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/string.h> | 33 | #include <linux/string.h> |
34 | #include <linux/skbuff.h> | 34 | #include <linux/skbuff.h> |
35 | #include <linux/audit.h> | 35 | #include <linux/audit.h> |
36 | #include <linux/slab.h> | ||
36 | #include <net/sock.h> | 37 | #include <net/sock.h> |
37 | #include <net/netlink.h> | 38 | #include <net/netlink.h> |
38 | #include <net/genetlink.h> | 39 | #include <net/genetlink.h> |
diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c index 7a10bbe02c13..d37b7f80fa37 100644 --- a/net/netlabel/netlabel_domainhash.c +++ b/net/netlabel/netlabel_domainhash.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/spinlock.h> | 35 | #include <linux/spinlock.h> |
36 | #include <linux/string.h> | 36 | #include <linux/string.h> |
37 | #include <linux/audit.h> | 37 | #include <linux/audit.h> |
38 | #include <linux/slab.h> | ||
38 | #include <net/netlabel.h> | 39 | #include <net/netlabel.h> |
39 | #include <net/cipso_ipv4.h> | 40 | #include <net/cipso_ipv4.h> |
40 | #include <asm/bug.h> | 41 | #include <asm/bug.h> |
@@ -50,9 +51,12 @@ struct netlbl_domhsh_tbl { | |||
50 | }; | 51 | }; |
51 | 52 | ||
52 | /* Domain hash table */ | 53 | /* Domain hash table */ |
53 | /* 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 |
54 | * hash table should be okay */ | 55 | * should be okay */ |
55 | static DEFINE_SPINLOCK(netlbl_domhsh_lock); | 56 | static 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)) | ||
56 | static struct netlbl_domhsh_tbl *netlbl_domhsh = NULL; | 60 | static struct netlbl_domhsh_tbl *netlbl_domhsh = NULL; |
57 | static struct netlbl_dom_map *netlbl_domhsh_def = NULL; | 61 | static struct netlbl_dom_map *netlbl_domhsh_def = NULL; |
58 | 62 | ||
@@ -106,7 +110,8 @@ static void netlbl_domhsh_free_entry(struct rcu_head *entry) | |||
106 | * Description: | 110 | * Description: |
107 | * 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 |
108 | * correct bucket number for the domain. The caller is responsibile for | 112 | * correct bucket number for the domain. The caller is responsibile for |
109 | * 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. | ||
110 | * | 115 | * |
111 | */ | 116 | */ |
112 | static u32 netlbl_domhsh_hash(const char *key) | 117 | static u32 netlbl_domhsh_hash(const char *key) |
@@ -120,7 +125,7 @@ static u32 netlbl_domhsh_hash(const char *key) | |||
120 | 125 | ||
121 | for (iter = 0, val = 0, len = strlen(key); iter < len; iter++) | 126 | for (iter = 0, val = 0, len = strlen(key); iter < len; iter++) |
122 | val = (val << 4 | (val >> (8 * sizeof(u32) - 4))) ^ key[iter]; | 127 | val = (val << 4 | (val >> (8 * sizeof(u32) - 4))) ^ key[iter]; |
123 | return val & (rcu_dereference(netlbl_domhsh)->size - 1); | 128 | return val & (netlbl_domhsh_rcu_deref(netlbl_domhsh)->size - 1); |
124 | } | 129 | } |
125 | 130 | ||
126 | /** | 131 | /** |
@@ -130,7 +135,8 @@ static u32 netlbl_domhsh_hash(const char *key) | |||
130 | * Description: | 135 | * Description: |
131 | * 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 |
132 | * 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 |
133 | * 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. | ||
134 | * | 140 | * |
135 | */ | 141 | */ |
136 | static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain) | 142 | static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain) |
@@ -141,7 +147,7 @@ static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain) | |||
141 | 147 | ||
142 | if (domain != NULL) { | 148 | if (domain != NULL) { |
143 | bkt = netlbl_domhsh_hash(domain); | 149 | bkt = netlbl_domhsh_hash(domain); |
144 | bkt_list = &rcu_dereference(netlbl_domhsh)->tbl[bkt]; | 150 | bkt_list = &netlbl_domhsh_rcu_deref(netlbl_domhsh)->tbl[bkt]; |
145 | list_for_each_entry_rcu(iter, bkt_list, list) | 151 | list_for_each_entry_rcu(iter, bkt_list, list) |
146 | if (iter->valid && strcmp(iter->domain, domain) == 0) | 152 | if (iter->valid && strcmp(iter->domain, domain) == 0) |
147 | return iter; | 153 | return iter; |
@@ -159,8 +165,8 @@ static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain) | |||
159 | * 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 |
160 | * 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 |
161 | * 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 |
162 | * returned. The caller is responsibile for the rcu hash table locks | 168 | * returned. The caller is responsibile ensuring that the hash table is |
163 | * (i.e. the caller much call rcu_read_[un]lock()). | 169 | * protected with either a RCU read lock or the hash table lock. |
164 | * | 170 | * |
165 | */ | 171 | */ |
166 | static struct netlbl_dom_map *netlbl_domhsh_search_def(const char *domain) | 172 | static struct netlbl_dom_map *netlbl_domhsh_search_def(const char *domain) |
@@ -169,7 +175,7 @@ static struct netlbl_dom_map *netlbl_domhsh_search_def(const char *domain) | |||
169 | 175 | ||
170 | entry = netlbl_domhsh_search(domain); | 176 | entry = netlbl_domhsh_search(domain); |
171 | if (entry == NULL) { | 177 | if (entry == NULL) { |
172 | entry = rcu_dereference(netlbl_domhsh_def); | 178 | entry = netlbl_domhsh_rcu_deref(netlbl_domhsh_def); |
173 | if (entry != NULL && !entry->valid) | 179 | if (entry != NULL && !entry->valid) |
174 | entry = NULL; | 180 | entry = NULL; |
175 | } | 181 | } |
@@ -306,8 +312,11 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry, | |||
306 | struct netlbl_af6list *tmp6; | 312 | struct netlbl_af6list *tmp6; |
307 | #endif /* IPv6 */ | 313 | #endif /* IPv6 */ |
308 | 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. */ | ||
309 | rcu_read_lock(); | 319 | rcu_read_lock(); |
310 | |||
311 | spin_lock(&netlbl_domhsh_lock); | 320 | spin_lock(&netlbl_domhsh_lock); |
312 | if (entry->domain != NULL) | 321 | if (entry->domain != NULL) |
313 | entry_old = netlbl_domhsh_search(entry->domain); | 322 | entry_old = netlbl_domhsh_search(entry->domain); |
@@ -315,7 +324,6 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry, | |||
315 | entry_old = netlbl_domhsh_search_def(entry->domain); | 324 | entry_old = netlbl_domhsh_search_def(entry->domain); |
316 | if (entry_old == NULL) { | 325 | if (entry_old == NULL) { |
317 | entry->valid = 1; | 326 | entry->valid = 1; |
318 | INIT_RCU_HEAD(&entry->rcu); | ||
319 | 327 | ||
320 | if (entry->domain != NULL) { | 328 | if (entry->domain != NULL) { |
321 | u32 bkt = netlbl_domhsh_hash(entry->domain); | 329 | u32 bkt = netlbl_domhsh_hash(entry->domain); |
@@ -682,7 +690,7 @@ struct netlbl_domaddr6_map *netlbl_domhsh_getentry_af6(const char *domain, | |||
682 | * buckets and @skip_chain entries. For each entry in the table call | 690 | * buckets and @skip_chain entries. For each entry in the table call |
683 | * @callback, if @callback returns a negative value stop 'walking' through the | 691 | * @callback, if @callback returns a negative value stop 'walking' through the |
684 | * table and return. Updates the values in @skip_bkt and @skip_chain on | 692 | * table and return. Updates the values in @skip_bkt and @skip_chain on |
685 | * return. Returns zero on succcess, negative values on failure. | 693 | * return. Returns zero on success, negative values on failure. |
686 | * | 694 | * |
687 | */ | 695 | */ |
688 | int netlbl_domhsh_walk(u32 *skip_bkt, | 696 | int netlbl_domhsh_walk(u32 *skip_bkt, |
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c index 6ce00205f342..1b83e0009d8d 100644 --- a/net/netlabel/netlabel_kapi.c +++ b/net/netlabel/netlabel_kapi.c | |||
@@ -30,6 +30,7 @@ | |||
30 | 30 | ||
31 | #include <linux/init.h> | 31 | #include <linux/init.h> |
32 | #include <linux/types.h> | 32 | #include <linux/types.h> |
33 | #include <linux/slab.h> | ||
33 | #include <linux/audit.h> | 34 | #include <linux/audit.h> |
34 | #include <linux/in.h> | 35 | #include <linux/in.h> |
35 | #include <linux/in6.h> | 36 | #include <linux/in6.h> |
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c index 8203623e65ad..998e85e895d0 100644 --- a/net/netlabel/netlabel_mgmt.c +++ b/net/netlabel/netlabel_mgmt.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/skbuff.h> | 34 | #include <linux/skbuff.h> |
35 | #include <linux/in.h> | 35 | #include <linux/in.h> |
36 | #include <linux/in6.h> | 36 | #include <linux/in6.h> |
37 | #include <linux/slab.h> | ||
37 | #include <net/sock.h> | 38 | #include <net/sock.h> |
38 | #include <net/netlink.h> | 39 | #include <net/netlink.h> |
39 | #include <net/genetlink.h> | 40 | #include <net/genetlink.h> |
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index fb357f010189..a3d64aabe2f7 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <linux/notifier.h> | 43 | #include <linux/notifier.h> |
44 | #include <linux/netdevice.h> | 44 | #include <linux/netdevice.h> |
45 | #include <linux/security.h> | 45 | #include <linux/security.h> |
46 | #include <linux/slab.h> | ||
46 | #include <net/sock.h> | 47 | #include <net/sock.h> |
47 | #include <net/netlink.h> | 48 | #include <net/netlink.h> |
48 | #include <net/genetlink.h> | 49 | #include <net/genetlink.h> |
@@ -114,6 +115,9 @@ struct netlbl_unlhsh_walk_arg { | |||
114 | /* 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 |
115 | * hash table should be okay */ | 116 | * hash table should be okay */ |
116 | static DEFINE_SPINLOCK(netlbl_unlhsh_lock); | 117 | static 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)) | ||
117 | static struct netlbl_unlhsh_tbl *netlbl_unlhsh = NULL; | 121 | static struct netlbl_unlhsh_tbl *netlbl_unlhsh = NULL; |
118 | static struct netlbl_unlhsh_iface *netlbl_unlhsh_def = NULL; | 122 | static struct netlbl_unlhsh_iface *netlbl_unlhsh_def = NULL; |
119 | 123 | ||
@@ -235,15 +239,13 @@ static void netlbl_unlhsh_free_iface(struct rcu_head *entry) | |||
235 | * Description: | 239 | * Description: |
236 | * 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 |
237 | * 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 |
238 | * 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. | ||
239 | * | 244 | * |
240 | */ | 245 | */ |
241 | static u32 netlbl_unlhsh_hash(int ifindex) | 246 | static u32 netlbl_unlhsh_hash(int ifindex) |
242 | { | 247 | { |
243 | /* this is taken _almost_ directly from | 248 | return ifindex & (netlbl_unlhsh_rcu_deref(netlbl_unlhsh)->size - 1); |
244 | * security/selinux/netif.c:sel_netif_hasfn() as they do pretty much | ||
245 | * the same thing */ | ||
246 | return ifindex & (rcu_dereference(netlbl_unlhsh)->size - 1); | ||
247 | } | 249 | } |
248 | 250 | ||
249 | /** | 251 | /** |
@@ -253,7 +255,8 @@ static u32 netlbl_unlhsh_hash(int ifindex) | |||
253 | * Description: | 255 | * Description: |
254 | * 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 |
255 | * interface entry which matches @ifindex, otherwise NULL is returned. The | 257 | * interface entry which matches @ifindex, otherwise NULL is returned. The |
256 | * 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. | ||
257 | * | 260 | * |
258 | */ | 261 | */ |
259 | static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex) | 262 | static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex) |
@@ -263,7 +266,7 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex) | |||
263 | struct netlbl_unlhsh_iface *iter; | 266 | struct netlbl_unlhsh_iface *iter; |
264 | 267 | ||
265 | bkt = netlbl_unlhsh_hash(ifindex); | 268 | bkt = netlbl_unlhsh_hash(ifindex); |
266 | bkt_list = &rcu_dereference(netlbl_unlhsh)->tbl[bkt]; | 269 | bkt_list = &netlbl_unlhsh_rcu_deref(netlbl_unlhsh)->tbl[bkt]; |
267 | list_for_each_entry_rcu(iter, bkt_list, list) | 270 | list_for_each_entry_rcu(iter, bkt_list, list) |
268 | if (iter->valid && iter->ifindex == ifindex) | 271 | if (iter->valid && iter->ifindex == ifindex) |
269 | return iter; | 272 | return iter; |
@@ -272,33 +275,6 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex) | |||
272 | } | 275 | } |
273 | 276 | ||
274 | /** | 277 | /** |
275 | * netlbl_unlhsh_search_iface_def - Search for a matching interface entry | ||
276 | * @ifindex: the network interface | ||
277 | * | ||
278 | * Description: | ||
279 | * Searches the unlabeled connection hash table and returns a pointer to the | ||
280 | * interface entry which matches @ifindex. If an exact match can not be found | ||
281 | * and there is a valid default entry, the default entry is returned, otherwise | ||
282 | * NULL is returned. The caller is responsible for calling the | ||
283 | * rcu_read_[un]lock() functions. | ||
284 | * | ||
285 | */ | ||
286 | static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface_def(int ifindex) | ||
287 | { | ||
288 | struct netlbl_unlhsh_iface *entry; | ||
289 | |||
290 | entry = netlbl_unlhsh_search_iface(ifindex); | ||
291 | if (entry != NULL) | ||
292 | return entry; | ||
293 | |||
294 | entry = rcu_dereference(netlbl_unlhsh_def); | ||
295 | if (entry != NULL && entry->valid) | ||
296 | return entry; | ||
297 | |||
298 | return NULL; | ||
299 | } | ||
300 | |||
301 | /** | ||
302 | * 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 |
303 | * @iface: the associated interface entry | 279 | * @iface: the associated interface entry |
304 | * @addr: IPv4 address in network byte order | 280 | * @addr: IPv4 address in network byte order |
@@ -308,8 +284,7 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface_def(int ifindex) | |||
308 | * Description: | 284 | * Description: |
309 | * 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 |
310 | * interface entry specified by @iface. On success zero is returned, otherwise | 286 | * interface entry specified by @iface. On success zero is returned, otherwise |
311 | * a negative value is returned. The caller is responsible for calling the | 287 | * a negative value is returned. |
312 | * rcu_read_[un]lock() functions. | ||
313 | * | 288 | * |
314 | */ | 289 | */ |
315 | static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface, | 290 | static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface, |
@@ -327,7 +302,6 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface, | |||
327 | entry->list.addr = addr->s_addr & mask->s_addr; | 302 | entry->list.addr = addr->s_addr & mask->s_addr; |
328 | entry->list.mask = mask->s_addr; | 303 | entry->list.mask = mask->s_addr; |
329 | entry->list.valid = 1; | 304 | entry->list.valid = 1; |
330 | INIT_RCU_HEAD(&entry->rcu); | ||
331 | entry->secid = secid; | 305 | entry->secid = secid; |
332 | 306 | ||
333 | spin_lock(&netlbl_unlhsh_lock); | 307 | spin_lock(&netlbl_unlhsh_lock); |
@@ -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 | */ |
357 | static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface, | 330 | static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface, |
@@ -373,7 +346,6 @@ static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface, | |||
373 | entry->list.addr.s6_addr32[3] &= mask->s6_addr32[3]; | 346 | entry->list.addr.s6_addr32[3] &= mask->s6_addr32[3]; |
374 | ipv6_addr_copy(&entry->list.mask, mask); | 347 | ipv6_addr_copy(&entry->list.mask, mask); |
375 | entry->list.valid = 1; | 348 | entry->list.valid = 1; |
376 | INIT_RCU_HEAD(&entry->rcu); | ||
377 | entry->secid = secid; | 349 | entry->secid = secid; |
378 | 350 | ||
379 | spin_lock(&netlbl_unlhsh_lock); | 351 | spin_lock(&netlbl_unlhsh_lock); |
@@ -393,8 +365,7 @@ static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface, | |||
393 | * Description: | 365 | * Description: |
394 | * 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. |
395 | * 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 |
396 | * is returned. The caller is responsible for calling the rcu_read_[un]lock() | 368 | * is returned. |
397 | * functions. | ||
398 | * | 369 | * |
399 | */ | 370 | */ |
400 | static struct netlbl_unlhsh_iface *netlbl_unlhsh_add_iface(int ifindex) | 371 | static struct netlbl_unlhsh_iface *netlbl_unlhsh_add_iface(int ifindex) |
@@ -410,7 +381,6 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_add_iface(int ifindex) | |||
410 | INIT_LIST_HEAD(&iface->addr4_list); | 381 | INIT_LIST_HEAD(&iface->addr4_list); |
411 | INIT_LIST_HEAD(&iface->addr6_list); | 382 | INIT_LIST_HEAD(&iface->addr6_list); |
412 | iface->valid = 1; | 383 | iface->valid = 1; |
413 | INIT_RCU_HEAD(&iface->rcu); | ||
414 | 384 | ||
415 | spin_lock(&netlbl_unlhsh_lock); | 385 | spin_lock(&netlbl_unlhsh_lock); |
416 | if (ifindex > 0) { | 386 | if (ifindex > 0) { |
@@ -418,10 +388,10 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_add_iface(int ifindex) | |||
418 | if (netlbl_unlhsh_search_iface(ifindex) != NULL) | 388 | if (netlbl_unlhsh_search_iface(ifindex) != NULL) |
419 | goto add_iface_failure; | 389 | goto add_iface_failure; |
420 | list_add_tail_rcu(&iface->list, | 390 | list_add_tail_rcu(&iface->list, |
421 | &rcu_dereference(netlbl_unlhsh)->tbl[bkt]); | 391 | &netlbl_unlhsh_rcu_deref(netlbl_unlhsh)->tbl[bkt]); |
422 | } else { | 392 | } else { |
423 | INIT_LIST_HEAD(&iface->list); | 393 | INIT_LIST_HEAD(&iface->list); |
424 | if (rcu_dereference(netlbl_unlhsh_def) != NULL) | 394 | if (netlbl_unlhsh_rcu_deref(netlbl_unlhsh_def) != NULL) |
425 | goto add_iface_failure; | 395 | goto add_iface_failure; |
426 | rcu_assign_pointer(netlbl_unlhsh_def, iface); | 396 | rcu_assign_pointer(netlbl_unlhsh_def, iface); |
427 | } | 397 | } |
@@ -472,13 +442,12 @@ int netlbl_unlhsh_add(struct net *net, | |||
472 | 442 | ||
473 | rcu_read_lock(); | 443 | rcu_read_lock(); |
474 | if (dev_name != NULL) { | 444 | if (dev_name != NULL) { |
475 | dev = dev_get_by_name(net, dev_name); | 445 | dev = dev_get_by_name_rcu(net, dev_name); |
476 | if (dev == NULL) { | 446 | if (dev == NULL) { |
477 | ret_val = -ENODEV; | 447 | ret_val = -ENODEV; |
478 | goto unlhsh_add_return; | 448 | goto unlhsh_add_return; |
479 | } | 449 | } |
480 | ifindex = dev->ifindex; | 450 | ifindex = dev->ifindex; |
481 | dev_put(dev); | ||
482 | iface = netlbl_unlhsh_search_iface(ifindex); | 451 | iface = netlbl_unlhsh_search_iface(ifindex); |
483 | } else { | 452 | } else { |
484 | ifindex = 0; | 453 | ifindex = 0; |
@@ -552,8 +521,7 @@ unlhsh_add_return: | |||
552 | * | 521 | * |
553 | * Description: | 522 | * Description: |
554 | * Remove an IP address entry from the unlabeled connection hash table. | 523 | * Remove an IP address entry from the unlabeled connection hash table. |
555 | * Returns zero on success, negative values on failure. The caller is | 524 | * Returns zero on success, negative values on failure. |
556 | * responsible for calling the rcu_read_[un]lock() functions. | ||
557 | * | 525 | * |
558 | */ | 526 | */ |
559 | static int netlbl_unlhsh_remove_addr4(struct net *net, | 527 | static int netlbl_unlhsh_remove_addr4(struct net *net, |
@@ -615,8 +583,7 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, | |||
615 | * | 583 | * |
616 | * Description: | 584 | * Description: |
617 | * Remove an IP address entry from the unlabeled connection hash table. | 585 | * Remove an IP address entry from the unlabeled connection hash table. |
618 | * Returns zero on success, negative values on failure. The caller is | 586 | * Returns zero on success, negative values on failure. |
619 | * responsible for calling the rcu_read_[un]lock() functions. | ||
620 | * | 587 | * |
621 | */ | 588 | */ |
622 | static int netlbl_unlhsh_remove_addr6(struct net *net, | 589 | static int netlbl_unlhsh_remove_addr6(struct net *net, |
@@ -737,13 +704,12 @@ int netlbl_unlhsh_remove(struct net *net, | |||
737 | 704 | ||
738 | rcu_read_lock(); | 705 | rcu_read_lock(); |
739 | if (dev_name != NULL) { | 706 | if (dev_name != NULL) { |
740 | dev = dev_get_by_name(net, dev_name); | 707 | dev = dev_get_by_name_rcu(net, dev_name); |
741 | if (dev == NULL) { | 708 | if (dev == NULL) { |
742 | ret_val = -ENODEV; | 709 | ret_val = -ENODEV; |
743 | goto unlhsh_remove_return; | 710 | goto unlhsh_remove_return; |
744 | } | 711 | } |
745 | iface = netlbl_unlhsh_search_iface(dev->ifindex); | 712 | iface = netlbl_unlhsh_search_iface(dev->ifindex); |
746 | dev_put(dev); | ||
747 | } else | 713 | } else |
748 | iface = rcu_dereference(netlbl_unlhsh_def); | 714 | iface = rcu_dereference(netlbl_unlhsh_def); |
749 | if (iface == NULL) { | 715 | if (iface == NULL) { |
@@ -1552,8 +1518,10 @@ int netlbl_unlabel_getattr(const struct sk_buff *skb, | |||
1552 | struct netlbl_unlhsh_iface *iface; | 1518 | struct netlbl_unlhsh_iface *iface; |
1553 | 1519 | ||
1554 | rcu_read_lock(); | 1520 | rcu_read_lock(); |
1555 | iface = netlbl_unlhsh_search_iface_def(skb->iif); | 1521 | iface = netlbl_unlhsh_search_iface(skb->skb_iif); |
1556 | if (iface == NULL) | 1522 | if (iface == NULL) |
1523 | iface = rcu_dereference(netlbl_unlhsh_def); | ||
1524 | if (iface == NULL || !iface->valid) | ||
1557 | goto unlabel_getattr_nolabel; | 1525 | goto unlabel_getattr_nolabel; |
1558 | switch (family) { | 1526 | switch (family) { |
1559 | case PF_INET: { | 1527 | case PF_INET: { |
diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c index 68706b4e3bf8..a3fd75ac3fa5 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/audit.h> | 35 | #include <linux/audit.h> |
36 | #include <linux/tty.h> | 36 | #include <linux/tty.h> |
37 | #include <linux/security.h> | 37 | #include <linux/security.h> |
38 | #include <linux/gfp.h> | ||
38 | #include <net/sock.h> | 39 | #include <net/sock.h> |
39 | #include <net/netlink.h> | 40 | #include <net/netlink.h> |
40 | #include <net/genetlink.h> | 41 | #include <net/genetlink.h> |