aboutsummaryrefslogtreecommitdiffstats
path: root/security/smack/smackfs.c
diff options
context:
space:
mode:
authorCasey Schaufler <casey@schaufler-ca.com>2013-05-22 21:43:03 -0400
committerCasey Schaufler <casey@schaufler-ca.com>2013-05-28 13:08:32 -0400
commit2f823ff8bec03a1e6f9e11fd0c4d54e4c7d09532 (patch)
tree8ba448a6cc7b5cdc4d173390721eda3f83a3e012 /security/smack/smackfs.c
parentc673944347edfd4362b10eea11ac384a582b1cf5 (diff)
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);
66 * If it isn't somehow marked, use this. 66 * If it isn't somehow marked, use this.
67 * It can be reset via smackfs/ambient 67 * It can be reset via smackfs/ambient
68 */ 68 */
69char *smack_net_ambient; 69struct smack_known *smack_net_ambient;
70 70
71/* 71/*
72 * This is the level in a CIPSO header that indicates a 72 * This is the level in a CIPSO header that indicates a
@@ -112,7 +112,7 @@ struct smack_master_list {
112LIST_HEAD(smack_rule_list); 112LIST_HEAD(smack_rule_list);
113 113
114struct smack_parsed_rule { 114struct smack_parsed_rule {
115 char *smk_subject; 115 struct smack_known *smk_subject;
116 char *smk_object; 116 char *smk_object;
117 int smk_access1; 117 int smk_access1;
118 int smk_access2; 118 int smk_access2;
@@ -163,9 +163,11 @@ static inline void smack_catset_bit(unsigned int cat, char *catsetp)
163 */ 163 */
164static void smk_netlabel_audit_set(struct netlbl_audit *nap) 164static void smk_netlabel_audit_set(struct netlbl_audit *nap)
165{ 165{
166 struct smack_known *skp = smk_of_current();
167
166 nap->loginuid = audit_get_loginuid(current); 168 nap->loginuid = audit_get_loginuid(current);
167 nap->sessionid = audit_get_sessionid(current); 169 nap->sessionid = audit_get_sessionid(current);
168 nap->secid = smack_to_secid(smk_of_current()); 170 nap->secid = skp->smk_secid;
169} 171}
170 172
171/* 173/*
@@ -306,7 +308,7 @@ static int smk_fill_rule(const char *subject, const char *object,
306 struct smack_known *skp; 308 struct smack_known *skp;
307 309
308 if (import) { 310 if (import) {
309 rule->smk_subject = smk_import(subject, len); 311 rule->smk_subject = smk_import_entry(subject, len);
310 if (rule->smk_subject == NULL) 312 if (rule->smk_subject == NULL)
311 return -1; 313 return -1;
312 314
@@ -321,7 +323,7 @@ static int smk_fill_rule(const char *subject, const char *object,
321 kfree(cp); 323 kfree(cp);
322 if (skp == NULL) 324 if (skp == NULL)
323 return -1; 325 return -1;
324 rule->smk_subject = skp->smk_known; 326 rule->smk_subject = skp;
325 327
326 cp = smk_parse_smack(object, len); 328 cp = smk_parse_smack(object, len);
327 if (cp == NULL) 329 if (cp == NULL)
@@ -445,7 +447,6 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
445 struct list_head *rule_list, 447 struct list_head *rule_list,
446 struct mutex *rule_lock, int format) 448 struct mutex *rule_lock, int format)
447{ 449{
448 struct smack_known *skp;
449 struct smack_parsed_rule *rule; 450 struct smack_parsed_rule *rule;
450 char *data; 451 char *data;
451 int datalen; 452 int datalen;
@@ -505,12 +506,10 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
505 goto out_free_rule; 506 goto out_free_rule;
506 } 507 }
507 508
508
509 if (rule_list == NULL) { 509 if (rule_list == NULL) {
510 load = 1; 510 load = 1;
511 skp = smk_find_entry(rule->smk_subject); 511 rule_list = &rule->smk_subject->smk_rules;
512 rule_list = &skp->smk_rules; 512 rule_lock = &rule->smk_subject->smk_rules_lock;
513 rule_lock = &skp->smk_rules_lock;
514 } 513 }
515 514
516 rc = smk_set_access(rule, rule_list, rule_lock, load); 515 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)
579 * because you should expect to be able to write 578 * because you should expect to be able to write
580 * anything you read back. 579 * anything you read back.
581 */ 580 */
582 if (strlen(srp->smk_subject) >= max || strlen(srp->smk_object) >= max) 581 if (strlen(srp->smk_subject->smk_known) >= max ||
582 strlen(srp->smk_object) >= max)
583 return; 583 return;
584 584
585 if (srp->smk_access == 0) 585 if (srp->smk_access == 0)
586 return; 586 return;
587 587
588 seq_printf(s, "%s %s", srp->smk_subject, srp->smk_object); 588 seq_printf(s, "%s %s", srp->smk_subject->smk_known, srp->smk_object);
589 589
590 seq_putc(s, ' '); 590 seq_putc(s, ' ');
591 591
@@ -738,9 +738,9 @@ static void smk_unlbl_ambient(char *oldambient)
738 __func__, __LINE__, rc); 738 __func__, __LINE__, rc);
739 } 739 }
740 if (smack_net_ambient == NULL) 740 if (smack_net_ambient == NULL)
741 smack_net_ambient = smack_known_floor.smk_known; 741 smack_net_ambient = &smack_known_floor;
742 742
743 rc = netlbl_cfg_unlbl_map_add(smack_net_ambient, PF_INET, 743 rc = netlbl_cfg_unlbl_map_add(smack_net_ambient->smk_known, PF_INET,
744 NULL, NULL, &nai); 744 NULL, NULL, &nai);
745 if (rc != 0) 745 if (rc != 0)
746 printk(KERN_WARNING "%s:%d add rc = %d\n", 746 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,
1535 */ 1535 */
1536 mutex_lock(&smack_ambient_lock); 1536 mutex_lock(&smack_ambient_lock);
1537 1537
1538 asize = strlen(smack_net_ambient) + 1; 1538 asize = strlen(smack_net_ambient->smk_known) + 1;
1539 1539
1540 if (cn >= asize) 1540 if (cn >= asize)
1541 rc = simple_read_from_buffer(buf, cn, ppos, 1541 rc = simple_read_from_buffer(buf, cn, ppos,
1542 smack_net_ambient, asize); 1542 smack_net_ambient->smk_known,
1543 asize);
1543 else 1544 else
1544 rc = -EINVAL; 1545 rc = -EINVAL;
1545 1546
@@ -1560,8 +1561,8 @@ static ssize_t smk_read_ambient(struct file *filp, char __user *buf,
1560static ssize_t smk_write_ambient(struct file *file, const char __user *buf, 1561static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
1561 size_t count, loff_t *ppos) 1562 size_t count, loff_t *ppos)
1562{ 1563{
1564 struct smack_known *skp;
1563 char *oldambient; 1565 char *oldambient;
1564 char *smack = NULL;
1565 char *data; 1566 char *data;
1566 int rc = count; 1567 int rc = count;
1567 1568
@@ -1577,16 +1578,16 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
1577 goto out; 1578 goto out;
1578 } 1579 }
1579 1580
1580 smack = smk_import(data, count); 1581 skp = smk_import_entry(data, count);
1581 if (smack == NULL) { 1582 if (skp == NULL) {
1582 rc = -EINVAL; 1583 rc = -EINVAL;
1583 goto out; 1584 goto out;
1584 } 1585 }
1585 1586
1586 mutex_lock(&smack_ambient_lock); 1587 mutex_lock(&smack_ambient_lock);
1587 1588
1588 oldambient = smack_net_ambient; 1589 oldambient = smack_net_ambient->smk_known;
1589 smack_net_ambient = smack; 1590 smack_net_ambient = skp;
1590 smk_unlbl_ambient(oldambient); 1591 smk_unlbl_ambient(oldambient);
1591 1592
1592 mutex_unlock(&smack_ambient_lock); 1593 mutex_unlock(&smack_ambient_lock);
@@ -1645,7 +1646,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
1645 size_t count, loff_t *ppos) 1646 size_t count, loff_t *ppos)
1646{ 1647{
1647 char *data; 1648 char *data;
1648 char *sp = smk_of_task(current->cred->security); 1649 struct smack_known *skp = smk_of_task(current->cred->security);
1649 int rc = count; 1650 int rc = count;
1650 1651
1651 if (!smack_privileged(CAP_MAC_ADMIN)) 1652 if (!smack_privileged(CAP_MAC_ADMIN))
@@ -1656,7 +1657,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
1656 * explicitly for clarity. The smk_access() implementation 1657 * explicitly for clarity. The smk_access() implementation
1657 * would use smk_access(smack_onlycap, MAY_WRITE) 1658 * would use smk_access(smack_onlycap, MAY_WRITE)
1658 */ 1659 */
1659 if (smack_onlycap != NULL && smack_onlycap != sp) 1660 if (smack_onlycap != NULL && smack_onlycap != skp->smk_known)
1660 return -EPERM; 1661 return -EPERM;
1661 1662
1662 data = kzalloc(count, GFP_KERNEL); 1663 data = kzalloc(count, GFP_KERNEL);
@@ -1866,8 +1867,8 @@ static ssize_t smk_user_access(struct file *file, const char __user *buf,
1866 if (res) 1867 if (res)
1867 return -EINVAL; 1868 return -EINVAL;
1868 1869
1869 res = smk_access(rule.smk_subject, rule.smk_object, rule.smk_access1, 1870 res = smk_access(rule.smk_subject, rule.smk_object,
1870 NULL); 1871 rule.smk_access1, NULL);
1871 data[0] = res == 0 ? '1' : '0'; 1872 data[0] = res == 0 ? '1' : '0';
1872 data[1] = '\0'; 1873 data[1] = '\0';
1873 1874