summaryrefslogtreecommitdiff
path: root/security/selinux
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux')
-rw-r--r--security/selinux/avc.c27
-rw-r--r--security/selinux/hooks.c25
-rw-r--r--security/selinux/include/avc.h1
-rw-r--r--security/selinux/netif.c18
-rw-r--r--security/selinux/selinuxfs.c18
-rw-r--r--security/selinux/ss/services.c3
6 files changed, 36 insertions, 56 deletions
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index ce742f1778e1..d515b2128a4e 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 a0d38459d650..20219ef5439a 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 e77b2ac2908b..47fda963495d 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 d6095d63d831..58cc481c93d5 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 19489042fdf7..35459340019e 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 c3e4b52699f4..973e00e34fa9 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();