aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-04-05 19:41:22 -0400
committerIngo Molnar <mingo@elte.hu>2009-04-05 19:41:22 -0400
commit9efe21cb82b5dbe3b0b2ae4de4eccc64ecb94e95 (patch)
tree7ff8833745d2f268f897f6fa4a27263b4a572245 /security/selinux
parentde18836e447c2dc30120c0919b8db8ddc0401cc4 (diff)
parent0221c81b1b8eb0cbb6b30a0ced52ead32d2b4e4c (diff)
Merge branch 'linus' into irq/threaded
Conflicts: include/linux/irq.h kernel/irq/handle.c
Diffstat (limited to 'security/selinux')
-rw-r--r--security/selinux/avc.c169
-rw-r--r--security/selinux/hooks.c515
-rw-r--r--security/selinux/include/av_perm_to_string.h2
-rw-r--r--security/selinux/include/av_permissions.h2
-rw-r--r--security/selinux/include/netlabel.h27
-rw-r--r--security/selinux/include/objsec.h2
-rw-r--r--security/selinux/include/security.h9
-rw-r--r--security/selinux/netlabel.c186
-rw-r--r--security/selinux/nlmsgtab.c2
-rw-r--r--security/selinux/selinuxfs.c70
-rw-r--r--security/selinux/ss/services.c2
11 files changed, 304 insertions, 682 deletions
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index eb41f43e2772..7f9b5fac8779 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -88,17 +88,16 @@ struct avc_entry {
88 u32 tsid; 88 u32 tsid;
89 u16 tclass; 89 u16 tclass;
90 struct av_decision avd; 90 struct av_decision avd;
91 atomic_t used; /* used recently */
92}; 91};
93 92
94struct avc_node { 93struct avc_node {
95 struct avc_entry ae; 94 struct avc_entry ae;
96 struct list_head list; 95 struct hlist_node list; /* anchored in avc_cache->slots[i] */
97 struct rcu_head rhead; 96 struct rcu_head rhead;
98}; 97};
99 98
100struct avc_cache { 99struct avc_cache {
101 struct list_head slots[AVC_CACHE_SLOTS]; 100 struct hlist_head slots[AVC_CACHE_SLOTS]; /* head for avc_node->list */
102 spinlock_t slots_lock[AVC_CACHE_SLOTS]; /* lock for writes */ 101 spinlock_t slots_lock[AVC_CACHE_SLOTS]; /* lock for writes */
103 atomic_t lru_hint; /* LRU hint for reclaim scan */ 102 atomic_t lru_hint; /* LRU hint for reclaim scan */
104 atomic_t active_nodes; 103 atomic_t active_nodes;
@@ -234,7 +233,7 @@ void __init avc_init(void)
234 int i; 233 int i;
235 234
236 for (i = 0; i < AVC_CACHE_SLOTS; i++) { 235 for (i = 0; i < AVC_CACHE_SLOTS; i++) {
237 INIT_LIST_HEAD(&avc_cache.slots[i]); 236 INIT_HLIST_HEAD(&avc_cache.slots[i]);
238 spin_lock_init(&avc_cache.slots_lock[i]); 237 spin_lock_init(&avc_cache.slots_lock[i]);
239 } 238 }
240 atomic_set(&avc_cache.active_nodes, 0); 239 atomic_set(&avc_cache.active_nodes, 0);
@@ -250,16 +249,20 @@ int avc_get_hash_stats(char *page)
250{ 249{
251 int i, chain_len, max_chain_len, slots_used; 250 int i, chain_len, max_chain_len, slots_used;
252 struct avc_node *node; 251 struct avc_node *node;
252 struct hlist_head *head;
253 253
254 rcu_read_lock(); 254 rcu_read_lock();
255 255
256 slots_used = 0; 256 slots_used = 0;
257 max_chain_len = 0; 257 max_chain_len = 0;
258 for (i = 0; i < AVC_CACHE_SLOTS; i++) { 258 for (i = 0; i < AVC_CACHE_SLOTS; i++) {
259 if (!list_empty(&avc_cache.slots[i])) { 259 head = &avc_cache.slots[i];
260 if (!hlist_empty(head)) {
261 struct hlist_node *next;
262
260 slots_used++; 263 slots_used++;
261 chain_len = 0; 264 chain_len = 0;
262 list_for_each_entry_rcu(node, &avc_cache.slots[i], list) 265 hlist_for_each_entry_rcu(node, next, head, list)
263 chain_len++; 266 chain_len++;
264 if (chain_len > max_chain_len) 267 if (chain_len > max_chain_len)
265 max_chain_len = chain_len; 268 max_chain_len = chain_len;
@@ -283,7 +286,7 @@ static void avc_node_free(struct rcu_head *rhead)
283 286
284static void avc_node_delete(struct avc_node *node) 287static void avc_node_delete(struct avc_node *node)
285{ 288{
286 list_del_rcu(&node->list); 289 hlist_del_rcu(&node->list);
287 call_rcu(&node->rhead, avc_node_free); 290 call_rcu(&node->rhead, avc_node_free);
288 atomic_dec(&avc_cache.active_nodes); 291 atomic_dec(&avc_cache.active_nodes);
289} 292}
@@ -297,7 +300,7 @@ static void avc_node_kill(struct avc_node *node)
297 300
298static void avc_node_replace(struct avc_node *new, struct avc_node *old) 301static void avc_node_replace(struct avc_node *new, struct avc_node *old)
299{ 302{
300 list_replace_rcu(&old->list, &new->list); 303 hlist_replace_rcu(&old->list, &new->list);
301 call_rcu(&old->rhead, avc_node_free); 304 call_rcu(&old->rhead, avc_node_free);
302 atomic_dec(&avc_cache.active_nodes); 305 atomic_dec(&avc_cache.active_nodes);
303} 306}
@@ -307,29 +310,31 @@ static inline int avc_reclaim_node(void)
307 struct avc_node *node; 310 struct avc_node *node;
308 int hvalue, try, ecx; 311 int hvalue, try, ecx;
309 unsigned long flags; 312 unsigned long flags;
313 struct hlist_head *head;
314 struct hlist_node *next;
315 spinlock_t *lock;
310 316
311 for (try = 0, ecx = 0; try < AVC_CACHE_SLOTS; try++) { 317 for (try = 0, ecx = 0; try < AVC_CACHE_SLOTS; try++) {
312 hvalue = atomic_inc_return(&avc_cache.lru_hint) & (AVC_CACHE_SLOTS - 1); 318 hvalue = atomic_inc_return(&avc_cache.lru_hint) & (AVC_CACHE_SLOTS - 1);
319 head = &avc_cache.slots[hvalue];
320 lock = &avc_cache.slots_lock[hvalue];
313 321
314 if (!spin_trylock_irqsave(&avc_cache.slots_lock[hvalue], flags)) 322 if (!spin_trylock_irqsave(lock, flags))
315 continue; 323 continue;
316 324
317 rcu_read_lock(); 325 rcu_read_lock();
318 list_for_each_entry(node, &avc_cache.slots[hvalue], list) { 326 hlist_for_each_entry(node, next, head, list) {
319 if (atomic_dec_and_test(&node->ae.used)) { 327 avc_node_delete(node);
320 /* Recently Unused */ 328 avc_cache_stats_incr(reclaims);
321 avc_node_delete(node); 329 ecx++;
322 avc_cache_stats_incr(reclaims); 330 if (ecx >= AVC_CACHE_RECLAIM) {
323 ecx++; 331 rcu_read_unlock();
324 if (ecx >= AVC_CACHE_RECLAIM) { 332 spin_unlock_irqrestore(lock, flags);
325 rcu_read_unlock(); 333 goto out;
326 spin_unlock_irqrestore(&avc_cache.slots_lock[hvalue], flags);
327 goto out;
328 }
329 } 334 }
330 } 335 }
331 rcu_read_unlock(); 336 rcu_read_unlock();
332 spin_unlock_irqrestore(&avc_cache.slots_lock[hvalue], flags); 337 spin_unlock_irqrestore(lock, flags);
333 } 338 }
334out: 339out:
335 return ecx; 340 return ecx;
@@ -344,8 +349,7 @@ static struct avc_node *avc_alloc_node(void)
344 goto out; 349 goto out;
345 350
346 INIT_RCU_HEAD(&node->rhead); 351 INIT_RCU_HEAD(&node->rhead);
347 INIT_LIST_HEAD(&node->list); 352 INIT_HLIST_NODE(&node->list);
348 atomic_set(&node->ae.used, 1);
349 avc_cache_stats_incr(allocations); 353 avc_cache_stats_incr(allocations);
350 354
351 if (atomic_inc_return(&avc_cache.active_nodes) > avc_cache_threshold) 355 if (atomic_inc_return(&avc_cache.active_nodes) > avc_cache_threshold)
@@ -355,21 +359,24 @@ out:
355 return node; 359 return node;
356} 360}
357 361
358static void avc_node_populate(struct avc_node *node, u32 ssid, u32 tsid, u16 tclass, struct avc_entry *ae) 362static void avc_node_populate(struct avc_node *node, u32 ssid, u32 tsid, u16 tclass, struct av_decision *avd)
359{ 363{
360 node->ae.ssid = ssid; 364 node->ae.ssid = ssid;
361 node->ae.tsid = tsid; 365 node->ae.tsid = tsid;
362 node->ae.tclass = tclass; 366 node->ae.tclass = tclass;
363 memcpy(&node->ae.avd, &ae->avd, sizeof(node->ae.avd)); 367 memcpy(&node->ae.avd, avd, sizeof(node->ae.avd));
364} 368}
365 369
366static inline struct avc_node *avc_search_node(u32 ssid, u32 tsid, u16 tclass) 370static inline struct avc_node *avc_search_node(u32 ssid, u32 tsid, u16 tclass)
367{ 371{
368 struct avc_node *node, *ret = NULL; 372 struct avc_node *node, *ret = NULL;
369 int hvalue; 373 int hvalue;
374 struct hlist_head *head;
375 struct hlist_node *next;
370 376
371 hvalue = avc_hash(ssid, tsid, tclass); 377 hvalue = avc_hash(ssid, tsid, tclass);
372 list_for_each_entry_rcu(node, &avc_cache.slots[hvalue], list) { 378 head = &avc_cache.slots[hvalue];
379 hlist_for_each_entry_rcu(node, next, head, list) {
373 if (ssid == node->ae.ssid && 380 if (ssid == node->ae.ssid &&
374 tclass == node->ae.tclass && 381 tclass == node->ae.tclass &&
375 tsid == node->ae.tsid) { 382 tsid == node->ae.tsid) {
@@ -378,15 +385,6 @@ static inline struct avc_node *avc_search_node(u32 ssid, u32 tsid, u16 tclass)
378 } 385 }
379 } 386 }
380 387
381 if (ret == NULL) {
382 /* cache miss */
383 goto out;
384 }
385
386 /* cache hit */
387 if (atomic_read(&ret->ae.used) != 1)
388 atomic_set(&ret->ae.used, 1);
389out:
390 return ret; 388 return ret;
391} 389}
392 390
@@ -395,30 +393,25 @@ out:
395 * @ssid: source security identifier 393 * @ssid: source security identifier
396 * @tsid: target security identifier 394 * @tsid: target security identifier
397 * @tclass: target security class 395 * @tclass: target security class
398 * @requested: requested permissions, interpreted based on @tclass
399 * 396 *
400 * Look up an AVC entry that is valid for the 397 * Look up an AVC entry that is valid for the
401 * @requested permissions between the SID pair
402 * (@ssid, @tsid), interpreting the permissions 398 * (@ssid, @tsid), interpreting the permissions
403 * based on @tclass. If a valid AVC entry exists, 399 * based on @tclass. If a valid AVC entry exists,
404 * then this function return the avc_node. 400 * then this function return the avc_node.
405 * Otherwise, this function returns NULL. 401 * Otherwise, this function returns NULL.
406 */ 402 */
407static struct avc_node *avc_lookup(u32 ssid, u32 tsid, u16 tclass, u32 requested) 403static struct avc_node *avc_lookup(u32 ssid, u32 tsid, u16 tclass)
408{ 404{
409 struct avc_node *node; 405 struct avc_node *node;
410 406
411 avc_cache_stats_incr(lookups); 407 avc_cache_stats_incr(lookups);
412 node = avc_search_node(ssid, tsid, tclass); 408 node = avc_search_node(ssid, tsid, tclass);
413 409
414 if (node && ((node->ae.avd.decided & requested) == requested)) { 410 if (node)
415 avc_cache_stats_incr(hits); 411 avc_cache_stats_incr(hits);
416 goto out; 412 else
417 } 413 avc_cache_stats_incr(misses);
418 414
419 node = NULL;
420 avc_cache_stats_incr(misses);
421out:
422 return node; 415 return node;
423} 416}
424 417
@@ -449,34 +442,41 @@ static int avc_latest_notif_update(int seqno, int is_insert)
449 * @ssid: source security identifier 442 * @ssid: source security identifier
450 * @tsid: target security identifier 443 * @tsid: target security identifier
451 * @tclass: target security class 444 * @tclass: target security class
452 * @ae: AVC entry 445 * @avd: resulting av decision
453 * 446 *
454 * Insert an AVC entry for the SID pair 447 * Insert an AVC entry for the SID pair
455 * (@ssid, @tsid) and class @tclass. 448 * (@ssid, @tsid) and class @tclass.
456 * The access vectors and the sequence number are 449 * The access vectors and the sequence number are
457 * normally provided by the security server in 450 * normally provided by the security server in
458 * response to a security_compute_av() call. If the 451 * response to a security_compute_av() call. If the
459 * sequence number @ae->avd.seqno is not less than the latest 452 * sequence number @avd->seqno is not less than the latest
460 * revocation notification, then the function copies 453 * revocation notification, then the function copies
461 * the access vectors into a cache entry, returns 454 * the access vectors into a cache entry, returns
462 * avc_node inserted. Otherwise, this function returns NULL. 455 * avc_node inserted. Otherwise, this function returns NULL.
463 */ 456 */
464static struct avc_node *avc_insert(u32 ssid, u32 tsid, u16 tclass, struct avc_entry *ae) 457static struct avc_node *avc_insert(u32 ssid, u32 tsid, u16 tclass, struct av_decision *avd)
465{ 458{
466 struct avc_node *pos, *node = NULL; 459 struct avc_node *pos, *node = NULL;
467 int hvalue; 460 int hvalue;
468 unsigned long flag; 461 unsigned long flag;
469 462
470 if (avc_latest_notif_update(ae->avd.seqno, 1)) 463 if (avc_latest_notif_update(avd->seqno, 1))
471 goto out; 464 goto out;
472 465
473 node = avc_alloc_node(); 466 node = avc_alloc_node();
474 if (node) { 467 if (node) {
468 struct hlist_head *head;
469 struct hlist_node *next;
470 spinlock_t *lock;
471
475 hvalue = avc_hash(ssid, tsid, tclass); 472 hvalue = avc_hash(ssid, tsid, tclass);
476 avc_node_populate(node, ssid, tsid, tclass, ae); 473 avc_node_populate(node, ssid, tsid, tclass, avd);
474
475 head = &avc_cache.slots[hvalue];
476 lock = &avc_cache.slots_lock[hvalue];
477 477
478 spin_lock_irqsave(&avc_cache.slots_lock[hvalue], flag); 478 spin_lock_irqsave(lock, flag);
479 list_for_each_entry(pos, &avc_cache.slots[hvalue], list) { 479 hlist_for_each_entry(pos, next, head, list) {
480 if (pos->ae.ssid == ssid && 480 if (pos->ae.ssid == ssid &&
481 pos->ae.tsid == tsid && 481 pos->ae.tsid == tsid &&
482 pos->ae.tclass == tclass) { 482 pos->ae.tclass == tclass) {
@@ -484,9 +484,9 @@ static struct avc_node *avc_insert(u32 ssid, u32 tsid, u16 tclass, struct avc_en
484 goto found; 484 goto found;
485 } 485 }
486 } 486 }
487 list_add_rcu(&node->list, &avc_cache.slots[hvalue]); 487 hlist_add_head_rcu(&node->list, head);
488found: 488found:
489 spin_unlock_irqrestore(&avc_cache.slots_lock[hvalue], flag); 489 spin_unlock_irqrestore(lock, flag);
490 } 490 }
491out: 491out:
492 return node; 492 return node;
@@ -742,17 +742,22 @@ static inline int avc_sidcmp(u32 x, u32 y)
742 * @event : Updating event 742 * @event : Updating event
743 * @perms : Permission mask bits 743 * @perms : Permission mask bits
744 * @ssid,@tsid,@tclass : identifier of an AVC entry 744 * @ssid,@tsid,@tclass : identifier of an AVC entry
745 * @seqno : sequence number when decision was made
745 * 746 *
746 * if a valid AVC entry doesn't exist,this function returns -ENOENT. 747 * if a valid AVC entry doesn't exist,this function returns -ENOENT.
747 * if kmalloc() called internal returns NULL, this function returns -ENOMEM. 748 * if kmalloc() called internal returns NULL, this function returns -ENOMEM.
748 * otherwise, this function update the AVC entry. The original AVC-entry object 749 * otherwise, this function update the AVC entry. The original AVC-entry object
749 * will release later by RCU. 750 * will release later by RCU.
750 */ 751 */
751static int avc_update_node(u32 event, u32 perms, u32 ssid, u32 tsid, u16 tclass) 752static int avc_update_node(u32 event, u32 perms, u32 ssid, u32 tsid, u16 tclass,
753 u32 seqno)
752{ 754{
753 int hvalue, rc = 0; 755 int hvalue, rc = 0;
754 unsigned long flag; 756 unsigned long flag;
755 struct avc_node *pos, *node, *orig = NULL; 757 struct avc_node *pos, *node, *orig = NULL;
758 struct hlist_head *head;
759 struct hlist_node *next;
760 spinlock_t *lock;
756 761
757 node = avc_alloc_node(); 762 node = avc_alloc_node();
758 if (!node) { 763 if (!node) {
@@ -762,12 +767,17 @@ static int avc_update_node(u32 event, u32 perms, u32 ssid, u32 tsid, u16 tclass)
762 767
763 /* Lock the target slot */ 768 /* Lock the target slot */
764 hvalue = avc_hash(ssid, tsid, tclass); 769 hvalue = avc_hash(ssid, tsid, tclass);
765 spin_lock_irqsave(&avc_cache.slots_lock[hvalue], flag);
766 770
767 list_for_each_entry(pos, &avc_cache.slots[hvalue], list) { 771 head = &avc_cache.slots[hvalue];
772 lock = &avc_cache.slots_lock[hvalue];
773
774 spin_lock_irqsave(lock, flag);
775
776 hlist_for_each_entry(pos, next, head, list) {
768 if (ssid == pos->ae.ssid && 777 if (ssid == pos->ae.ssid &&
769 tsid == pos->ae.tsid && 778 tsid == pos->ae.tsid &&
770 tclass == pos->ae.tclass){ 779 tclass == pos->ae.tclass &&
780 seqno == pos->ae.avd.seqno){
771 orig = pos; 781 orig = pos;
772 break; 782 break;
773 } 783 }
@@ -783,7 +793,7 @@ static int avc_update_node(u32 event, u32 perms, u32 ssid, u32 tsid, u16 tclass)
783 * Copy and replace original node. 793 * Copy and replace original node.
784 */ 794 */
785 795
786 avc_node_populate(node, ssid, tsid, tclass, &orig->ae); 796 avc_node_populate(node, ssid, tsid, tclass, &orig->ae.avd);
787 797
788 switch (event) { 798 switch (event) {
789 case AVC_CALLBACK_GRANT: 799 case AVC_CALLBACK_GRANT:
@@ -808,7 +818,7 @@ static int avc_update_node(u32 event, u32 perms, u32 ssid, u32 tsid, u16 tclass)
808 } 818 }
809 avc_node_replace(node, orig); 819 avc_node_replace(node, orig);
810out_unlock: 820out_unlock:
811 spin_unlock_irqrestore(&avc_cache.slots_lock[hvalue], flag); 821 spin_unlock_irqrestore(lock, flag);
812out: 822out:
813 return rc; 823 return rc;
814} 824}
@@ -823,18 +833,24 @@ int avc_ss_reset(u32 seqno)
823 int i, rc = 0, tmprc; 833 int i, rc = 0, tmprc;
824 unsigned long flag; 834 unsigned long flag;
825 struct avc_node *node; 835 struct avc_node *node;
836 struct hlist_head *head;
837 struct hlist_node *next;
838 spinlock_t *lock;
826 839
827 for (i = 0; i < AVC_CACHE_SLOTS; i++) { 840 for (i = 0; i < AVC_CACHE_SLOTS; i++) {
828 spin_lock_irqsave(&avc_cache.slots_lock[i], flag); 841 head = &avc_cache.slots[i];
842 lock = &avc_cache.slots_lock[i];
843
844 spin_lock_irqsave(lock, flag);
829 /* 845 /*
830 * With preemptable RCU, the outer spinlock does not 846 * With preemptable RCU, the outer spinlock does not
831 * prevent RCU grace periods from ending. 847 * prevent RCU grace periods from ending.
832 */ 848 */
833 rcu_read_lock(); 849 rcu_read_lock();
834 list_for_each_entry(node, &avc_cache.slots[i], list) 850 hlist_for_each_entry(node, next, head, list)
835 avc_node_delete(node); 851 avc_node_delete(node);
836 rcu_read_unlock(); 852 rcu_read_unlock();
837 spin_unlock_irqrestore(&avc_cache.slots_lock[i], flag); 853 spin_unlock_irqrestore(lock, flag);
838 } 854 }
839 855
840 for (c = avc_callbacks; c; c = c->next) { 856 for (c = avc_callbacks; c; c = c->next) {
@@ -875,10 +891,10 @@ int avc_ss_reset(u32 seqno)
875int avc_has_perm_noaudit(u32 ssid, u32 tsid, 891int avc_has_perm_noaudit(u32 ssid, u32 tsid,
876 u16 tclass, u32 requested, 892 u16 tclass, u32 requested,
877 unsigned flags, 893 unsigned flags,
878 struct av_decision *avd) 894 struct av_decision *in_avd)
879{ 895{
880 struct avc_node *node; 896 struct avc_node *node;
881 struct avc_entry entry, *p_ae; 897 struct av_decision avd_entry, *avd;
882 int rc = 0; 898 int rc = 0;
883 u32 denied; 899 u32 denied;
884 900
@@ -886,29 +902,34 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid,
886 902
887 rcu_read_lock(); 903 rcu_read_lock();
888 904
889 node = avc_lookup(ssid, tsid, tclass, requested); 905 node = avc_lookup(ssid, tsid, tclass);
890 if (!node) { 906 if (!node) {
891 rcu_read_unlock(); 907 rcu_read_unlock();
892 rc = security_compute_av(ssid, tsid, tclass, requested, &entry.avd); 908
909 if (in_avd)
910 avd = in_avd;
911 else
912 avd = &avd_entry;
913
914 rc = security_compute_av(ssid, tsid, tclass, requested, avd);
893 if (rc) 915 if (rc)
894 goto out; 916 goto out;
895 rcu_read_lock(); 917 rcu_read_lock();
896 node = avc_insert(ssid, tsid, tclass, &entry); 918 node = avc_insert(ssid, tsid, tclass, avd);
919 } else {
920 if (in_avd)
921 memcpy(in_avd, &node->ae.avd, sizeof(*in_avd));
922 avd = &node->ae.avd;
897 } 923 }
898 924
899 p_ae = node ? &node->ae : &entry; 925 denied = requested & ~(avd->allowed);
900
901 if (avd)
902 memcpy(avd, &p_ae->avd, sizeof(*avd));
903
904 denied = requested & ~(p_ae->avd.allowed);
905 926
906 if (denied) { 927 if (denied) {
907 if (flags & AVC_STRICT) 928 if (flags & AVC_STRICT)
908 rc = -EACCES; 929 rc = -EACCES;
909 else if (!selinux_enforcing || security_permissive_sid(ssid)) 930 else if (!selinux_enforcing || security_permissive_sid(ssid))
910 avc_update_node(AVC_CALLBACK_GRANT, requested, ssid, 931 avc_update_node(AVC_CALLBACK_GRANT, requested, ssid,
911 tsid, tclass); 932 tsid, tclass, avd->seqno);
912 else 933 else
913 rc = -EACCES; 934 rc = -EACCES;
914 } 935 }
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 00815973d412..ba808ef6babb 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -89,11 +89,10 @@
89#define XATTR_SELINUX_SUFFIX "selinux" 89#define XATTR_SELINUX_SUFFIX "selinux"
90#define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX 90#define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX
91 91
92#define NUM_SEL_MNT_OPTS 4 92#define NUM_SEL_MNT_OPTS 5
93 93
94extern unsigned int policydb_loaded_version; 94extern unsigned int policydb_loaded_version;
95extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm); 95extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm);
96extern int selinux_compat_net;
97extern struct security_operations *security_ops; 96extern struct security_operations *security_ops;
98 97
99/* SECMARK reference count */ 98/* SECMARK reference count */
@@ -311,7 +310,7 @@ static int sk_alloc_security(struct sock *sk, int family, gfp_t priority)
311 ssec->sid = SECINITSID_UNLABELED; 310 ssec->sid = SECINITSID_UNLABELED;
312 sk->sk_security = ssec; 311 sk->sk_security = ssec;
313 312
314 selinux_netlbl_sk_security_reset(ssec, family); 313 selinux_netlbl_sk_security_reset(ssec);
315 314
316 return 0; 315 return 0;
317} 316}
@@ -353,6 +352,7 @@ enum {
353 Opt_fscontext = 2, 352 Opt_fscontext = 2,
354 Opt_defcontext = 3, 353 Opt_defcontext = 3,
355 Opt_rootcontext = 4, 354 Opt_rootcontext = 4,
355 Opt_labelsupport = 5,
356}; 356};
357 357
358static const match_table_t tokens = { 358static const match_table_t tokens = {
@@ -360,6 +360,7 @@ static const match_table_t tokens = {
360 {Opt_fscontext, FSCONTEXT_STR "%s"}, 360 {Opt_fscontext, FSCONTEXT_STR "%s"},
361 {Opt_defcontext, DEFCONTEXT_STR "%s"}, 361 {Opt_defcontext, DEFCONTEXT_STR "%s"},
362 {Opt_rootcontext, ROOTCONTEXT_STR "%s"}, 362 {Opt_rootcontext, ROOTCONTEXT_STR "%s"},
363 {Opt_labelsupport, LABELSUPP_STR},
363 {Opt_error, NULL}, 364 {Opt_error, NULL},
364}; 365};
365 366
@@ -431,7 +432,7 @@ static int sb_finish_set_opts(struct super_block *sb)
431 } 432 }
432 } 433 }
433 434
434 sbsec->initialized = 1; 435 sbsec->flags |= (SE_SBINITIALIZED | SE_SBLABELSUPP);
435 436
436 if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors)) 437 if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors))
437 printk(KERN_ERR "SELinux: initialized (dev %s, type %s), unknown behavior\n", 438 printk(KERN_ERR "SELinux: initialized (dev %s, type %s), unknown behavior\n",
@@ -441,6 +442,12 @@ static int sb_finish_set_opts(struct super_block *sb)
441 sb->s_id, sb->s_type->name, 442 sb->s_id, sb->s_type->name,
442 labeling_behaviors[sbsec->behavior-1]); 443 labeling_behaviors[sbsec->behavior-1]);
443 444
445 if (sbsec->behavior == SECURITY_FS_USE_GENFS ||
446 sbsec->behavior == SECURITY_FS_USE_MNTPOINT ||
447 sbsec->behavior == SECURITY_FS_USE_NONE ||
448 sbsec->behavior > ARRAY_SIZE(labeling_behaviors))
449 sbsec->flags &= ~SE_SBLABELSUPP;
450
444 /* Initialize the root inode. */ 451 /* Initialize the root inode. */
445 rc = inode_doinit_with_dentry(root_inode, root); 452 rc = inode_doinit_with_dentry(root_inode, root);
446 453
@@ -487,23 +494,22 @@ static int selinux_get_mnt_opts(const struct super_block *sb,
487 494
488 security_init_mnt_opts(opts); 495 security_init_mnt_opts(opts);
489 496
490 if (!sbsec->initialized) 497 if (!(sbsec->flags & SE_SBINITIALIZED))
491 return -EINVAL; 498 return -EINVAL;
492 499
493 if (!ss_initialized) 500 if (!ss_initialized)
494 return -EINVAL; 501 return -EINVAL;
495 502
496 /* 503 tmp = sbsec->flags & SE_MNTMASK;
497 * if we ever use sbsec flags for anything other than tracking mount
498 * settings this is going to need a mask
499 */
500 tmp = sbsec->flags;
501 /* count the number of mount options for this sb */ 504 /* count the number of mount options for this sb */
502 for (i = 0; i < 8; i++) { 505 for (i = 0; i < 8; i++) {
503 if (tmp & 0x01) 506 if (tmp & 0x01)
504 opts->num_mnt_opts++; 507 opts->num_mnt_opts++;
505 tmp >>= 1; 508 tmp >>= 1;
506 } 509 }
510 /* Check if the Label support flag is set */
511 if (sbsec->flags & SE_SBLABELSUPP)
512 opts->num_mnt_opts++;
507 513
508 opts->mnt_opts = kcalloc(opts->num_mnt_opts, sizeof(char *), GFP_ATOMIC); 514 opts->mnt_opts = kcalloc(opts->num_mnt_opts, sizeof(char *), GFP_ATOMIC);
509 if (!opts->mnt_opts) { 515 if (!opts->mnt_opts) {
@@ -549,6 +555,10 @@ static int selinux_get_mnt_opts(const struct super_block *sb,
549 opts->mnt_opts[i] = context; 555 opts->mnt_opts[i] = context;
550 opts->mnt_opts_flags[i++] = ROOTCONTEXT_MNT; 556 opts->mnt_opts_flags[i++] = ROOTCONTEXT_MNT;
551 } 557 }
558 if (sbsec->flags & SE_SBLABELSUPP) {
559 opts->mnt_opts[i] = NULL;
560 opts->mnt_opts_flags[i++] = SE_SBLABELSUPP;
561 }
552 562
553 BUG_ON(i != opts->num_mnt_opts); 563 BUG_ON(i != opts->num_mnt_opts);
554 564
@@ -562,8 +572,10 @@ out_free:
562static int bad_option(struct superblock_security_struct *sbsec, char flag, 572static int bad_option(struct superblock_security_struct *sbsec, char flag,
563 u32 old_sid, u32 new_sid) 573 u32 old_sid, u32 new_sid)
564{ 574{
575 char mnt_flags = sbsec->flags & SE_MNTMASK;
576
565 /* check if the old mount command had the same options */ 577 /* check if the old mount command had the same options */
566 if (sbsec->initialized) 578 if (sbsec->flags & SE_SBINITIALIZED)
567 if (!(sbsec->flags & flag) || 579 if (!(sbsec->flags & flag) ||
568 (old_sid != new_sid)) 580 (old_sid != new_sid))
569 return 1; 581 return 1;
@@ -571,8 +583,8 @@ static int bad_option(struct superblock_security_struct *sbsec, char flag,
571 /* check if we were passed the same options twice, 583 /* check if we were passed the same options twice,
572 * aka someone passed context=a,context=b 584 * aka someone passed context=a,context=b
573 */ 585 */
574 if (!sbsec->initialized) 586 if (!(sbsec->flags & SE_SBINITIALIZED))
575 if (sbsec->flags & flag) 587 if (mnt_flags & flag)
576 return 1; 588 return 1;
577 return 0; 589 return 0;
578} 590}
@@ -626,7 +638,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
626 * this sb does not set any security options. (The first options 638 * this sb does not set any security options. (The first options
627 * will be used for both mounts) 639 * will be used for both mounts)
628 */ 640 */
629 if (sbsec->initialized && (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA) 641 if ((sbsec->flags & SE_SBINITIALIZED) && (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA)
630 && (num_opts == 0)) 642 && (num_opts == 0))
631 goto out; 643 goto out;
632 644
@@ -637,6 +649,9 @@ static int selinux_set_mnt_opts(struct super_block *sb,
637 */ 649 */
638 for (i = 0; i < num_opts; i++) { 650 for (i = 0; i < num_opts; i++) {
639 u32 sid; 651 u32 sid;
652
653 if (flags[i] == SE_SBLABELSUPP)
654 continue;
640 rc = security_context_to_sid(mount_options[i], 655 rc = security_context_to_sid(mount_options[i],
641 strlen(mount_options[i]), &sid); 656 strlen(mount_options[i]), &sid);
642 if (rc) { 657 if (rc) {
@@ -690,19 +705,19 @@ static int selinux_set_mnt_opts(struct super_block *sb,
690 } 705 }
691 } 706 }
692 707
693 if (sbsec->initialized) { 708 if (sbsec->flags & SE_SBINITIALIZED) {
694 /* previously mounted with options, but not on this attempt? */ 709 /* previously mounted with options, but not on this attempt? */
695 if (sbsec->flags && !num_opts) 710 if ((sbsec->flags & SE_MNTMASK) && !num_opts)
696 goto out_double_mount; 711 goto out_double_mount;
697 rc = 0; 712 rc = 0;
698 goto out; 713 goto out;
699 } 714 }
700 715
701 if (strcmp(sb->s_type->name, "proc") == 0) 716 if (strcmp(sb->s_type->name, "proc") == 0)
702 sbsec->proc = 1; 717 sbsec->flags |= SE_SBPROC;
703 718
704 /* Determine the labeling behavior to use for this filesystem type. */ 719 /* Determine the labeling behavior to use for this filesystem type. */
705 rc = security_fs_use(sbsec->proc ? "proc" : sb->s_type->name, &sbsec->behavior, &sbsec->sid); 720 rc = security_fs_use((sbsec->flags & SE_SBPROC) ? "proc" : sb->s_type->name, &sbsec->behavior, &sbsec->sid);
706 if (rc) { 721 if (rc) {
707 printk(KERN_WARNING "%s: security_fs_use(%s) returned %d\n", 722 printk(KERN_WARNING "%s: security_fs_use(%s) returned %d\n",
708 __func__, sb->s_type->name, rc); 723 __func__, sb->s_type->name, rc);
@@ -806,10 +821,10 @@ static void selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
806 } 821 }
807 822
808 /* how can we clone if the old one wasn't set up?? */ 823 /* how can we clone if the old one wasn't set up?? */
809 BUG_ON(!oldsbsec->initialized); 824 BUG_ON(!(oldsbsec->flags & SE_SBINITIALIZED));
810 825
811 /* if fs is reusing a sb, just let its options stand... */ 826 /* if fs is reusing a sb, just let its options stand... */
812 if (newsbsec->initialized) 827 if (newsbsec->flags & SE_SBINITIALIZED)
813 return; 828 return;
814 829
815 mutex_lock(&newsbsec->lock); 830 mutex_lock(&newsbsec->lock);
@@ -917,7 +932,8 @@ static int selinux_parse_opts_str(char *options,
917 goto out_err; 932 goto out_err;
918 } 933 }
919 break; 934 break;
920 935 case Opt_labelsupport:
936 break;
921 default: 937 default:
922 rc = -EINVAL; 938 rc = -EINVAL;
923 printk(KERN_WARNING "SELinux: unknown mount option\n"); 939 printk(KERN_WARNING "SELinux: unknown mount option\n");
@@ -999,7 +1015,12 @@ static void selinux_write_opts(struct seq_file *m,
999 char *prefix; 1015 char *prefix;
1000 1016
1001 for (i = 0; i < opts->num_mnt_opts; i++) { 1017 for (i = 0; i < opts->num_mnt_opts; i++) {
1002 char *has_comma = strchr(opts->mnt_opts[i], ','); 1018 char *has_comma;
1019
1020 if (opts->mnt_opts[i])
1021 has_comma = strchr(opts->mnt_opts[i], ',');
1022 else
1023 has_comma = NULL;
1003 1024
1004 switch (opts->mnt_opts_flags[i]) { 1025 switch (opts->mnt_opts_flags[i]) {
1005 case CONTEXT_MNT: 1026 case CONTEXT_MNT:
@@ -1014,6 +1035,10 @@ static void selinux_write_opts(struct seq_file *m,
1014 case DEFCONTEXT_MNT: 1035 case DEFCONTEXT_MNT:
1015 prefix = DEFCONTEXT_STR; 1036 prefix = DEFCONTEXT_STR;
1016 break; 1037 break;
1038 case SE_SBLABELSUPP:
1039 seq_putc(m, ',');
1040 seq_puts(m, LABELSUPP_STR);
1041 continue;
1017 default: 1042 default:
1018 BUG(); 1043 BUG();
1019 }; 1044 };
@@ -1209,7 +1234,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
1209 goto out_unlock; 1234 goto out_unlock;
1210 1235
1211 sbsec = inode->i_sb->s_security; 1236 sbsec = inode->i_sb->s_security;
1212 if (!sbsec->initialized) { 1237 if (!(sbsec->flags & SE_SBINITIALIZED)) {
1213 /* Defer initialization until selinux_complete_init, 1238 /* Defer initialization until selinux_complete_init,
1214 after the initial policy is loaded and the security 1239 after the initial policy is loaded and the security
1215 server is ready to handle calls. */ 1240 server is ready to handle calls. */
@@ -1237,19 +1262,26 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
1237 dentry = d_find_alias(inode); 1262 dentry = d_find_alias(inode);
1238 } 1263 }
1239 if (!dentry) { 1264 if (!dentry) {
1240 printk(KERN_WARNING "SELinux: %s: no dentry for dev=%s " 1265 /*
1241 "ino=%ld\n", __func__, inode->i_sb->s_id, 1266 * this is can be hit on boot when a file is accessed
1242 inode->i_ino); 1267 * before the policy is loaded. When we load policy we
1268 * may find inodes that have no dentry on the
1269 * sbsec->isec_head list. No reason to complain as these
1270 * will get fixed up the next time we go through
1271 * inode_doinit with a dentry, before these inodes could
1272 * be used again by userspace.
1273 */
1243 goto out_unlock; 1274 goto out_unlock;
1244 } 1275 }
1245 1276
1246 len = INITCONTEXTLEN; 1277 len = INITCONTEXTLEN;
1247 context = kmalloc(len, GFP_NOFS); 1278 context = kmalloc(len+1, GFP_NOFS);
1248 if (!context) { 1279 if (!context) {
1249 rc = -ENOMEM; 1280 rc = -ENOMEM;
1250 dput(dentry); 1281 dput(dentry);
1251 goto out_unlock; 1282 goto out_unlock;
1252 } 1283 }
1284 context[len] = '\0';
1253 rc = inode->i_op->getxattr(dentry, XATTR_NAME_SELINUX, 1285 rc = inode->i_op->getxattr(dentry, XATTR_NAME_SELINUX,
1254 context, len); 1286 context, len);
1255 if (rc == -ERANGE) { 1287 if (rc == -ERANGE) {
@@ -1262,12 +1294,13 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
1262 } 1294 }
1263 kfree(context); 1295 kfree(context);
1264 len = rc; 1296 len = rc;
1265 context = kmalloc(len, GFP_NOFS); 1297 context = kmalloc(len+1, GFP_NOFS);
1266 if (!context) { 1298 if (!context) {
1267 rc = -ENOMEM; 1299 rc = -ENOMEM;
1268 dput(dentry); 1300 dput(dentry);
1269 goto out_unlock; 1301 goto out_unlock;
1270 } 1302 }
1303 context[len] = '\0';
1271 rc = inode->i_op->getxattr(dentry, 1304 rc = inode->i_op->getxattr(dentry,
1272 XATTR_NAME_SELINUX, 1305 XATTR_NAME_SELINUX,
1273 context, len); 1306 context, len);
@@ -1289,10 +1322,19 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
1289 sbsec->def_sid, 1322 sbsec->def_sid,
1290 GFP_NOFS); 1323 GFP_NOFS);
1291 if (rc) { 1324 if (rc) {
1292 printk(KERN_WARNING "SELinux: %s: context_to_sid(%s) " 1325 char *dev = inode->i_sb->s_id;
1293 "returned %d for dev=%s ino=%ld\n", 1326 unsigned long ino = inode->i_ino;
1294 __func__, context, -rc, 1327
1295 inode->i_sb->s_id, inode->i_ino); 1328 if (rc == -EINVAL) {
1329 if (printk_ratelimit())
1330 printk(KERN_NOTICE "SELinux: inode=%lu on dev=%s was found to have an invalid "
1331 "context=%s. This indicates you may need to relabel the inode or the "
1332 "filesystem in question.\n", ino, dev, context);
1333 } else {
1334 printk(KERN_WARNING "SELinux: %s: context_to_sid(%s) "
1335 "returned %d for dev=%s ino=%ld\n",
1336 __func__, context, -rc, dev, ino);
1337 }
1296 kfree(context); 1338 kfree(context);
1297 /* Leave with the unlabeled SID */ 1339 /* Leave with the unlabeled SID */
1298 rc = 0; 1340 rc = 0;
@@ -1326,7 +1368,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
1326 /* Default to the fs superblock SID. */ 1368 /* Default to the fs superblock SID. */
1327 isec->sid = sbsec->sid; 1369 isec->sid = sbsec->sid;
1328 1370
1329 if (sbsec->proc && !S_ISLNK(inode->i_mode)) { 1371 if ((sbsec->flags & SE_SBPROC) && !S_ISLNK(inode->i_mode)) {
1330 struct proc_inode *proci = PROC_I(inode); 1372 struct proc_inode *proci = PROC_I(inode);
1331 if (proci->pde) { 1373 if (proci->pde) {
1332 isec->sclass = inode_mode_to_security_class(inode->i_mode); 1374 isec->sclass = inode_mode_to_security_class(inode->i_mode);
@@ -1587,7 +1629,7 @@ static int may_create(struct inode *dir,
1587 if (rc) 1629 if (rc)
1588 return rc; 1630 return rc;
1589 1631
1590 if (!newsid || sbsec->behavior == SECURITY_FS_USE_MNTPOINT) { 1632 if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) {
1591 rc = security_transition_sid(sid, dsec->sid, tclass, &newsid); 1633 rc = security_transition_sid(sid, dsec->sid, tclass, &newsid);
1592 if (rc) 1634 if (rc)
1593 return rc; 1635 return rc;
@@ -1801,6 +1843,8 @@ static inline u32 open_file_to_av(struct file *file)
1801 av |= FIFO_FILE__OPEN; 1843 av |= FIFO_FILE__OPEN;
1802 else if (S_ISDIR(mode)) 1844 else if (S_ISDIR(mode))
1803 av |= DIR__OPEN; 1845 av |= DIR__OPEN;
1846 else if (S_ISSOCK(mode))
1847 av |= SOCK_FILE__OPEN;
1804 else 1848 else
1805 printk(KERN_ERR "SELinux: WARNING: inside %s with " 1849 printk(KERN_ERR "SELinux: WARNING: inside %s with "
1806 "unknown mode:%o\n", __func__, mode); 1850 "unknown mode:%o\n", __func__, mode);
@@ -1815,7 +1859,7 @@ static int selinux_ptrace_may_access(struct task_struct *child,
1815{ 1859{
1816 int rc; 1860 int rc;
1817 1861
1818 rc = secondary_ops->ptrace_may_access(child, mode); 1862 rc = cap_ptrace_may_access(child, mode);
1819 if (rc) 1863 if (rc)
1820 return rc; 1864 return rc;
1821 1865
@@ -1832,7 +1876,7 @@ static int selinux_ptrace_traceme(struct task_struct *parent)
1832{ 1876{
1833 int rc; 1877 int rc;
1834 1878
1835 rc = secondary_ops->ptrace_traceme(parent); 1879 rc = cap_ptrace_traceme(parent);
1836 if (rc) 1880 if (rc)
1837 return rc; 1881 return rc;
1838 1882
@@ -1848,7 +1892,7 @@ static int selinux_capget(struct task_struct *target, kernel_cap_t *effective,
1848 if (error) 1892 if (error)
1849 return error; 1893 return error;
1850 1894
1851 return secondary_ops->capget(target, effective, inheritable, permitted); 1895 return cap_capget(target, effective, inheritable, permitted);
1852} 1896}
1853 1897
1854static int selinux_capset(struct cred *new, const struct cred *old, 1898static int selinux_capset(struct cred *new, const struct cred *old,
@@ -1858,7 +1902,7 @@ static int selinux_capset(struct cred *new, const struct cred *old,
1858{ 1902{
1859 int error; 1903 int error;
1860 1904
1861 error = secondary_ops->capset(new, old, 1905 error = cap_capset(new, old,
1862 effective, inheritable, permitted); 1906 effective, inheritable, permitted);
1863 if (error) 1907 if (error)
1864 return error; 1908 return error;
@@ -1866,12 +1910,22 @@ static int selinux_capset(struct cred *new, const struct cred *old,
1866 return cred_has_perm(old, new, PROCESS__SETCAP); 1910 return cred_has_perm(old, new, PROCESS__SETCAP);
1867} 1911}
1868 1912
1913/*
1914 * (This comment used to live with the selinux_task_setuid hook,
1915 * which was removed).
1916 *
1917 * Since setuid only affects the current process, and since the SELinux
1918 * controls are not based on the Linux identity attributes, SELinux does not
1919 * need to control this operation. However, SELinux does control the use of
1920 * the CAP_SETUID and CAP_SETGID capabilities using the capable hook.
1921 */
1922
1869static int selinux_capable(struct task_struct *tsk, const struct cred *cred, 1923static int selinux_capable(struct task_struct *tsk, const struct cred *cred,
1870 int cap, int audit) 1924 int cap, int audit)
1871{ 1925{
1872 int rc; 1926 int rc;
1873 1927
1874 rc = secondary_ops->capable(tsk, cred, cap, audit); 1928 rc = cap_capable(tsk, cred, cap, audit);
1875 if (rc) 1929 if (rc)
1876 return rc; 1930 return rc;
1877 1931
@@ -1997,7 +2051,7 @@ static int selinux_syslog(int type)
1997{ 2051{
1998 int rc; 2052 int rc;
1999 2053
2000 rc = secondary_ops->syslog(type); 2054 rc = cap_syslog(type);
2001 if (rc) 2055 if (rc)
2002 return rc; 2056 return rc;
2003 2057
@@ -2028,10 +2082,6 @@ static int selinux_syslog(int type)
2028 * mapping. 0 means there is enough memory for the allocation to 2082 * mapping. 0 means there is enough memory for the allocation to
2029 * succeed and -ENOMEM implies there is not. 2083 * succeed and -ENOMEM implies there is not.
2030 * 2084 *
2031 * Note that secondary_ops->capable and task_has_perm_noaudit return 0
2032 * if the capability is granted, but __vm_enough_memory requires 1 if
2033 * the capability is granted.
2034 *
2035 * Do not audit the selinux permission check, as this is applied to all 2085 * Do not audit the selinux permission check, as this is applied to all
2036 * processes that allocate mappings. 2086 * processes that allocate mappings.
2037 */ 2087 */
@@ -2058,7 +2108,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
2058 struct inode *inode = bprm->file->f_path.dentry->d_inode; 2108 struct inode *inode = bprm->file->f_path.dentry->d_inode;
2059 int rc; 2109 int rc;
2060 2110
2061 rc = secondary_ops->bprm_set_creds(bprm); 2111 rc = cap_bprm_set_creds(bprm);
2062 if (rc) 2112 if (rc)
2063 return rc; 2113 return rc;
2064 2114
@@ -2156,11 +2206,6 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
2156 return 0; 2206 return 0;
2157} 2207}
2158 2208
2159static int selinux_bprm_check_security(struct linux_binprm *bprm)
2160{
2161 return secondary_ops->bprm_check_security(bprm);
2162}
2163
2164static int selinux_bprm_secureexec(struct linux_binprm *bprm) 2209static int selinux_bprm_secureexec(struct linux_binprm *bprm)
2165{ 2210{
2166 const struct cred *cred = current_cred(); 2211 const struct cred *cred = current_cred();
@@ -2180,7 +2225,7 @@ static int selinux_bprm_secureexec(struct linux_binprm *bprm)
2180 PROCESS__NOATSECURE, NULL); 2225 PROCESS__NOATSECURE, NULL);
2181 } 2226 }
2182 2227
2183 return (atsecure || secondary_ops->bprm_secureexec(bprm)); 2228 return (atsecure || cap_bprm_secureexec(bprm));
2184} 2229}
2185 2230
2186extern struct vfsmount *selinuxfs_mount; 2231extern struct vfsmount *selinuxfs_mount;
@@ -2290,8 +2335,6 @@ static void selinux_bprm_committing_creds(struct linux_binprm *bprm)
2290 struct rlimit *rlim, *initrlim; 2335 struct rlimit *rlim, *initrlim;
2291 int rc, i; 2336 int rc, i;
2292 2337
2293 secondary_ops->bprm_committing_creds(bprm);
2294
2295 new_tsec = bprm->cred->security; 2338 new_tsec = bprm->cred->security;
2296 if (new_tsec->sid == new_tsec->osid) 2339 if (new_tsec->sid == new_tsec->osid)
2297 return; 2340 return;
@@ -2337,8 +2380,6 @@ static void selinux_bprm_committed_creds(struct linux_binprm *bprm)
2337 int rc, i; 2380 int rc, i;
2338 unsigned long flags; 2381 unsigned long flags;
2339 2382
2340 secondary_ops->bprm_committed_creds(bprm);
2341
2342 osid = tsec->osid; 2383 osid = tsec->osid;
2343 sid = tsec->sid; 2384 sid = tsec->sid;
2344 2385
@@ -2400,7 +2441,8 @@ static inline int selinux_option(char *option, int len)
2400 return (match_prefix(CONTEXT_STR, sizeof(CONTEXT_STR)-1, option, len) || 2441 return (match_prefix(CONTEXT_STR, sizeof(CONTEXT_STR)-1, option, len) ||
2401 match_prefix(FSCONTEXT_STR, sizeof(FSCONTEXT_STR)-1, option, len) || 2442 match_prefix(FSCONTEXT_STR, sizeof(FSCONTEXT_STR)-1, option, len) ||
2402 match_prefix(DEFCONTEXT_STR, sizeof(DEFCONTEXT_STR)-1, option, len) || 2443 match_prefix(DEFCONTEXT_STR, sizeof(DEFCONTEXT_STR)-1, option, len) ||
2403 match_prefix(ROOTCONTEXT_STR, sizeof(ROOTCONTEXT_STR)-1, option, len)); 2444 match_prefix(ROOTCONTEXT_STR, sizeof(ROOTCONTEXT_STR)-1, option, len) ||
2445 match_prefix(LABELSUPP_STR, sizeof(LABELSUPP_STR)-1, option, len));
2404} 2446}
2405 2447
2406static inline void take_option(char **to, char *from, int *first, int len) 2448static inline void take_option(char **to, char *from, int *first, int len)
@@ -2513,11 +2555,6 @@ static int selinux_mount(char *dev_name,
2513 void *data) 2555 void *data)
2514{ 2556{
2515 const struct cred *cred = current_cred(); 2557 const struct cred *cred = current_cred();
2516 int rc;
2517
2518 rc = secondary_ops->sb_mount(dev_name, path, type, flags, data);
2519 if (rc)
2520 return rc;
2521 2558
2522 if (flags & MS_REMOUNT) 2559 if (flags & MS_REMOUNT)
2523 return superblock_has_perm(cred, path->mnt->mnt_sb, 2560 return superblock_has_perm(cred, path->mnt->mnt_sb,
@@ -2530,11 +2567,6 @@ static int selinux_mount(char *dev_name,
2530static int selinux_umount(struct vfsmount *mnt, int flags) 2567static int selinux_umount(struct vfsmount *mnt, int flags)
2531{ 2568{
2532 const struct cred *cred = current_cred(); 2569 const struct cred *cred = current_cred();
2533 int rc;
2534
2535 rc = secondary_ops->sb_umount(mnt, flags);
2536 if (rc)
2537 return rc;
2538 2570
2539 return superblock_has_perm(cred, mnt->mnt_sb, 2571 return superblock_has_perm(cred, mnt->mnt_sb,
2540 FILESYSTEM__UNMOUNT, NULL); 2572 FILESYSTEM__UNMOUNT, NULL);
@@ -2570,7 +2602,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
2570 sid = tsec->sid; 2602 sid = tsec->sid;
2571 newsid = tsec->create_sid; 2603 newsid = tsec->create_sid;
2572 2604
2573 if (!newsid || sbsec->behavior == SECURITY_FS_USE_MNTPOINT) { 2605 if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) {
2574 rc = security_transition_sid(sid, dsec->sid, 2606 rc = security_transition_sid(sid, dsec->sid,
2575 inode_mode_to_security_class(inode->i_mode), 2607 inode_mode_to_security_class(inode->i_mode),
2576 &newsid); 2608 &newsid);
@@ -2585,14 +2617,14 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
2585 } 2617 }
2586 2618
2587 /* Possibly defer initialization to selinux_complete_init. */ 2619 /* Possibly defer initialization to selinux_complete_init. */
2588 if (sbsec->initialized) { 2620 if (sbsec->flags & SE_SBINITIALIZED) {
2589 struct inode_security_struct *isec = inode->i_security; 2621 struct inode_security_struct *isec = inode->i_security;
2590 isec->sclass = inode_mode_to_security_class(inode->i_mode); 2622 isec->sclass = inode_mode_to_security_class(inode->i_mode);
2591 isec->sid = newsid; 2623 isec->sid = newsid;
2592 isec->initialized = 1; 2624 isec->initialized = 1;
2593 } 2625 }
2594 2626
2595 if (!ss_initialized || sbsec->behavior == SECURITY_FS_USE_MNTPOINT) 2627 if (!ss_initialized || !(sbsec->flags & SE_SBLABELSUPP))
2596 return -EOPNOTSUPP; 2628 return -EOPNOTSUPP;
2597 2629
2598 if (name) { 2630 if (name) {
@@ -2622,21 +2654,11 @@ static int selinux_inode_create(struct inode *dir, struct dentry *dentry, int ma
2622 2654
2623static int selinux_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry) 2655static int selinux_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
2624{ 2656{
2625 int rc;
2626
2627 rc = secondary_ops->inode_link(old_dentry, dir, new_dentry);
2628 if (rc)
2629 return rc;
2630 return may_link(dir, old_dentry, MAY_LINK); 2657 return may_link(dir, old_dentry, MAY_LINK);
2631} 2658}
2632 2659
2633static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry) 2660static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry)
2634{ 2661{
2635 int rc;
2636
2637 rc = secondary_ops->inode_unlink(dir, dentry);
2638 if (rc)
2639 return rc;
2640 return may_link(dir, dentry, MAY_UNLINK); 2662 return may_link(dir, dentry, MAY_UNLINK);
2641} 2663}
2642 2664
@@ -2657,12 +2679,6 @@ static int selinux_inode_rmdir(struct inode *dir, struct dentry *dentry)
2657 2679
2658static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) 2680static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
2659{ 2681{
2660 int rc;
2661
2662 rc = secondary_ops->inode_mknod(dir, dentry, mode, dev);
2663 if (rc)
2664 return rc;
2665
2666 return may_create(dir, dentry, inode_mode_to_security_class(mode)); 2682 return may_create(dir, dentry, inode_mode_to_security_class(mode));
2667} 2683}
2668 2684
@@ -2682,22 +2698,13 @@ static int selinux_inode_readlink(struct dentry *dentry)
2682static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata) 2698static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata)
2683{ 2699{
2684 const struct cred *cred = current_cred(); 2700 const struct cred *cred = current_cred();
2685 int rc;
2686 2701
2687 rc = secondary_ops->inode_follow_link(dentry, nameidata);
2688 if (rc)
2689 return rc;
2690 return dentry_has_perm(cred, NULL, dentry, FILE__READ); 2702 return dentry_has_perm(cred, NULL, dentry, FILE__READ);
2691} 2703}
2692 2704
2693static int selinux_inode_permission(struct inode *inode, int mask) 2705static int selinux_inode_permission(struct inode *inode, int mask)
2694{ 2706{
2695 const struct cred *cred = current_cred(); 2707 const struct cred *cred = current_cred();
2696 int rc;
2697
2698 rc = secondary_ops->inode_permission(inode, mask);
2699 if (rc)
2700 return rc;
2701 2708
2702 if (!mask) { 2709 if (!mask) {
2703 /* No permission to check. Existence test. */ 2710 /* No permission to check. Existence test. */
@@ -2711,11 +2718,6 @@ static int selinux_inode_permission(struct inode *inode, int mask)
2711static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) 2718static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
2712{ 2719{
2713 const struct cred *cred = current_cred(); 2720 const struct cred *cred = current_cred();
2714 int rc;
2715
2716 rc = secondary_ops->inode_setattr(dentry, iattr);
2717 if (rc)
2718 return rc;
2719 2721
2720 if (iattr->ia_valid & ATTR_FORCE) 2722 if (iattr->ia_valid & ATTR_FORCE)
2721 return 0; 2723 return 0;
@@ -2769,7 +2771,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
2769 return selinux_inode_setotherxattr(dentry, name); 2771 return selinux_inode_setotherxattr(dentry, name);
2770 2772
2771 sbsec = inode->i_sb->s_security; 2773 sbsec = inode->i_sb->s_security;
2772 if (sbsec->behavior == SECURITY_FS_USE_MNTPOINT) 2774 if (!(sbsec->flags & SE_SBLABELSUPP))
2773 return -EOPNOTSUPP; 2775 return -EOPNOTSUPP;
2774 2776
2775 if (!is_owner_or_cap(inode)) 2777 if (!is_owner_or_cap(inode))
@@ -2931,16 +2933,6 @@ static int selinux_inode_listsecurity(struct inode *inode, char *buffer, size_t
2931 return len; 2933 return len;
2932} 2934}
2933 2935
2934static int selinux_inode_need_killpriv(struct dentry *dentry)
2935{
2936 return secondary_ops->inode_need_killpriv(dentry);
2937}
2938
2939static int selinux_inode_killpriv(struct dentry *dentry)
2940{
2941 return secondary_ops->inode_killpriv(dentry);
2942}
2943
2944static void selinux_inode_getsecid(const struct inode *inode, u32 *secid) 2936static void selinux_inode_getsecid(const struct inode *inode, u32 *secid)
2945{ 2937{
2946 struct inode_security_struct *isec = inode->i_security; 2938 struct inode_security_struct *isec = inode->i_security;
@@ -2952,7 +2944,6 @@ static void selinux_inode_getsecid(const struct inode *inode, u32 *secid)
2952static int selinux_revalidate_file_permission(struct file *file, int mask) 2944static int selinux_revalidate_file_permission(struct file *file, int mask)
2953{ 2945{
2954 const struct cred *cred = current_cred(); 2946 const struct cred *cred = current_cred();
2955 int rc;
2956 struct inode *inode = file->f_path.dentry->d_inode; 2947 struct inode *inode = file->f_path.dentry->d_inode;
2957 2948
2958 if (!mask) { 2949 if (!mask) {
@@ -2964,29 +2955,15 @@ static int selinux_revalidate_file_permission(struct file *file, int mask)
2964 if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE)) 2955 if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE))
2965 mask |= MAY_APPEND; 2956 mask |= MAY_APPEND;
2966 2957
2967 rc = file_has_perm(cred, file, 2958 return file_has_perm(cred, file,
2968 file_mask_to_av(inode->i_mode, mask)); 2959 file_mask_to_av(inode->i_mode, mask));
2969 if (rc)
2970 return rc;
2971
2972 return selinux_netlbl_inode_permission(inode, mask);
2973} 2960}
2974 2961
2975static int selinux_file_permission(struct file *file, int mask) 2962static int selinux_file_permission(struct file *file, int mask)
2976{ 2963{
2977 struct inode *inode = file->f_path.dentry->d_inode; 2964 if (!mask)
2978 struct file_security_struct *fsec = file->f_security;
2979 struct inode_security_struct *isec = inode->i_security;
2980 u32 sid = current_sid();
2981
2982 if (!mask) {
2983 /* No permission to check. Existence test. */ 2965 /* No permission to check. Existence test. */
2984 return 0; 2966 return 0;
2985 }
2986
2987 if (sid == fsec->sid && fsec->isid == isec->sid
2988 && fsec->pseqno == avc_policy_seqno())
2989 return selinux_netlbl_inode_permission(inode, mask);
2990 2967
2991 return selinux_revalidate_file_permission(file, mask); 2968 return selinux_revalidate_file_permission(file, mask);
2992} 2969}
@@ -3078,18 +3055,13 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
3078 unsigned long prot) 3055 unsigned long prot)
3079{ 3056{
3080 const struct cred *cred = current_cred(); 3057 const struct cred *cred = current_cred();
3081 int rc;
3082
3083 rc = secondary_ops->file_mprotect(vma, reqprot, prot);
3084 if (rc)
3085 return rc;
3086 3058
3087 if (selinux_checkreqprot) 3059 if (selinux_checkreqprot)
3088 prot = reqprot; 3060 prot = reqprot;
3089 3061
3090#ifndef CONFIG_PPC32 3062#ifndef CONFIG_PPC32
3091 if ((prot & PROT_EXEC) && !(vma->vm_flags & VM_EXEC)) { 3063 if ((prot & PROT_EXEC) && !(vma->vm_flags & VM_EXEC)) {
3092 rc = 0; 3064 int rc = 0;
3093 if (vma->vm_start >= vma->vm_mm->start_brk && 3065 if (vma->vm_start >= vma->vm_mm->start_brk &&
3094 vma->vm_end <= vma->vm_mm->brk) { 3066 vma->vm_end <= vma->vm_mm->brk) {
3095 rc = cred_has_perm(cred, cred, PROCESS__EXECHEAP); 3067 rc = cred_has_perm(cred, cred, PROCESS__EXECHEAP);
@@ -3239,12 +3211,6 @@ static int selinux_dentry_open(struct file *file, const struct cred *cred)
3239 3211
3240static int selinux_task_create(unsigned long clone_flags) 3212static int selinux_task_create(unsigned long clone_flags)
3241{ 3213{
3242 int rc;
3243
3244 rc = secondary_ops->task_create(clone_flags);
3245 if (rc)
3246 return rc;
3247
3248 return current_has_perm(current, PROCESS__FORK); 3214 return current_has_perm(current, PROCESS__FORK);
3249} 3215}
3250 3216
@@ -3278,14 +3244,6 @@ static int selinux_cred_prepare(struct cred *new, const struct cred *old,
3278} 3244}
3279 3245
3280/* 3246/*
3281 * commit new credentials
3282 */
3283static void selinux_cred_commit(struct cred *new, const struct cred *old)
3284{
3285 secondary_ops->cred_commit(new, old);
3286}
3287
3288/*
3289 * set the security data for a kernel service 3247 * set the security data for a kernel service
3290 * - all the creation contexts are set to unlabelled 3248 * - all the creation contexts are set to unlabelled
3291 */ 3249 */
@@ -3329,29 +3287,6 @@ static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode)
3329 return 0; 3287 return 0;
3330} 3288}
3331 3289
3332static int selinux_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags)
3333{
3334 /* Since setuid only affects the current process, and
3335 since the SELinux controls are not based on the Linux
3336 identity attributes, SELinux does not need to control
3337 this operation. However, SELinux does control the use
3338 of the CAP_SETUID and CAP_SETGID capabilities using the
3339 capable hook. */
3340 return 0;
3341}
3342
3343static int selinux_task_fix_setuid(struct cred *new, const struct cred *old,
3344 int flags)
3345{
3346 return secondary_ops->task_fix_setuid(new, old, flags);
3347}
3348
3349static int selinux_task_setgid(gid_t id0, gid_t id1, gid_t id2, int flags)
3350{
3351 /* See the comment for setuid above. */
3352 return 0;
3353}
3354
3355static int selinux_task_setpgid(struct task_struct *p, pid_t pgid) 3290static int selinux_task_setpgid(struct task_struct *p, pid_t pgid)
3356{ 3291{
3357 return current_has_perm(p, PROCESS__SETPGID); 3292 return current_has_perm(p, PROCESS__SETPGID);
@@ -3372,17 +3307,11 @@ static void selinux_task_getsecid(struct task_struct *p, u32 *secid)
3372 *secid = task_sid(p); 3307 *secid = task_sid(p);
3373} 3308}
3374 3309
3375static int selinux_task_setgroups(struct group_info *group_info)
3376{
3377 /* See the comment for setuid above. */
3378 return 0;
3379}
3380
3381static int selinux_task_setnice(struct task_struct *p, int nice) 3310static int selinux_task_setnice(struct task_struct *p, int nice)
3382{ 3311{
3383 int rc; 3312 int rc;
3384 3313
3385 rc = secondary_ops->task_setnice(p, nice); 3314 rc = cap_task_setnice(p, nice);
3386 if (rc) 3315 if (rc)
3387 return rc; 3316 return rc;
3388 3317
@@ -3393,7 +3322,7 @@ static int selinux_task_setioprio(struct task_struct *p, int ioprio)
3393{ 3322{
3394 int rc; 3323 int rc;
3395 3324
3396 rc = secondary_ops->task_setioprio(p, ioprio); 3325 rc = cap_task_setioprio(p, ioprio);
3397 if (rc) 3326 if (rc)
3398 return rc; 3327 return rc;
3399 3328
@@ -3408,11 +3337,6 @@ static int selinux_task_getioprio(struct task_struct *p)
3408static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim) 3337static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim)
3409{ 3338{
3410 struct rlimit *old_rlim = current->signal->rlim + resource; 3339 struct rlimit *old_rlim = current->signal->rlim + resource;
3411 int rc;
3412
3413 rc = secondary_ops->task_setrlimit(resource, new_rlim);
3414 if (rc)
3415 return rc;
3416 3340
3417 /* Control the ability to change the hard limit (whether 3341 /* Control the ability to change the hard limit (whether
3418 lowering or raising it), so that the hard limit can 3342 lowering or raising it), so that the hard limit can
@@ -3428,7 +3352,7 @@ static int selinux_task_setscheduler(struct task_struct *p, int policy, struct s
3428{ 3352{
3429 int rc; 3353 int rc;
3430 3354
3431 rc = secondary_ops->task_setscheduler(p, policy, lp); 3355 rc = cap_task_setscheduler(p, policy, lp);
3432 if (rc) 3356 if (rc)
3433 return rc; 3357 return rc;
3434 3358
@@ -3451,10 +3375,6 @@ static int selinux_task_kill(struct task_struct *p, struct siginfo *info,
3451 u32 perm; 3375 u32 perm;
3452 int rc; 3376 int rc;
3453 3377
3454 rc = secondary_ops->task_kill(p, info, sig, secid);
3455 if (rc)
3456 return rc;
3457
3458 if (!sig) 3378 if (!sig)
3459 perm = PROCESS__SIGNULL; /* null signal; existence test */ 3379 perm = PROCESS__SIGNULL; /* null signal; existence test */
3460 else 3380 else
@@ -3467,18 +3387,6 @@ static int selinux_task_kill(struct task_struct *p, struct siginfo *info,
3467 return rc; 3387 return rc;
3468} 3388}
3469 3389
3470static int selinux_task_prctl(int option,
3471 unsigned long arg2,
3472 unsigned long arg3,
3473 unsigned long arg4,
3474 unsigned long arg5)
3475{
3476 /* The current prctl operations do not appear to require
3477 any SELinux controls since they merely observe or modify
3478 the state of the current process. */
3479 return secondary_ops->task_prctl(option, arg2, arg3, arg4, arg5);
3480}
3481
3482static int selinux_task_wait(struct task_struct *p) 3390static int selinux_task_wait(struct task_struct *p)
3483{ 3391{
3484 return task_has_perm(p, current, PROCESS__SIGCHLD); 3392 return task_has_perm(p, current, PROCESS__SIGCHLD);
@@ -3799,7 +3707,7 @@ static int selinux_socket_post_create(struct socket *sock, int family,
3799 sksec = sock->sk->sk_security; 3707 sksec = sock->sk->sk_security;
3800 sksec->sid = isec->sid; 3708 sksec->sid = isec->sid;
3801 sksec->sclass = isec->sclass; 3709 sksec->sclass = isec->sclass;
3802 err = selinux_netlbl_socket_post_create(sock); 3710 err = selinux_netlbl_socket_post_create(sock->sk, family);
3803 } 3711 }
3804 3712
3805 return err; 3713 return err;
@@ -3990,13 +3898,7 @@ static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
3990static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg, 3898static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg,
3991 int size) 3899 int size)
3992{ 3900{
3993 int rc; 3901 return socket_has_perm(current, sock, SOCKET__WRITE);
3994
3995 rc = socket_has_perm(current, sock, SOCKET__WRITE);
3996 if (rc)
3997 return rc;
3998
3999 return selinux_netlbl_inode_permission(SOCK_INODE(sock), MAY_WRITE);
4000} 3902}
4001 3903
4002static int selinux_socket_recvmsg(struct socket *sock, struct msghdr *msg, 3904static int selinux_socket_recvmsg(struct socket *sock, struct msghdr *msg,
@@ -4047,10 +3949,6 @@ static int selinux_socket_unix_stream_connect(struct socket *sock,
4047 struct avc_audit_data ad; 3949 struct avc_audit_data ad;
4048 int err; 3950 int err;
4049 3951
4050 err = secondary_ops->unix_stream_connect(sock, other, newsk);
4051 if (err)
4052 return err;
4053
4054 isec = SOCK_INODE(sock)->i_security; 3952 isec = SOCK_INODE(sock)->i_security;
4055 other_isec = SOCK_INODE(other)->i_security; 3953 other_isec = SOCK_INODE(other)->i_security;
4056 3954
@@ -4120,72 +4018,6 @@ static int selinux_inet_sys_rcv_skb(int ifindex, char *addrp, u16 family,
4120 SECCLASS_NODE, NODE__RECVFROM, ad); 4018 SECCLASS_NODE, NODE__RECVFROM, ad);
4121} 4019}
4122 4020
4123static int selinux_sock_rcv_skb_iptables_compat(struct sock *sk,
4124 struct sk_buff *skb,
4125 struct avc_audit_data *ad,
4126 u16 family,
4127 char *addrp)
4128{
4129 int err;
4130 struct sk_security_struct *sksec = sk->sk_security;
4131 u16 sk_class;
4132 u32 netif_perm, node_perm, recv_perm;
4133 u32 port_sid, node_sid, if_sid, sk_sid;
4134
4135 sk_sid = sksec->sid;
4136 sk_class = sksec->sclass;
4137
4138 switch (sk_class) {
4139 case SECCLASS_UDP_SOCKET:
4140 netif_perm = NETIF__UDP_RECV;
4141 node_perm = NODE__UDP_RECV;
4142 recv_perm = UDP_SOCKET__RECV_MSG;
4143 break;
4144 case SECCLASS_TCP_SOCKET:
4145 netif_perm = NETIF__TCP_RECV;
4146 node_perm = NODE__TCP_RECV;
4147 recv_perm = TCP_SOCKET__RECV_MSG;
4148 break;
4149 case SECCLASS_DCCP_SOCKET:
4150 netif_perm = NETIF__DCCP_RECV;
4151 node_perm = NODE__DCCP_RECV;
4152 recv_perm = DCCP_SOCKET__RECV_MSG;
4153 break;
4154 default:
4155 netif_perm = NETIF__RAWIP_RECV;
4156 node_perm = NODE__RAWIP_RECV;
4157 recv_perm = 0;
4158 break;
4159 }
4160
4161 err = sel_netif_sid(skb->iif, &if_sid);
4162 if (err)
4163 return err;
4164 err = avc_has_perm(sk_sid, if_sid, SECCLASS_NETIF, netif_perm, ad);
4165 if (err)
4166 return err;
4167
4168 err = sel_netnode_sid(addrp, family, &node_sid);
4169 if (err)
4170 return err;
4171 err = avc_has_perm(sk_sid, node_sid, SECCLASS_NODE, node_perm, ad);
4172 if (err)
4173 return err;
4174
4175 if (!recv_perm)
4176 return 0;
4177 err = sel_netport_sid(sk->sk_protocol,
4178 ntohs(ad->u.net.sport), &port_sid);
4179 if (unlikely(err)) {
4180 printk(KERN_WARNING
4181 "SELinux: failure in"
4182 " selinux_sock_rcv_skb_iptables_compat(),"
4183 " network port label not found\n");
4184 return err;
4185 }
4186 return avc_has_perm(sk_sid, port_sid, sk_class, recv_perm, ad);
4187}
4188
4189static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb, 4021static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
4190 u16 family) 4022 u16 family)
4191{ 4023{
@@ -4203,14 +4035,12 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
4203 if (err) 4035 if (err)
4204 return err; 4036 return err;
4205 4037
4206 if (selinux_compat_net) 4038 if (selinux_secmark_enabled()) {
4207 err = selinux_sock_rcv_skb_iptables_compat(sk, skb, &ad,
4208 family, addrp);
4209 else if (selinux_secmark_enabled())
4210 err = avc_has_perm(sk_sid, skb->secmark, SECCLASS_PACKET, 4039 err = avc_has_perm(sk_sid, skb->secmark, SECCLASS_PACKET,
4211 PACKET__RECV, &ad); 4040 PACKET__RECV, &ad);
4212 if (err) 4041 if (err)
4213 return err; 4042 return err;
4043 }
4214 4044
4215 if (selinux_policycap_netpeer) { 4045 if (selinux_policycap_netpeer) {
4216 err = selinux_skb_peerlbl_sid(skb, family, &peer_sid); 4046 err = selinux_skb_peerlbl_sid(skb, family, &peer_sid);
@@ -4252,7 +4082,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
4252 * to the selinux_sock_rcv_skb_compat() function to deal with the 4082 * to the selinux_sock_rcv_skb_compat() function to deal with the
4253 * special handling. We do this in an attempt to keep this function 4083 * special handling. We do this in an attempt to keep this function
4254 * as fast and as clean as possible. */ 4084 * as fast and as clean as possible. */
4255 if (selinux_compat_net || !selinux_policycap_netpeer) 4085 if (!selinux_policycap_netpeer)
4256 return selinux_sock_rcv_skb_compat(sk, skb, family); 4086 return selinux_sock_rcv_skb_compat(sk, skb, family);
4257 4087
4258 secmark_active = selinux_secmark_enabled(); 4088 secmark_active = selinux_secmark_enabled();
@@ -4384,7 +4214,7 @@ static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk)
4384 newssec->peer_sid = ssec->peer_sid; 4214 newssec->peer_sid = ssec->peer_sid;
4385 newssec->sclass = ssec->sclass; 4215 newssec->sclass = ssec->sclass;
4386 4216
4387 selinux_netlbl_sk_security_reset(newssec, newsk->sk_family); 4217 selinux_netlbl_sk_security_reset(newssec);
4388} 4218}
4389 4219
4390static void selinux_sk_getsecid(struct sock *sk, u32 *secid) 4220static void selinux_sk_getsecid(struct sock *sk, u32 *secid)
@@ -4428,16 +4258,15 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
4428 if (peersid == SECSID_NULL) { 4258 if (peersid == SECSID_NULL) {
4429 req->secid = sksec->sid; 4259 req->secid = sksec->sid;
4430 req->peer_secid = SECSID_NULL; 4260 req->peer_secid = SECSID_NULL;
4431 return 0; 4261 } else {
4262 err = security_sid_mls_copy(sksec->sid, peersid, &newsid);
4263 if (err)
4264 return err;
4265 req->secid = newsid;
4266 req->peer_secid = peersid;
4432 } 4267 }
4433 4268
4434 err = security_sid_mls_copy(sksec->sid, peersid, &newsid); 4269 return selinux_netlbl_inet_conn_request(req, family);
4435 if (err)
4436 return err;
4437
4438 req->secid = newsid;
4439 req->peer_secid = peersid;
4440 return 0;
4441} 4270}
4442 4271
4443static void selinux_inet_csk_clone(struct sock *newsk, 4272static void selinux_inet_csk_clone(struct sock *newsk,
@@ -4454,7 +4283,7 @@ static void selinux_inet_csk_clone(struct sock *newsk,
4454 4283
4455 /* We don't need to take any sort of lock here as we are the only 4284 /* We don't need to take any sort of lock here as we are the only
4456 * thread with access to newsksec */ 4285 * thread with access to newsksec */
4457 selinux_netlbl_sk_security_reset(newsksec, req->rsk_ops->family); 4286 selinux_netlbl_inet_csk_clone(newsk, req->rsk_ops->family);
4458} 4287}
4459 4288
4460static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb) 4289static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb)
@@ -4467,8 +4296,6 @@ static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb)
4467 family = PF_INET; 4296 family = PF_INET;
4468 4297
4469 selinux_skb_peerlbl_sid(skb, family, &sksec->peer_sid); 4298 selinux_skb_peerlbl_sid(skb, family, &sksec->peer_sid);
4470
4471 selinux_netlbl_inet_conn_established(sk, family);
4472} 4299}
4473 4300
4474static void selinux_req_classify_flow(const struct request_sock *req, 4301static void selinux_req_classify_flow(const struct request_sock *req,
@@ -4620,71 +4447,6 @@ static unsigned int selinux_ipv4_output(unsigned int hooknum,
4620 return selinux_ip_output(skb, PF_INET); 4447 return selinux_ip_output(skb, PF_INET);
4621} 4448}
4622 4449
4623static int selinux_ip_postroute_iptables_compat(struct sock *sk,
4624 int ifindex,
4625 struct avc_audit_data *ad,
4626 u16 family, char *addrp)
4627{
4628 int err;
4629 struct sk_security_struct *sksec = sk->sk_security;
4630 u16 sk_class;
4631 u32 netif_perm, node_perm, send_perm;
4632 u32 port_sid, node_sid, if_sid, sk_sid;
4633
4634 sk_sid = sksec->sid;
4635 sk_class = sksec->sclass;
4636
4637 switch (sk_class) {
4638 case SECCLASS_UDP_SOCKET:
4639 netif_perm = NETIF__UDP_SEND;
4640 node_perm = NODE__UDP_SEND;
4641 send_perm = UDP_SOCKET__SEND_MSG;
4642 break;
4643 case SECCLASS_TCP_SOCKET:
4644 netif_perm = NETIF__TCP_SEND;
4645 node_perm = NODE__TCP_SEND;
4646 send_perm = TCP_SOCKET__SEND_MSG;
4647 break;
4648 case SECCLASS_DCCP_SOCKET:
4649 netif_perm = NETIF__DCCP_SEND;
4650 node_perm = NODE__DCCP_SEND;
4651 send_perm = DCCP_SOCKET__SEND_MSG;
4652 break;
4653 default:
4654 netif_perm = NETIF__RAWIP_SEND;
4655 node_perm = NODE__RAWIP_SEND;
4656 send_perm = 0;
4657 break;
4658 }
4659
4660 err = sel_netif_sid(ifindex, &if_sid);
4661 if (err)
4662 return err;
4663 err = avc_has_perm(sk_sid, if_sid, SECCLASS_NETIF, netif_perm, ad);
4664 return err;
4665
4666 err = sel_netnode_sid(addrp, family, &node_sid);
4667 if (err)
4668 return err;
4669 err = avc_has_perm(sk_sid, node_sid, SECCLASS_NODE, node_perm, ad);
4670 if (err)
4671 return err;
4672
4673 if (send_perm != 0)
4674 return 0;
4675
4676 err = sel_netport_sid(sk->sk_protocol,
4677 ntohs(ad->u.net.dport), &port_sid);
4678 if (unlikely(err)) {
4679 printk(KERN_WARNING
4680 "SELinux: failure in"
4681 " selinux_ip_postroute_iptables_compat(),"
4682 " network port label not found\n");
4683 return err;
4684 }
4685 return avc_has_perm(sk_sid, port_sid, sk_class, send_perm, ad);
4686}
4687
4688static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, 4450static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
4689 int ifindex, 4451 int ifindex,
4690 u16 family) 4452 u16 family)
@@ -4705,15 +4467,10 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
4705 if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto)) 4467 if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto))
4706 return NF_DROP; 4468 return NF_DROP;
4707 4469
4708 if (selinux_compat_net) { 4470 if (selinux_secmark_enabled())
4709 if (selinux_ip_postroute_iptables_compat(skb->sk, ifindex,
4710 &ad, family, addrp))
4711 return NF_DROP;
4712 } else if (selinux_secmark_enabled()) {
4713 if (avc_has_perm(sksec->sid, skb->secmark, 4471 if (avc_has_perm(sksec->sid, skb->secmark,
4714 SECCLASS_PACKET, PACKET__SEND, &ad)) 4472 SECCLASS_PACKET, PACKET__SEND, &ad))
4715 return NF_DROP; 4473 return NF_DROP;
4716 }
4717 4474
4718 if (selinux_policycap_netpeer) 4475 if (selinux_policycap_netpeer)
4719 if (selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto)) 4476 if (selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto))
@@ -4737,7 +4494,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
4737 * to the selinux_ip_postroute_compat() function to deal with the 4494 * to the selinux_ip_postroute_compat() function to deal with the
4738 * special handling. We do this in an attempt to keep this function 4495 * special handling. We do this in an attempt to keep this function
4739 * as fast and as clean as possible. */ 4496 * as fast and as clean as possible. */
4740 if (selinux_compat_net || !selinux_policycap_netpeer) 4497 if (!selinux_policycap_netpeer)
4741 return selinux_ip_postroute_compat(skb, ifindex, family); 4498 return selinux_ip_postroute_compat(skb, ifindex, family);
4742#ifdef CONFIG_XFRM 4499#ifdef CONFIG_XFRM
4743 /* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec 4500 /* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec
@@ -4844,7 +4601,7 @@ static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
4844{ 4601{
4845 int err; 4602 int err;
4846 4603
4847 err = secondary_ops->netlink_send(sk, skb); 4604 err = cap_netlink_send(sk, skb);
4848 if (err) 4605 if (err)
4849 return err; 4606 return err;
4850 4607
@@ -4859,7 +4616,7 @@ static int selinux_netlink_recv(struct sk_buff *skb, int capability)
4859 int err; 4616 int err;
4860 struct avc_audit_data ad; 4617 struct avc_audit_data ad;
4861 4618
4862 err = secondary_ops->netlink_recv(skb, capability); 4619 err = cap_netlink_recv(skb, capability);
4863 if (err) 4620 if (err)
4864 return err; 4621 return err;
4865 4622
@@ -5167,11 +4924,6 @@ static int selinux_shm_shmat(struct shmid_kernel *shp,
5167 char __user *shmaddr, int shmflg) 4924 char __user *shmaddr, int shmflg)
5168{ 4925{
5169 u32 perms; 4926 u32 perms;
5170 int rc;
5171
5172 rc = secondary_ops->shm_shmat(shp, shmaddr, shmflg);
5173 if (rc)
5174 return rc;
5175 4927
5176 if (shmflg & SHM_RDONLY) 4928 if (shmflg & SHM_RDONLY)
5177 perms = SHM__READ; 4929 perms = SHM__READ;
@@ -5581,7 +5333,6 @@ static struct security_operations selinux_ops = {
5581 .netlink_recv = selinux_netlink_recv, 5333 .netlink_recv = selinux_netlink_recv,
5582 5334
5583 .bprm_set_creds = selinux_bprm_set_creds, 5335 .bprm_set_creds = selinux_bprm_set_creds,
5584 .bprm_check_security = selinux_bprm_check_security,
5585 .bprm_committing_creds = selinux_bprm_committing_creds, 5336 .bprm_committing_creds = selinux_bprm_committing_creds,
5586 .bprm_committed_creds = selinux_bprm_committed_creds, 5337 .bprm_committed_creds = selinux_bprm_committed_creds,
5587 .bprm_secureexec = selinux_bprm_secureexec, 5338 .bprm_secureexec = selinux_bprm_secureexec,
@@ -5623,8 +5374,6 @@ static struct security_operations selinux_ops = {
5623 .inode_getsecurity = selinux_inode_getsecurity, 5374 .inode_getsecurity = selinux_inode_getsecurity,
5624 .inode_setsecurity = selinux_inode_setsecurity, 5375 .inode_setsecurity = selinux_inode_setsecurity,
5625 .inode_listsecurity = selinux_inode_listsecurity, 5376 .inode_listsecurity = selinux_inode_listsecurity,
5626 .inode_need_killpriv = selinux_inode_need_killpriv,
5627 .inode_killpriv = selinux_inode_killpriv,
5628 .inode_getsecid = selinux_inode_getsecid, 5377 .inode_getsecid = selinux_inode_getsecid,
5629 5378
5630 .file_permission = selinux_file_permission, 5379 .file_permission = selinux_file_permission,
@@ -5644,17 +5393,12 @@ static struct security_operations selinux_ops = {
5644 .task_create = selinux_task_create, 5393 .task_create = selinux_task_create,
5645 .cred_free = selinux_cred_free, 5394 .cred_free = selinux_cred_free,
5646 .cred_prepare = selinux_cred_prepare, 5395 .cred_prepare = selinux_cred_prepare,
5647 .cred_commit = selinux_cred_commit,
5648 .kernel_act_as = selinux_kernel_act_as, 5396 .kernel_act_as = selinux_kernel_act_as,
5649 .kernel_create_files_as = selinux_kernel_create_files_as, 5397 .kernel_create_files_as = selinux_kernel_create_files_as,
5650 .task_setuid = selinux_task_setuid,
5651 .task_fix_setuid = selinux_task_fix_setuid,
5652 .task_setgid = selinux_task_setgid,
5653 .task_setpgid = selinux_task_setpgid, 5398 .task_setpgid = selinux_task_setpgid,
5654 .task_getpgid = selinux_task_getpgid, 5399 .task_getpgid = selinux_task_getpgid,
5655 .task_getsid = selinux_task_getsid, 5400 .task_getsid = selinux_task_getsid,
5656 .task_getsecid = selinux_task_getsecid, 5401 .task_getsecid = selinux_task_getsecid,
5657 .task_setgroups = selinux_task_setgroups,
5658 .task_setnice = selinux_task_setnice, 5402 .task_setnice = selinux_task_setnice,
5659 .task_setioprio = selinux_task_setioprio, 5403 .task_setioprio = selinux_task_setioprio,
5660 .task_getioprio = selinux_task_getioprio, 5404 .task_getioprio = selinux_task_getioprio,
@@ -5664,7 +5408,6 @@ static struct security_operations selinux_ops = {
5664 .task_movememory = selinux_task_movememory, 5408 .task_movememory = selinux_task_movememory,
5665 .task_kill = selinux_task_kill, 5409 .task_kill = selinux_task_kill,
5666 .task_wait = selinux_task_wait, 5410 .task_wait = selinux_task_wait,
5667 .task_prctl = selinux_task_prctl,
5668 .task_to_inode = selinux_task_to_inode, 5411 .task_to_inode = selinux_task_to_inode,
5669 5412
5670 .ipc_permission = selinux_ipc_permission, 5413 .ipc_permission = selinux_ipc_permission,
diff --git a/security/selinux/include/av_perm_to_string.h b/security/selinux/include/av_perm_to_string.h
index c0c885427b91..31df1d7c1aee 100644
--- a/security/selinux/include/av_perm_to_string.h
+++ b/security/selinux/include/av_perm_to_string.h
@@ -24,6 +24,7 @@
24 S_(SECCLASS_CHR_FILE, CHR_FILE__EXECMOD, "execmod") 24 S_(SECCLASS_CHR_FILE, CHR_FILE__EXECMOD, "execmod")
25 S_(SECCLASS_CHR_FILE, CHR_FILE__OPEN, "open") 25 S_(SECCLASS_CHR_FILE, CHR_FILE__OPEN, "open")
26 S_(SECCLASS_BLK_FILE, BLK_FILE__OPEN, "open") 26 S_(SECCLASS_BLK_FILE, BLK_FILE__OPEN, "open")
27 S_(SECCLASS_SOCK_FILE, SOCK_FILE__OPEN, "open")
27 S_(SECCLASS_FIFO_FILE, FIFO_FILE__OPEN, "open") 28 S_(SECCLASS_FIFO_FILE, FIFO_FILE__OPEN, "open")
28 S_(SECCLASS_FD, FD__USE, "use") 29 S_(SECCLASS_FD, FD__USE, "use")
29 S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__CONNECTTO, "connectto") 30 S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__CONNECTTO, "connectto")
@@ -152,6 +153,7 @@
152 S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_WRITE, "nlmsg_write") 153 S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_WRITE, "nlmsg_write")
153 S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_RELAY, "nlmsg_relay") 154 S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_RELAY, "nlmsg_relay")
154 S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_READPRIV, "nlmsg_readpriv") 155 S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_READPRIV, "nlmsg_readpriv")
156 S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_TTY_AUDIT, "nlmsg_tty_audit")
155 S_(SECCLASS_NETLINK_IP6FW_SOCKET, NETLINK_IP6FW_SOCKET__NLMSG_READ, "nlmsg_read") 157 S_(SECCLASS_NETLINK_IP6FW_SOCKET, NETLINK_IP6FW_SOCKET__NLMSG_READ, "nlmsg_read")
156 S_(SECCLASS_NETLINK_IP6FW_SOCKET, NETLINK_IP6FW_SOCKET__NLMSG_WRITE, "nlmsg_write") 158 S_(SECCLASS_NETLINK_IP6FW_SOCKET, NETLINK_IP6FW_SOCKET__NLMSG_WRITE, "nlmsg_write")
157 S_(SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO, "sendto") 159 S_(SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO, "sendto")
diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h
index 0ba79fe00e11..d645192ee950 100644
--- a/security/selinux/include/av_permissions.h
+++ b/security/selinux/include/av_permissions.h
@@ -174,6 +174,7 @@
174#define SOCK_FILE__SWAPON 0x00004000UL 174#define SOCK_FILE__SWAPON 0x00004000UL
175#define SOCK_FILE__QUOTAON 0x00008000UL 175#define SOCK_FILE__QUOTAON 0x00008000UL
176#define SOCK_FILE__MOUNTON 0x00010000UL 176#define SOCK_FILE__MOUNTON 0x00010000UL
177#define SOCK_FILE__OPEN 0x00020000UL
177#define FIFO_FILE__IOCTL 0x00000001UL 178#define FIFO_FILE__IOCTL 0x00000001UL
178#define FIFO_FILE__READ 0x00000002UL 179#define FIFO_FILE__READ 0x00000002UL
179#define FIFO_FILE__WRITE 0x00000004UL 180#define FIFO_FILE__WRITE 0x00000004UL
@@ -707,6 +708,7 @@
707#define NETLINK_AUDIT_SOCKET__NLMSG_WRITE 0x00800000UL 708#define NETLINK_AUDIT_SOCKET__NLMSG_WRITE 0x00800000UL
708#define NETLINK_AUDIT_SOCKET__NLMSG_RELAY 0x01000000UL 709#define NETLINK_AUDIT_SOCKET__NLMSG_RELAY 0x01000000UL
709#define NETLINK_AUDIT_SOCKET__NLMSG_READPRIV 0x02000000UL 710#define NETLINK_AUDIT_SOCKET__NLMSG_READPRIV 0x02000000UL
711#define NETLINK_AUDIT_SOCKET__NLMSG_TTY_AUDIT 0x04000000UL
710#define NETLINK_IP6FW_SOCKET__IOCTL 0x00000001UL 712#define NETLINK_IP6FW_SOCKET__IOCTL 0x00000001UL
711#define NETLINK_IP6FW_SOCKET__READ 0x00000002UL 713#define NETLINK_IP6FW_SOCKET__READ 0x00000002UL
712#define NETLINK_IP6FW_SOCKET__WRITE 0x00000004UL 714#define NETLINK_IP6FW_SOCKET__WRITE 0x00000004UL
diff --git a/security/selinux/include/netlabel.h b/security/selinux/include/netlabel.h
index b913c8d06038..b4b5b9b2f0be 100644
--- a/security/selinux/include/netlabel.h
+++ b/security/selinux/include/netlabel.h
@@ -32,6 +32,7 @@
32#include <linux/net.h> 32#include <linux/net.h>
33#include <linux/skbuff.h> 33#include <linux/skbuff.h>
34#include <net/sock.h> 34#include <net/sock.h>
35#include <net/request_sock.h>
35 36
36#include "avc.h" 37#include "avc.h"
37#include "objsec.h" 38#include "objsec.h"
@@ -42,8 +43,7 @@ void selinux_netlbl_cache_invalidate(void);
42void selinux_netlbl_err(struct sk_buff *skb, int error, int gateway); 43void selinux_netlbl_err(struct sk_buff *skb, int error, int gateway);
43 44
44void selinux_netlbl_sk_security_free(struct sk_security_struct *ssec); 45void selinux_netlbl_sk_security_free(struct sk_security_struct *ssec);
45void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec, 46void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec);
46 int family);
47 47
48int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, 48int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
49 u16 family, 49 u16 family,
@@ -53,9 +53,9 @@ int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
53 u16 family, 53 u16 family,
54 u32 sid); 54 u32 sid);
55 55
56void selinux_netlbl_inet_conn_established(struct sock *sk, u16 family); 56int selinux_netlbl_inet_conn_request(struct request_sock *req, u16 family);
57int selinux_netlbl_socket_post_create(struct socket *sock); 57void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family);
58int selinux_netlbl_inode_permission(struct inode *inode, int mask); 58int selinux_netlbl_socket_post_create(struct sock *sk, u16 family);
59int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec, 59int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
60 struct sk_buff *skb, 60 struct sk_buff *skb,
61 u16 family, 61 u16 family,
@@ -85,8 +85,7 @@ static inline void selinux_netlbl_sk_security_free(
85} 85}
86 86
87static inline void selinux_netlbl_sk_security_reset( 87static inline void selinux_netlbl_sk_security_reset(
88 struct sk_security_struct *ssec, 88 struct sk_security_struct *ssec)
89 int family)
90{ 89{
91 return; 90 return;
92} 91}
@@ -113,17 +112,17 @@ static inline int selinux_netlbl_conn_setsid(struct sock *sk,
113 return 0; 112 return 0;
114} 113}
115 114
116static inline void selinux_netlbl_inet_conn_established(struct sock *sk, 115static inline int selinux_netlbl_inet_conn_request(struct request_sock *req,
117 u16 family) 116 u16 family)
118{ 117{
119 return; 118 return 0;
120} 119}
121static inline int selinux_netlbl_socket_post_create(struct socket *sock) 120static inline void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family)
122{ 121{
123 return 0; 122 return;
124} 123}
125static inline int selinux_netlbl_inode_permission(struct inode *inode, 124static inline int selinux_netlbl_socket_post_create(struct sock *sk,
126 int mask) 125 u16 family)
127{ 126{
128 return 0; 127 return 0;
129} 128}
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index 3cc45168f674..c4e062336ef3 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -60,9 +60,7 @@ struct superblock_security_struct {
60 u32 def_sid; /* default SID for labeling */ 60 u32 def_sid; /* default SID for labeling */
61 u32 mntpoint_sid; /* SECURITY_FS_USE_MNTPOINT context for files */ 61 u32 mntpoint_sid; /* SECURITY_FS_USE_MNTPOINT context for files */
62 unsigned int behavior; /* labeling behavior */ 62 unsigned int behavior; /* labeling behavior */
63 unsigned char initialized; /* initialization flag */
64 unsigned char flags; /* which mount options were specified */ 63 unsigned char flags; /* which mount options were specified */
65 unsigned char proc; /* proc fs */
66 struct mutex lock; 64 struct mutex lock;
67 struct list_head isec_head; 65 struct list_head isec_head;
68 spinlock_t isec_lock; 66 spinlock_t isec_lock;
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 72447370bc95..5c3434f7626f 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -37,15 +37,23 @@
37#define POLICYDB_VERSION_MAX POLICYDB_VERSION_BOUNDARY 37#define POLICYDB_VERSION_MAX POLICYDB_VERSION_BOUNDARY
38#endif 38#endif
39 39
40/* Mask for just the mount related flags */
41#define SE_MNTMASK 0x0f
42/* Super block security struct flags for mount options */
40#define CONTEXT_MNT 0x01 43#define CONTEXT_MNT 0x01
41#define FSCONTEXT_MNT 0x02 44#define FSCONTEXT_MNT 0x02
42#define ROOTCONTEXT_MNT 0x04 45#define ROOTCONTEXT_MNT 0x04
43#define DEFCONTEXT_MNT 0x08 46#define DEFCONTEXT_MNT 0x08
47/* Non-mount related flags */
48#define SE_SBINITIALIZED 0x10
49#define SE_SBPROC 0x20
50#define SE_SBLABELSUPP 0x40
44 51
45#define CONTEXT_STR "context=" 52#define CONTEXT_STR "context="
46#define FSCONTEXT_STR "fscontext=" 53#define FSCONTEXT_STR "fscontext="
47#define ROOTCONTEXT_STR "rootcontext=" 54#define ROOTCONTEXT_STR "rootcontext="
48#define DEFCONTEXT_STR "defcontext=" 55#define DEFCONTEXT_STR "defcontext="
56#define LABELSUPP_STR "seclabel"
49 57
50struct netlbl_lsm_secattr; 58struct netlbl_lsm_secattr;
51 59
@@ -80,7 +88,6 @@ int security_policycap_supported(unsigned int req_cap);
80#define SEL_VEC_MAX 32 88#define SEL_VEC_MAX 32
81struct av_decision { 89struct av_decision {
82 u32 allowed; 90 u32 allowed;
83 u32 decided;
84 u32 auditallow; 91 u32 auditallow;
85 u32 auditdeny; 92 u32 auditdeny;
86 u32 seqno; 93 u32 seqno;
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c
index 350794ab9b42..2e984413c7b2 100644
--- a/security/selinux/netlabel.c
+++ b/security/selinux/netlabel.c
@@ -100,41 +100,6 @@ static struct netlbl_lsm_secattr *selinux_netlbl_sock_genattr(struct sock *sk)
100} 100}
101 101
102/** 102/**
103 * selinux_netlbl_sock_setsid - Label a socket using the NetLabel mechanism
104 * @sk: the socket to label
105 *
106 * Description:
107 * Attempt to label a socket using the NetLabel mechanism. Returns zero values
108 * on success, negative values on failure.
109 *
110 */
111static int selinux_netlbl_sock_setsid(struct sock *sk)
112{
113 int rc;
114 struct sk_security_struct *sksec = sk->sk_security;
115 struct netlbl_lsm_secattr *secattr;
116
117 if (sksec->nlbl_state != NLBL_REQUIRE)
118 return 0;
119
120 secattr = selinux_netlbl_sock_genattr(sk);
121 if (secattr == NULL)
122 return -ENOMEM;
123 rc = netlbl_sock_setattr(sk, secattr);
124 switch (rc) {
125 case 0:
126 sksec->nlbl_state = NLBL_LABELED;
127 break;
128 case -EDESTADDRREQ:
129 sksec->nlbl_state = NLBL_REQSKB;
130 rc = 0;
131 break;
132 }
133
134 return rc;
135}
136
137/**
138 * selinux_netlbl_cache_invalidate - Invalidate the NetLabel cache 103 * selinux_netlbl_cache_invalidate - Invalidate the NetLabel cache
139 * 104 *
140 * Description: 105 * Description:
@@ -188,13 +153,9 @@ void selinux_netlbl_sk_security_free(struct sk_security_struct *ssec)
188 * The caller is responsibile for all the NetLabel sk_security_struct locking. 153 * The caller is responsibile for all the NetLabel sk_security_struct locking.
189 * 154 *
190 */ 155 */
191void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec, 156void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec)
192 int family)
193{ 157{
194 if (family == PF_INET) 158 ssec->nlbl_state = NLBL_UNSET;
195 ssec->nlbl_state = NLBL_REQUIRE;
196 else
197 ssec->nlbl_state = NLBL_UNSET;
198} 159}
199 160
200/** 161/**
@@ -281,127 +242,86 @@ skbuff_setsid_return:
281} 242}
282 243
283/** 244/**
284 * selinux_netlbl_inet_conn_established - Netlabel the newly accepted connection 245 * selinux_netlbl_inet_conn_request - Label an incoming stream connection
285 * @sk: the new connection 246 * @req: incoming connection request socket
286 * 247 *
287 * Description: 248 * Description:
288 * A new connection has been established on @sk so make sure it is labeled 249 * A new incoming connection request is represented by @req, we need to label
289 * correctly with the NetLabel susbsystem. 250 * the new request_sock here and the stack will ensure the on-the-wire label
251 * will get preserved when a full sock is created once the connection handshake
252 * is complete. Returns zero on success, negative values on failure.
290 * 253 *
291 */ 254 */
292void selinux_netlbl_inet_conn_established(struct sock *sk, u16 family) 255int selinux_netlbl_inet_conn_request(struct request_sock *req, u16 family)
293{ 256{
294 int rc; 257 int rc;
295 struct sk_security_struct *sksec = sk->sk_security; 258 struct netlbl_lsm_secattr secattr;
296 struct netlbl_lsm_secattr *secattr;
297 struct inet_sock *sk_inet = inet_sk(sk);
298 struct sockaddr_in addr;
299
300 if (sksec->nlbl_state != NLBL_REQUIRE)
301 return;
302 259
303 secattr = selinux_netlbl_sock_genattr(sk); 260 if (family != PF_INET)
304 if (secattr == NULL) 261 return 0;
305 return;
306 262
307 rc = netlbl_sock_setattr(sk, secattr); 263 netlbl_secattr_init(&secattr);
308 switch (rc) { 264 rc = security_netlbl_sid_to_secattr(req->secid, &secattr);
309 case 0: 265 if (rc != 0)
310 sksec->nlbl_state = NLBL_LABELED; 266 goto inet_conn_request_return;
311 break; 267 rc = netlbl_req_setattr(req, &secattr);
312 case -EDESTADDRREQ: 268inet_conn_request_return:
313 /* no PF_INET6 support yet because we don't support any IPv6 269 netlbl_secattr_destroy(&secattr);
314 * labeling protocols */ 270 return rc;
315 if (family != PF_INET) {
316 sksec->nlbl_state = NLBL_UNSET;
317 return;
318 }
319
320 addr.sin_family = family;
321 addr.sin_addr.s_addr = sk_inet->daddr;
322 if (netlbl_conn_setattr(sk, (struct sockaddr *)&addr,
323 secattr) != 0) {
324 /* we failed to label the connected socket (could be
325 * for a variety of reasons, the actual "why" isn't
326 * important here) so we have to go to our backup plan,
327 * labeling the packets individually in the netfilter
328 * local output hook. this is okay but we need to
329 * adjust the MSS of the connection to take into
330 * account any labeling overhead, since we don't know
331 * the exact overhead at this point we'll use the worst
332 * case value which is 40 bytes for IPv4 */
333 struct inet_connection_sock *sk_conn = inet_csk(sk);
334 sk_conn->icsk_ext_hdr_len += 40 -
335 (sk_inet->opt ? sk_inet->opt->optlen : 0);
336 sk_conn->icsk_sync_mss(sk, sk_conn->icsk_pmtu_cookie);
337
338 sksec->nlbl_state = NLBL_REQSKB;
339 } else
340 sksec->nlbl_state = NLBL_CONNLABELED;
341 break;
342 default:
343 /* note that we are failing to label the socket which could be
344 * a bad thing since it means traffic could leave the system
345 * without the desired labeling, however, all is not lost as
346 * we have a check in selinux_netlbl_inode_permission() to
347 * pick up the pieces that we might drop here because we can't
348 * return an error code */
349 break;
350 }
351} 271}
352 272
353/** 273/**
354 * selinux_netlbl_socket_post_create - Label a socket using NetLabel 274 * selinux_netlbl_inet_csk_clone - Initialize the newly created sock
355 * @sock: the socket to label 275 * @sk: the new sock
356 * 276 *
357 * Description: 277 * Description:
358 * Attempt to label a socket using the NetLabel mechanism using the given 278 * A new connection has been established using @sk, we've already labeled the
359 * SID. Returns zero values on success, negative values on failure. 279 * socket via the request_sock struct in selinux_netlbl_inet_conn_request() but
280 * we need to set the NetLabel state here since we now have a sock structure.
360 * 281 *
361 */ 282 */
362int selinux_netlbl_socket_post_create(struct socket *sock) 283void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family)
363{ 284{
364 return selinux_netlbl_sock_setsid(sock->sk); 285 struct sk_security_struct *sksec = sk->sk_security;
286
287 if (family == PF_INET)
288 sksec->nlbl_state = NLBL_LABELED;
289 else
290 sksec->nlbl_state = NLBL_UNSET;
365} 291}
366 292
367/** 293/**
368 * selinux_netlbl_inode_permission - Verify the socket is NetLabel labeled 294 * selinux_netlbl_socket_post_create - Label a socket using NetLabel
369 * @inode: the file descriptor's inode 295 * @sock: the socket to label
370 * @mask: the permission mask 296 * @family: protocol family
371 * 297 *
372 * Description: 298 * Description:
373 * Looks at a file's inode and if it is marked as a socket protected by 299 * Attempt to label a socket using the NetLabel mechanism using the given
374 * NetLabel then verify that the socket has been labeled, if not try to label 300 * SID. Returns zero values on success, negative values on failure.
375 * the socket now with the inode's SID. Returns zero on success, negative
376 * values on failure.
377 * 301 *
378 */ 302 */
379int selinux_netlbl_inode_permission(struct inode *inode, int mask) 303int selinux_netlbl_socket_post_create(struct sock *sk, u16 family)
380{ 304{
381 int rc; 305 int rc;
382 struct sock *sk; 306 struct sk_security_struct *sksec = sk->sk_security;
383 struct socket *sock; 307 struct netlbl_lsm_secattr *secattr;
384 struct sk_security_struct *sksec;
385 308
386 if (!S_ISSOCK(inode->i_mode) || 309 if (family != PF_INET)
387 ((mask & (MAY_WRITE | MAY_APPEND)) == 0))
388 return 0;
389 sock = SOCKET_I(inode);
390 sk = sock->sk;
391 if (sk == NULL)
392 return 0;
393 sksec = sk->sk_security;
394 if (sksec == NULL || sksec->nlbl_state != NLBL_REQUIRE)
395 return 0; 310 return 0;
396 311
397 local_bh_disable(); 312 secattr = selinux_netlbl_sock_genattr(sk);
398 bh_lock_sock_nested(sk); 313 if (secattr == NULL)
399 if (likely(sksec->nlbl_state == NLBL_REQUIRE)) 314 return -ENOMEM;
400 rc = selinux_netlbl_sock_setsid(sk); 315 rc = netlbl_sock_setattr(sk, family, secattr);
401 else 316 switch (rc) {
317 case 0:
318 sksec->nlbl_state = NLBL_LABELED;
319 break;
320 case -EDESTADDRREQ:
321 sksec->nlbl_state = NLBL_REQSKB;
402 rc = 0; 322 rc = 0;
403 bh_unlock_sock(sk); 323 break;
404 local_bh_enable(); 324 }
405 325
406 return rc; 326 return rc;
407} 327}
diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c
index 4ed7bab89c59..c6875fd3b9d6 100644
--- a/security/selinux/nlmsgtab.c
+++ b/security/selinux/nlmsgtab.c
@@ -113,7 +113,7 @@ static struct nlmsg_perm nlmsg_audit_perms[] =
113 { AUDIT_USER, NETLINK_AUDIT_SOCKET__NLMSG_RELAY }, 113 { AUDIT_USER, NETLINK_AUDIT_SOCKET__NLMSG_RELAY },
114 { AUDIT_SIGNAL_INFO, NETLINK_AUDIT_SOCKET__NLMSG_READ }, 114 { AUDIT_SIGNAL_INFO, NETLINK_AUDIT_SOCKET__NLMSG_READ },
115 { AUDIT_TTY_GET, NETLINK_AUDIT_SOCKET__NLMSG_READ }, 115 { AUDIT_TTY_GET, NETLINK_AUDIT_SOCKET__NLMSG_READ },
116 { AUDIT_TTY_SET, NETLINK_AUDIT_SOCKET__NLMSG_WRITE }, 116 { AUDIT_TTY_SET, NETLINK_AUDIT_SOCKET__NLMSG_TTY_AUDIT },
117}; 117};
118 118
119 119
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 01ec6d2c6b97..2d5136ec3d54 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -47,8 +47,6 @@ static char *policycap_names[] = {
47 47
48unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE; 48unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
49 49
50int selinux_compat_net = 0;
51
52static int __init checkreqprot_setup(char *str) 50static int __init checkreqprot_setup(char *str)
53{ 51{
54 unsigned long checkreqprot; 52 unsigned long checkreqprot;
@@ -58,16 +56,6 @@ static int __init checkreqprot_setup(char *str)
58} 56}
59__setup("checkreqprot=", checkreqprot_setup); 57__setup("checkreqprot=", checkreqprot_setup);
60 58
61static int __init selinux_compat_net_setup(char *str)
62{
63 unsigned long compat_net;
64 if (!strict_strtoul(str, 0, &compat_net))
65 selinux_compat_net = compat_net ? 1 : 0;
66 return 1;
67}
68__setup("selinux_compat_net=", selinux_compat_net_setup);
69
70
71static DEFINE_MUTEX(sel_mutex); 59static DEFINE_MUTEX(sel_mutex);
72 60
73/* global data for booleans */ 61/* global data for booleans */
@@ -450,61 +438,6 @@ static const struct file_operations sel_checkreqprot_ops = {
450 .write = sel_write_checkreqprot, 438 .write = sel_write_checkreqprot,
451}; 439};
452 440
453static ssize_t sel_read_compat_net(struct file *filp, char __user *buf,
454 size_t count, loff_t *ppos)
455{
456 char tmpbuf[TMPBUFLEN];
457 ssize_t length;
458
459 length = scnprintf(tmpbuf, TMPBUFLEN, "%d", selinux_compat_net);
460 return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
461}
462
463static ssize_t sel_write_compat_net(struct file *file, const char __user *buf,
464 size_t count, loff_t *ppos)
465{
466 char *page;
467 ssize_t length;
468 int new_value;
469
470 length = task_has_security(current, SECURITY__LOAD_POLICY);
471 if (length)
472 return length;
473
474 if (count >= PAGE_SIZE)
475 return -ENOMEM;
476 if (*ppos != 0) {
477 /* No partial writes. */
478 return -EINVAL;
479 }
480 page = (char *)get_zeroed_page(GFP_KERNEL);
481 if (!page)
482 return -ENOMEM;
483 length = -EFAULT;
484 if (copy_from_user(page, buf, count))
485 goto out;
486
487 length = -EINVAL;
488 if (sscanf(page, "%d", &new_value) != 1)
489 goto out;
490
491 if (new_value) {
492 printk(KERN_NOTICE
493 "SELinux: compat_net is deprecated, please use secmark"
494 " instead\n");
495 selinux_compat_net = 1;
496 } else
497 selinux_compat_net = 0;
498 length = count;
499out:
500 free_page((unsigned long) page);
501 return length;
502}
503static const struct file_operations sel_compat_net_ops = {
504 .read = sel_read_compat_net,
505 .write = sel_write_compat_net,
506};
507
508/* 441/*
509 * Remaining nodes use transaction based IO methods like nfsd/nfsctl.c 442 * Remaining nodes use transaction based IO methods like nfsd/nfsctl.c
510 */ 443 */
@@ -595,7 +528,7 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
595 528
596 length = scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, 529 length = scnprintf(buf, SIMPLE_TRANSACTION_LIMIT,
597 "%x %x %x %x %u", 530 "%x %x %x %x %u",
598 avd.allowed, avd.decided, 531 avd.allowed, 0xffffffff,
599 avd.auditallow, avd.auditdeny, 532 avd.auditallow, avd.auditdeny,
600 avd.seqno); 533 avd.seqno);
601out2: 534out2:
@@ -1665,7 +1598,6 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
1665 [SEL_DISABLE] = {"disable", &sel_disable_ops, S_IWUSR}, 1598 [SEL_DISABLE] = {"disable", &sel_disable_ops, S_IWUSR},
1666 [SEL_MEMBER] = {"member", &transaction_ops, S_IRUGO|S_IWUGO}, 1599 [SEL_MEMBER] = {"member", &transaction_ops, S_IRUGO|S_IWUGO},
1667 [SEL_CHECKREQPROT] = {"checkreqprot", &sel_checkreqprot_ops, S_IRUGO|S_IWUSR}, 1600 [SEL_CHECKREQPROT] = {"checkreqprot", &sel_checkreqprot_ops, S_IRUGO|S_IWUSR},
1668 [SEL_COMPAT_NET] = {"compat_net", &sel_compat_net_ops, S_IRUGO|S_IWUSR},
1669 [SEL_REJECT_UNKNOWN] = {"reject_unknown", &sel_handle_unknown_ops, S_IRUGO}, 1601 [SEL_REJECT_UNKNOWN] = {"reject_unknown", &sel_handle_unknown_ops, S_IRUGO},
1670 [SEL_DENY_UNKNOWN] = {"deny_unknown", &sel_handle_unknown_ops, S_IRUGO}, 1602 [SEL_DENY_UNKNOWN] = {"deny_unknown", &sel_handle_unknown_ops, S_IRUGO},
1671 /* last one */ {""} 1603 /* last one */ {""}
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index c65e4fe4a0f1..deeec6c013ae 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -407,7 +407,6 @@ static int context_struct_compute_av(struct context *scontext,
407 * Initialize the access vectors to the default values. 407 * Initialize the access vectors to the default values.
408 */ 408 */
409 avd->allowed = 0; 409 avd->allowed = 0;
410 avd->decided = 0xffffffff;
411 avd->auditallow = 0; 410 avd->auditallow = 0;
412 avd->auditdeny = 0xffffffff; 411 avd->auditdeny = 0xffffffff;
413 avd->seqno = latest_granting; 412 avd->seqno = latest_granting;
@@ -743,7 +742,6 @@ int security_compute_av(u32 ssid,
743 742
744 if (!ss_initialized) { 743 if (!ss_initialized) {
745 avd->allowed = 0xffffffff; 744 avd->allowed = 0xffffffff;
746 avd->decided = 0xffffffff;
747 avd->auditallow = 0; 745 avd->auditallow = 0;
748 avd->auditdeny = 0xffffffff; 746 avd->auditdeny = 0xffffffff;
749 avd->seqno = latest_granting; 747 avd->seqno = latest_granting;