aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/capability.c2
-rw-r--r--security/keys/user_defined.c16
-rw-r--r--security/security.c6
-rw-r--r--security/selinux/avc.c36
-rw-r--r--security/selinux/hooks.c27
-rw-r--r--security/selinux/include/avc.h18
-rw-r--r--security/selinux/netif.c18
-rw-r--r--security/selinux/ss/policydb.c10
-rw-r--r--security/smack/smack_lsm.c6
9 files changed, 72 insertions, 67 deletions
diff --git a/security/capability.c b/security/capability.c
index 2984ea4f776..bbb51156261 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -181,7 +181,7 @@ static int cap_inode_follow_link(struct dentry *dentry,
181 return 0; 181 return 0;
182} 182}
183 183
184static int cap_inode_permission(struct inode *inode, int mask) 184static int cap_inode_permission(struct inode *inode, int mask, unsigned flags)
185{ 185{
186 return 0; 186 return 0;
187} 187}
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index c6ca8662a46..f66baf44f32 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -69,18 +69,6 @@ error:
69EXPORT_SYMBOL_GPL(user_instantiate); 69EXPORT_SYMBOL_GPL(user_instantiate);
70 70
71/* 71/*
72 * dispose of the old data from an updated user defined key
73 */
74static void user_update_rcu_disposal(struct rcu_head *rcu)
75{
76 struct user_key_payload *upayload;
77
78 upayload = container_of(rcu, struct user_key_payload, rcu);
79
80 kfree(upayload);
81}
82
83/*
84 * update a user defined key 72 * update a user defined key
85 * - the key's semaphore is write-locked 73 * - the key's semaphore is write-locked
86 */ 74 */
@@ -114,7 +102,7 @@ int user_update(struct key *key, const void *data, size_t datalen)
114 key->expiry = 0; 102 key->expiry = 0;
115 } 103 }
116 104
117 call_rcu(&zap->rcu, user_update_rcu_disposal); 105 kfree_rcu(zap, rcu);
118 106
119error: 107error:
120 return ret; 108 return ret;
@@ -145,7 +133,7 @@ void user_revoke(struct key *key)
145 133
146 if (upayload) { 134 if (upayload) {
147 rcu_assign_pointer(key->payload.data, NULL); 135 rcu_assign_pointer(key->payload.data, NULL);
148 call_rcu(&upayload->rcu, user_update_rcu_disposal); 136 kfree_rcu(upayload, rcu);
149 } 137 }
150} 138}
151 139
diff --git a/security/security.c b/security/security.c
index 101142369db..4ba6d4cc061 100644
--- a/security/security.c
+++ b/security/security.c
@@ -518,16 +518,14 @@ int security_inode_permission(struct inode *inode, int mask)
518{ 518{
519 if (unlikely(IS_PRIVATE(inode))) 519 if (unlikely(IS_PRIVATE(inode)))
520 return 0; 520 return 0;
521 return security_ops->inode_permission(inode, mask); 521 return security_ops->inode_permission(inode, mask, 0);
522} 522}
523 523
524int security_inode_exec_permission(struct inode *inode, unsigned int flags) 524int security_inode_exec_permission(struct inode *inode, unsigned int flags)
525{ 525{
526 if (unlikely(IS_PRIVATE(inode))) 526 if (unlikely(IS_PRIVATE(inode)))
527 return 0; 527 return 0;
528 if (flags) 528 return security_ops->inode_permission(inode, MAY_EXEC, flags);
529 return -ECHILD;
530 return security_ops->inode_permission(inode, MAY_EXEC);
531} 529}
532 530
533int security_inode_setattr(struct dentry *dentry, struct iattr *attr) 531int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index 9da6420e205..1d027e29ce8 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -471,6 +471,7 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a)
471 * @avd: access vector decisions 471 * @avd: access vector decisions
472 * @result: result from avc_has_perm_noaudit 472 * @result: result from avc_has_perm_noaudit
473 * @a: auxiliary audit data 473 * @a: auxiliary audit data
474 * @flags: VFS walk flags
474 * 475 *
475 * Audit the granting or denial of permissions in accordance 476 * Audit the granting or denial of permissions in accordance
476 * with the policy. This function is typically called by 477 * with the policy. This function is typically called by
@@ -481,9 +482,10 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a)
481 * be performed under a lock, to allow the lock to be released 482 * be performed under a lock, to allow the lock to be released
482 * before calling the auditing code. 483 * before calling the auditing code.
483 */ 484 */
484void avc_audit(u32 ssid, u32 tsid, 485int avc_audit(u32 ssid, u32 tsid,
485 u16 tclass, u32 requested, 486 u16 tclass, u32 requested,
486 struct av_decision *avd, int result, struct common_audit_data *a) 487 struct av_decision *avd, int result, struct common_audit_data *a,
488 unsigned flags)
487{ 489{
488 struct common_audit_data stack_data; 490 struct common_audit_data stack_data;
489 u32 denied, audited; 491 u32 denied, audited;
@@ -515,11 +517,24 @@ void avc_audit(u32 ssid, u32 tsid,
515 else 517 else
516 audited = requested & avd->auditallow; 518 audited = requested & avd->auditallow;
517 if (!audited) 519 if (!audited)
518 return; 520 return 0;
521
519 if (!a) { 522 if (!a) {
520 a = &stack_data; 523 a = &stack_data;
521 COMMON_AUDIT_DATA_INIT(a, NONE); 524 COMMON_AUDIT_DATA_INIT(a, NONE);
522 } 525 }
526
527 /*
528 * When in a RCU walk do the audit on the RCU retry. This is because
529 * the collection of the dname in an inode audit message is not RCU
530 * safe. Note this may drop some audits when the situation changes
531 * during retry. However this is logically just as if the operation
532 * happened a little later.
533 */
534 if ((a->type == LSM_AUDIT_DATA_FS) &&
535 (flags & IPERM_FLAG_RCU))
536 return -ECHILD;
537
523 a->selinux_audit_data.tclass = tclass; 538 a->selinux_audit_data.tclass = tclass;
524 a->selinux_audit_data.requested = requested; 539 a->selinux_audit_data.requested = requested;
525 a->selinux_audit_data.ssid = ssid; 540 a->selinux_audit_data.ssid = ssid;
@@ -529,6 +544,7 @@ void avc_audit(u32 ssid, u32 tsid,
529 a->lsm_pre_audit = avc_audit_pre_callback; 544 a->lsm_pre_audit = avc_audit_pre_callback;
530 a->lsm_post_audit = avc_audit_post_callback; 545 a->lsm_post_audit = avc_audit_post_callback;
531 common_lsm_audit(a); 546 common_lsm_audit(a);
547 return 0;
532} 548}
533 549
534/** 550/**
@@ -793,6 +809,7 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid,
793 * @tclass: target security class 809 * @tclass: target security class
794 * @requested: requested permissions, interpreted based on @tclass 810 * @requested: requested permissions, interpreted based on @tclass
795 * @auditdata: auxiliary audit data 811 * @auditdata: auxiliary audit data
812 * @flags: VFS walk flags
796 * 813 *
797 * Check the AVC to determine whether the @requested permissions are granted 814 * Check the AVC to determine whether the @requested permissions are granted
798 * for the SID pair (@ssid, @tsid), interpreting the permissions 815 * for the SID pair (@ssid, @tsid), interpreting the permissions
@@ -802,14 +819,19 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid,
802 * permissions are granted, -%EACCES if any permissions are denied, or 819 * permissions are granted, -%EACCES if any permissions are denied, or
803 * another -errno upon other errors. 820 * another -errno upon other errors.
804 */ 821 */
805int avc_has_perm(u32 ssid, u32 tsid, u16 tclass, 822int avc_has_perm_flags(u32 ssid, u32 tsid, u16 tclass,
806 u32 requested, struct common_audit_data *auditdata) 823 u32 requested, struct common_audit_data *auditdata,
824 unsigned flags)
807{ 825{
808 struct av_decision avd; 826 struct av_decision avd;
809 int rc; 827 int rc, rc2;
810 828
811 rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, 0, &avd); 829 rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, 0, &avd);
812 avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata); 830
831 rc2 = avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata,
832 flags);
833 if (rc2)
834 return rc2;
813 return rc; 835 return rc;
814} 836}
815 837
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index f9c3764e485..8fb24884300 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1446,8 +1446,11 @@ static int task_has_capability(struct task_struct *tsk,
1446 } 1446 }
1447 1447
1448 rc = avc_has_perm_noaudit(sid, sid, sclass, av, 0, &avd); 1448 rc = avc_has_perm_noaudit(sid, sid, sclass, av, 0, &avd);
1449 if (audit == SECURITY_CAP_AUDIT) 1449 if (audit == SECURITY_CAP_AUDIT) {
1450 avc_audit(sid, sid, sclass, av, &avd, rc, &ad); 1450 int rc2 = avc_audit(sid, sid, sclass, av, &avd, rc, &ad, 0);
1451 if (rc2)
1452 return rc2;
1453 }
1451 return rc; 1454 return rc;
1452} 1455}
1453 1456
@@ -1467,7 +1470,8 @@ static int task_has_system(struct task_struct *tsk,
1467static int inode_has_perm(const struct cred *cred, 1470static int inode_has_perm(const struct cred *cred,
1468 struct inode *inode, 1471 struct inode *inode,
1469 u32 perms, 1472 u32 perms,
1470 struct common_audit_data *adp) 1473 struct common_audit_data *adp,
1474 unsigned flags)
1471{ 1475{
1472 struct inode_security_struct *isec; 1476 struct inode_security_struct *isec;
1473 struct common_audit_data ad; 1477 struct common_audit_data ad;
@@ -1487,7 +1491,7 @@ static int inode_has_perm(const struct cred *cred,
1487 ad.u.fs.inode = inode; 1491 ad.u.fs.inode = inode;
1488 } 1492 }
1489 1493
1490 return avc_has_perm(sid, isec->sid, isec->sclass, perms, adp); 1494 return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags);
1491} 1495}
1492 1496
1493/* Same as inode_has_perm, but pass explicit audit data containing 1497/* Same as inode_has_perm, but pass explicit audit data containing
@@ -1504,7 +1508,7 @@ static inline int dentry_has_perm(const struct cred *cred,
1504 COMMON_AUDIT_DATA_INIT(&ad, FS); 1508 COMMON_AUDIT_DATA_INIT(&ad, FS);
1505 ad.u.fs.path.mnt = mnt; 1509 ad.u.fs.path.mnt = mnt;
1506 ad.u.fs.path.dentry = dentry; 1510 ad.u.fs.path.dentry = dentry;
1507 return inode_has_perm(cred, inode, av, &ad); 1511 return inode_has_perm(cred, inode, av, &ad, 0);
1508} 1512}
1509 1513
1510/* Check whether a task can use an open file descriptor to 1514/* Check whether a task can use an open file descriptor to
@@ -1540,7 +1544,7 @@ static int file_has_perm(const struct cred *cred,
1540 /* av is zero if only checking access to the descriptor. */ 1544 /* av is zero if only checking access to the descriptor. */
1541 rc = 0; 1545 rc = 0;
1542 if (av) 1546 if (av)
1543 rc = inode_has_perm(cred, inode, av, &ad); 1547 rc = inode_has_perm(cred, inode, av, &ad, 0);
1544 1548
1545out: 1549out:
1546 return rc; 1550 return rc;
@@ -1574,7 +1578,8 @@ static int may_create(struct inode *dir,
1574 return rc; 1578 return rc;
1575 1579
1576 if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) { 1580 if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) {
1577 rc = security_transition_sid(sid, dsec->sid, tclass, NULL, &newsid); 1581 rc = security_transition_sid(sid, dsec->sid, tclass,
1582 &dentry->d_name, &newsid);
1578 if (rc) 1583 if (rc)
1579 return rc; 1584 return rc;
1580 } 1585 }
@@ -2103,7 +2108,7 @@ static inline void flush_unauthorized_files(const struct cred *cred,
2103 file = file_priv->file; 2108 file = file_priv->file;
2104 inode = file->f_path.dentry->d_inode; 2109 inode = file->f_path.dentry->d_inode;
2105 if (inode_has_perm(cred, inode, 2110 if (inode_has_perm(cred, inode,
2106 FILE__READ | FILE__WRITE, NULL)) { 2111 FILE__READ | FILE__WRITE, NULL, 0)) {
2107 drop_tty = 1; 2112 drop_tty = 1;
2108 } 2113 }
2109 } 2114 }
@@ -2635,7 +2640,7 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *na
2635 return dentry_has_perm(cred, NULL, dentry, FILE__READ); 2640 return dentry_has_perm(cred, NULL, dentry, FILE__READ);
2636} 2641}
2637 2642
2638static int selinux_inode_permission(struct inode *inode, int mask) 2643static int selinux_inode_permission(struct inode *inode, int mask, unsigned flags)
2639{ 2644{
2640 const struct cred *cred = current_cred(); 2645 const struct cred *cred = current_cred();
2641 struct common_audit_data ad; 2646 struct common_audit_data ad;
@@ -2657,7 +2662,7 @@ static int selinux_inode_permission(struct inode *inode, int mask)
2657 2662
2658 perms = file_mask_to_av(inode->i_mode, mask); 2663 perms = file_mask_to_av(inode->i_mode, mask);
2659 2664
2660 return inode_has_perm(cred, inode, perms, &ad); 2665 return inode_has_perm(cred, inode, perms, &ad, flags);
2661} 2666}
2662 2667
2663static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) 2668static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
@@ -3205,7 +3210,7 @@ static int selinux_dentry_open(struct file *file, const struct cred *cred)
3205 * new inode label or new policy. 3210 * new inode label or new policy.
3206 * This check is not redundant - do not remove. 3211 * This check is not redundant - do not remove.
3207 */ 3212 */
3208 return inode_has_perm(cred, inode, open_file_to_av(file), NULL); 3213 return inode_has_perm(cred, inode, open_file_to_av(file), NULL, 0);
3209} 3214}
3210 3215
3211/* task security operations */ 3216/* task security operations */
diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h
index 5615081b73e..e77b2ac2908 100644
--- a/security/selinux/include/avc.h
+++ b/security/selinux/include/avc.h
@@ -54,11 +54,11 @@ struct avc_cache_stats {
54 54
55void __init avc_init(void); 55void __init avc_init(void);
56 56
57void avc_audit(u32 ssid, u32 tsid, 57int avc_audit(u32 ssid, u32 tsid,
58 u16 tclass, u32 requested, 58 u16 tclass, u32 requested,
59 struct av_decision *avd, 59 struct av_decision *avd,
60 int result, 60 int result,
61 struct common_audit_data *a); 61 struct common_audit_data *a, unsigned flags);
62 62
63#define AVC_STRICT 1 /* Ignore permissive mode. */ 63#define AVC_STRICT 1 /* Ignore permissive mode. */
64int avc_has_perm_noaudit(u32 ssid, u32 tsid, 64int avc_has_perm_noaudit(u32 ssid, u32 tsid,
@@ -66,9 +66,17 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid,
66 unsigned flags, 66 unsigned flags,
67 struct av_decision *avd); 67 struct av_decision *avd);
68 68
69int avc_has_perm(u32 ssid, u32 tsid, 69int avc_has_perm_flags(u32 ssid, u32 tsid,
70 u16 tclass, u32 requested, 70 u16 tclass, u32 requested,
71 struct common_audit_data *auditdata); 71 struct common_audit_data *auditdata,
72 unsigned);
73
74static inline int avc_has_perm(u32 ssid, u32 tsid,
75 u16 tclass, u32 requested,
76 struct common_audit_data *auditdata)
77{
78 return avc_has_perm_flags(ssid, tsid, tclass, requested, auditdata, 0);
79}
72 80
73u32 avc_policy_seqno(void); 81u32 avc_policy_seqno(void);
74 82
diff --git a/security/selinux/netif.c b/security/selinux/netif.c
index d6095d63d83..58cc481c93d 100644
--- a/security/selinux/netif.c
+++ b/security/selinux/netif.c
@@ -104,22 +104,6 @@ static int sel_netif_insert(struct sel_netif *netif)
104} 104}
105 105
106/** 106/**
107 * sel_netif_free - Frees an interface entry
108 * @p: the entry's RCU field
109 *
110 * Description:
111 * This function is designed to be used as a callback to the call_rcu()
112 * function so that memory allocated to a hash table interface entry can be
113 * released safely.
114 *
115 */
116static void sel_netif_free(struct rcu_head *p)
117{
118 struct sel_netif *netif = container_of(p, struct sel_netif, rcu_head);
119 kfree(netif);
120}
121
122/**
123 * sel_netif_destroy - Remove an interface record from the table 107 * sel_netif_destroy - Remove an interface record from the table
124 * @netif: the existing interface record 108 * @netif: the existing interface record
125 * 109 *
@@ -131,7 +115,7 @@ static void sel_netif_destroy(struct sel_netif *netif)
131{ 115{
132 list_del_rcu(&netif->list); 116 list_del_rcu(&netif->list);
133 sel_netif_total--; 117 sel_netif_total--;
134 call_rcu(&netif->rcu_head, sel_netif_free); 118 kfree_rcu(netif, rcu_head);
135} 119}
136 120
137/** 121/**
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index e7b850ad57e..7102457661d 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -502,7 +502,7 @@ static int policydb_index(struct policydb *p)
502 goto out; 502 goto out;
503 503
504 rc = flex_array_prealloc(p->type_val_to_struct_array, 0, 504 rc = flex_array_prealloc(p->type_val_to_struct_array, 0,
505 p->p_types.nprim - 1, GFP_KERNEL | __GFP_ZERO); 505 p->p_types.nprim, GFP_KERNEL | __GFP_ZERO);
506 if (rc) 506 if (rc)
507 goto out; 507 goto out;
508 508
@@ -519,7 +519,7 @@ static int policydb_index(struct policydb *p)
519 goto out; 519 goto out;
520 520
521 rc = flex_array_prealloc(p->sym_val_to_name[i], 521 rc = flex_array_prealloc(p->sym_val_to_name[i],
522 0, p->symtab[i].nprim - 1, 522 0, p->symtab[i].nprim,
523 GFP_KERNEL | __GFP_ZERO); 523 GFP_KERNEL | __GFP_ZERO);
524 if (rc) 524 if (rc)
525 goto out; 525 goto out;
@@ -1819,8 +1819,6 @@ static int filename_trans_read(struct policydb *p, void *fp)
1819 goto out; 1819 goto out;
1820 nel = le32_to_cpu(buf[0]); 1820 nel = le32_to_cpu(buf[0]);
1821 1821
1822 printk(KERN_ERR "%s: nel=%d\n", __func__, nel);
1823
1824 last = p->filename_trans; 1822 last = p->filename_trans;
1825 while (last && last->next) 1823 while (last && last->next)
1826 last = last->next; 1824 last = last->next;
@@ -1857,8 +1855,6 @@ static int filename_trans_read(struct policydb *p, void *fp)
1857 goto out; 1855 goto out;
1858 name[len] = 0; 1856 name[len] = 0;
1859 1857
1860 printk(KERN_ERR "%s: ft=%p ft->name=%p ft->name=%s\n", __func__, ft, ft->name, ft->name);
1861
1862 rc = next_entry(buf, fp, sizeof(u32) * 4); 1858 rc = next_entry(buf, fp, sizeof(u32) * 4);
1863 if (rc) 1859 if (rc)
1864 goto out; 1860 goto out;
@@ -2375,7 +2371,7 @@ int policydb_read(struct policydb *p, void *fp)
2375 goto bad; 2371 goto bad;
2376 2372
2377 /* preallocate so we don't have to worry about the put ever failing */ 2373 /* preallocate so we don't have to worry about the put ever failing */
2378 rc = flex_array_prealloc(p->type_attr_map_array, 0, p->p_types.nprim - 1, 2374 rc = flex_array_prealloc(p->type_attr_map_array, 0, p->p_types.nprim,
2379 GFP_KERNEL | __GFP_ZERO); 2375 GFP_KERNEL | __GFP_ZERO);
2380 if (rc) 2376 if (rc)
2381 goto bad; 2377 goto bad;
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index c6f8fcadae0..400a5d5cde6 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -686,7 +686,7 @@ static int smack_inode_rename(struct inode *old_inode,
686 * 686 *
687 * Returns 0 if access is permitted, -EACCES otherwise 687 * Returns 0 if access is permitted, -EACCES otherwise
688 */ 688 */
689static int smack_inode_permission(struct inode *inode, int mask) 689static int smack_inode_permission(struct inode *inode, int mask, unsigned flags)
690{ 690{
691 struct smk_audit_info ad; 691 struct smk_audit_info ad;
692 692
@@ -696,6 +696,10 @@ static int smack_inode_permission(struct inode *inode, int mask)
696 */ 696 */
697 if (mask == 0) 697 if (mask == 0)
698 return 0; 698 return 0;
699
700 /* May be droppable after audit */
701 if (flags & IPERM_FLAG_RCU)
702 return -ECHILD;
699 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 703 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
700 smk_ad_setfield_u_fs_inode(&ad, inode); 704 smk_ad_setfield_u_fs_inode(&ad, inode);
701 return smk_curacc(smk_of_inode(inode), mask, &ad); 705 return smk_curacc(smk_of_inode(inode), mask, &ad);