summaryrefslogtreecommitdiff
path: root/security/smack/smackfs.c
diff options
context:
space:
mode:
authorCasey Schaufler <casey@schaufler-ca.com>2013-05-23 05:43:03 +0400
committerCasey Schaufler <casey@schaufler-ca.com>2013-05-28 21:08:32 +0400
commit2f823ff8bec03a1e6f9e11fd0c4d54e4c7d09532 (patch)
tree8ba448a6cc7b5cdc4d173390721eda3f83a3e012 /security/smack/smackfs.c
parentc673944347edfd4362b10eea11ac384a582b1cf5 (diff)
downloadlinux-2f823ff8bec03a1e6f9e11fd0c4d54e4c7d09532.tar.xz
Smack: Improve access check performance
Each Smack label that the kernel has seen is added to a list of labels. The list of access rules for a given subject label hangs off of the label list entry for the label. This patch changes the structures that contain subject labels to point at the label list entry rather that the label itself. Doing so removes a label list lookup in smk_access() that was accounting for the largest single chunk of Smack overhead. Targeted for git://git.gitorious.org/smack-next/kernel.git Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
Diffstat (limited to 'security/smack/smackfs.c')
-rw-r--r--security/smack/smackfs.c51
1 files changed, 26 insertions, 25 deletions
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 53a08b85bda4..3c79cba5fa4a 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -66,7 +66,7 @@ static DEFINE_MUTEX(smk_netlbladdr_lock);
* If it isn't somehow marked, use this.
* It can be reset via smackfs/ambient
*/
-char *smack_net_ambient;
+struct smack_known *smack_net_ambient;
/*
* This is the level in a CIPSO header that indicates a
@@ -112,7 +112,7 @@ struct smack_master_list {
LIST_HEAD(smack_rule_list);
struct smack_parsed_rule {
- char *smk_subject;
+ struct smack_known *smk_subject;
char *smk_object;
int smk_access1;
int smk_access2;
@@ -163,9 +163,11 @@ static inline void smack_catset_bit(unsigned int cat, char *catsetp)
*/
static void smk_netlabel_audit_set(struct netlbl_audit *nap)
{
+ struct smack_known *skp = smk_of_current();
+
nap->loginuid = audit_get_loginuid(current);
nap->sessionid = audit_get_sessionid(current);
- nap->secid = smack_to_secid(smk_of_current());
+ nap->secid = skp->smk_secid;
}
/*
@@ -306,7 +308,7 @@ static int smk_fill_rule(const char *subject, const char *object,
struct smack_known *skp;
if (import) {
- rule->smk_subject = smk_import(subject, len);
+ rule->smk_subject = smk_import_entry(subject, len);
if (rule->smk_subject == NULL)
return -1;
@@ -321,7 +323,7 @@ static int smk_fill_rule(const char *subject, const char *object,
kfree(cp);
if (skp == NULL)
return -1;
- rule->smk_subject = skp->smk_known;
+ rule->smk_subject = skp;
cp = smk_parse_smack(object, len);
if (cp == NULL)
@@ -445,7 +447,6 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
struct list_head *rule_list,
struct mutex *rule_lock, int format)
{
- struct smack_known *skp;
struct smack_parsed_rule *rule;
char *data;
int datalen;
@@ -505,12 +506,10 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
goto out_free_rule;
}
-
if (rule_list == NULL) {
load = 1;
- skp = smk_find_entry(rule->smk_subject);
- rule_list = &skp->smk_rules;
- rule_lock = &skp->smk_rules_lock;
+ rule_list = &rule->smk_subject->smk_rules;
+ rule_lock = &rule->smk_subject->smk_rules_lock;
}
rc = smk_set_access(rule, rule_list, rule_lock, load);
@@ -579,13 +578,14 @@ static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max)
* because you should expect to be able to write
* anything you read back.
*/
- if (strlen(srp->smk_subject) >= max || strlen(srp->smk_object) >= max)
+ if (strlen(srp->smk_subject->smk_known) >= max ||
+ strlen(srp->smk_object) >= max)
return;
if (srp->smk_access == 0)
return;
- seq_printf(s, "%s %s", srp->smk_subject, srp->smk_object);
+ seq_printf(s, "%s %s", srp->smk_subject->smk_known, srp->smk_object);
seq_putc(s, ' ');
@@ -738,9 +738,9 @@ static void smk_unlbl_ambient(char *oldambient)
__func__, __LINE__, rc);
}
if (smack_net_ambient == NULL)
- smack_net_ambient = smack_known_floor.smk_known;
+ smack_net_ambient = &smack_known_floor;
- rc = netlbl_cfg_unlbl_map_add(smack_net_ambient, PF_INET,
+ rc = netlbl_cfg_unlbl_map_add(smack_net_ambient->smk_known, PF_INET,
NULL, NULL, &nai);
if (rc != 0)
printk(KERN_WARNING "%s:%d add rc = %d\n",
@@ -1535,11 +1535,12 @@ static ssize_t smk_read_ambient(struct file *filp, char __user *buf,
*/
mutex_lock(&smack_ambient_lock);
- asize = strlen(smack_net_ambient) + 1;
+ asize = strlen(smack_net_ambient->smk_known) + 1;
if (cn >= asize)
rc = simple_read_from_buffer(buf, cn, ppos,
- smack_net_ambient, asize);
+ smack_net_ambient->smk_known,
+ asize);
else
rc = -EINVAL;
@@ -1560,8 +1561,8 @@ static ssize_t smk_read_ambient(struct file *filp, char __user *buf,
static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
+ struct smack_known *skp;
char *oldambient;
- char *smack = NULL;
char *data;
int rc = count;
@@ -1577,16 +1578,16 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
goto out;
}
- smack = smk_import(data, count);
- if (smack == NULL) {
+ skp = smk_import_entry(data, count);
+ if (skp == NULL) {
rc = -EINVAL;
goto out;
}
mutex_lock(&smack_ambient_lock);
- oldambient = smack_net_ambient;
- smack_net_ambient = smack;
+ oldambient = smack_net_ambient->smk_known;
+ smack_net_ambient = skp;
smk_unlbl_ambient(oldambient);
mutex_unlock(&smack_ambient_lock);
@@ -1645,7 +1646,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
char *data;
- char *sp = smk_of_task(current->cred->security);
+ struct smack_known *skp = smk_of_task(current->cred->security);
int rc = count;
if (!smack_privileged(CAP_MAC_ADMIN))
@@ -1656,7 +1657,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
* explicitly for clarity. The smk_access() implementation
* would use smk_access(smack_onlycap, MAY_WRITE)
*/
- if (smack_onlycap != NULL && smack_onlycap != sp)
+ if (smack_onlycap != NULL && smack_onlycap != skp->smk_known)
return -EPERM;
data = kzalloc(count, GFP_KERNEL);
@@ -1866,8 +1867,8 @@ static ssize_t smk_user_access(struct file *file, const char __user *buf,
if (res)
return -EINVAL;
- res = smk_access(rule.smk_subject, rule.smk_object, rule.smk_access1,
- NULL);
+ res = smk_access(rule.smk_subject, rule.smk_object,
+ rule.smk_access1, NULL);
data[0] = res == 0 ? '1' : '0';
data[1] = '\0';