diff options
Diffstat (limited to 'security/selinux')
-rw-r--r-- | security/selinux/avc.c | 27 | ||||
-rw-r--r-- | security/selinux/hooks.c | 25 | ||||
-rw-r--r-- | security/selinux/include/avc.h | 1 | ||||
-rw-r--r-- | security/selinux/netif.c | 18 | ||||
-rw-r--r-- | security/selinux/selinuxfs.c | 18 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 3 |
6 files changed, 36 insertions, 56 deletions
diff --git a/security/selinux/avc.c b/security/selinux/avc.c index ce742f1..d515b21 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -38,11 +38,7 @@ #define AVC_CACHE_RECLAIM 16 #ifdef CONFIG_SECURITY_SELINUX_AVC_STATS -#define avc_cache_stats_incr(field) \ -do { \ - per_cpu(avc_cache_stats, get_cpu()).field++; \ - put_cpu(); \ -} while (0) +#define avc_cache_stats_incr(field) this_cpu_inc(avc_cache_stats.field) #else #define avc_cache_stats_incr(field) do {} while (0) #endif @@ -347,11 +343,10 @@ static struct avc_node *avc_lookup(u32 ssid, u32 tsid, u16 tclass) node = avc_search_node(ssid, tsid, tclass); if (node) - avc_cache_stats_incr(hits); - else - avc_cache_stats_incr(misses); + return node; - return node; + avc_cache_stats_incr(misses); + return NULL; } static int avc_latest_notif_update(int seqno, int is_insert) @@ -757,10 +752,9 @@ int avc_ss_reset(u32 seqno) int avc_has_perm_noaudit(u32 ssid, u32 tsid, u16 tclass, u32 requested, unsigned flags, - struct av_decision *in_avd) + struct av_decision *avd) { struct avc_node *node; - struct av_decision avd_entry, *avd; int rc = 0; u32 denied; @@ -769,20 +763,13 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid, rcu_read_lock(); node = avc_lookup(ssid, tsid, tclass); - if (!node) { + if (unlikely(!node)) { rcu_read_unlock(); - - if (in_avd) - avd = in_avd; - else - avd = &avd_entry; - security_compute_av(ssid, tsid, tclass, avd); rcu_read_lock(); node = avc_insert(ssid, tsid, tclass, avd); } else { - if (in_avd) - memcpy(in_avd, &node->ae.avd, sizeof(*in_avd)); + memcpy(avd, &node->ae.avd, sizeof(*avd)); avd = &node->ae.avd; } diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index a0d3845..20219ef 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -1476,7 +1476,6 @@ static int inode_has_perm(const struct cred *cred, unsigned flags) { struct inode_security_struct *isec; - struct common_audit_data ad; u32 sid; validate_creds(cred); @@ -1487,15 +1486,21 @@ static int inode_has_perm(const struct cred *cred, sid = cred_sid(cred); isec = inode->i_security; - if (!adp) { - adp = &ad; - COMMON_AUDIT_DATA_INIT(&ad, INODE); - ad.u.inode = inode; - } - return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags); } +static int inode_has_perm_noadp(const struct cred *cred, + struct inode *inode, + u32 perms, + unsigned flags) +{ + struct common_audit_data ad; + + COMMON_AUDIT_DATA_INIT(&ad, INODE); + ad.u.inode = inode; + return inode_has_perm(cred, inode, perms, &ad, flags); +} + /* Same as inode_has_perm, but pass explicit audit data containing the dentry to help the auditing code to more easily generate the pathname if needed. */ @@ -2122,8 +2127,8 @@ static inline void flush_unauthorized_files(const struct cred *cred, struct tty_file_private, list); file = file_priv->file; inode = file->f_path.dentry->d_inode; - if (inode_has_perm(cred, inode, - FILE__READ | FILE__WRITE, NULL, 0)) { + if (inode_has_perm_noadp(cred, inode, + FILE__READ | FILE__WRITE, 0)) { drop_tty = 1; } } @@ -3228,7 +3233,7 @@ static int selinux_dentry_open(struct file *file, const struct cred *cred) * new inode label or new policy. * This check is not redundant - do not remove. */ - return inode_has_perm(cred, inode, open_file_to_av(file), NULL, 0); + return inode_has_perm_noadp(cred, inode, open_file_to_av(file), 0); } /* task security operations */ diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h index e77b2ac..47fda96 100644 --- a/security/selinux/include/avc.h +++ b/security/selinux/include/avc.h @@ -41,7 +41,6 @@ struct sk_buff; */ struct avc_cache_stats { unsigned int lookups; - unsigned int hits; unsigned int misses; unsigned int allocations; unsigned int reclaims; diff --git a/security/selinux/netif.c b/security/selinux/netif.c index d6095d6..58cc481 100644 --- a/security/selinux/netif.c +++ b/security/selinux/netif.c @@ -104,22 +104,6 @@ static int sel_netif_insert(struct sel_netif *netif) } /** - * sel_netif_free - Frees an interface entry - * @p: the entry's RCU field - * - * Description: - * This function is designed to be used as a callback to the call_rcu() - * function so that memory allocated to a hash table interface entry can be - * released safely. - * - */ -static void sel_netif_free(struct rcu_head *p) -{ - struct sel_netif *netif = container_of(p, struct sel_netif, rcu_head); - kfree(netif); -} - -/** * sel_netif_destroy - Remove an interface record from the table * @netif: the existing interface record * @@ -131,7 +115,7 @@ static void sel_netif_destroy(struct sel_netif *netif) { list_del_rcu(&netif->list); sel_netif_total--; - call_rcu(&netif->rcu_head, sel_netif_free); + kfree_rcu(netif, rcu_head); } /** diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 1948904..3545934 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -282,7 +282,7 @@ static ssize_t sel_write_disable(struct file *file, const char __user *buf, length = -ENOMEM; if (count >= PAGE_SIZE) - goto out;; + goto out; /* No partial writes. */ length = -EINVAL; @@ -924,12 +924,12 @@ static ssize_t sel_write_user(struct file *file, char *buf, size_t size) length = task_has_security(current, SECURITY__COMPUTE_USER); if (length) - goto out;; + goto out; length = -ENOMEM; con = kzalloc(size + 1, GFP_KERNEL); if (!con) - goto out;; + goto out; length = -ENOMEM; user = kzalloc(size + 1, GFP_KERNEL); @@ -989,7 +989,7 @@ static ssize_t sel_write_member(struct file *file, char *buf, size_t size) length = -ENOMEM; scon = kzalloc(size + 1, GFP_KERNEL); if (!scon) - goto out;; + goto out; length = -ENOMEM; tcon = kzalloc(size + 1, GFP_KERNEL); @@ -1428,10 +1428,14 @@ static int sel_avc_stats_seq_show(struct seq_file *seq, void *v) if (v == SEQ_START_TOKEN) seq_printf(seq, "lookups hits misses allocations reclaims " "frees\n"); - else - seq_printf(seq, "%u %u %u %u %u %u\n", st->lookups, - st->hits, st->misses, st->allocations, + else { + unsigned int lookups = st->lookups; + unsigned int misses = st->misses; + unsigned int hits = lookups - misses; + seq_printf(seq, "%u %u %u %u %u %u\n", lookups, + hits, misses, st->allocations, st->reclaims, st->frees); + } return 0; } diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index c3e4b52..973e00e 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -2217,10 +2217,11 @@ out_unlock: goto out; } for (i = 0, j = 0; i < mynel; i++) { + struct av_decision dummy_avd; rc = avc_has_perm_noaudit(fromsid, mysids[i], SECCLASS_PROCESS, /* kernel value */ PROCESS__TRANSITION, AVC_STRICT, - NULL); + &dummy_avd); if (!rc) mysids2[j++] = mysids[i]; cond_resched(); |