aboutsummaryrefslogtreecommitdiffstats
path: root/security/smack/smackfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/smack/smackfs.c')
-rw-r--r--security/smack/smackfs.c47
1 files changed, 31 insertions, 16 deletions
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 5498c4a2d1a..6aceef518a4 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -191,19 +191,37 @@ static int smk_set_access(struct smack_rule *srp, struct list_head *rule_list,
191} 191}
192 192
193/** 193/**
194 * smk_parse_rule - parse subject, object and access type 194 * smk_parse_rule - parse Smack rule from load string
195 * @data: string to be parsed whose size is SMK_LOADLEN 195 * @data: string to be parsed whose size is SMK_LOADLEN
196 * @rule: parsed entities are stored in here 196 * @rule: Smack rule
197 * @import: if non-zero, import labels
197 */ 198 */
198static int smk_parse_rule(const char *data, struct smack_rule *rule) 199static int smk_parse_rule(const char *data, struct smack_rule *rule, int import)
199{ 200{
200 rule->smk_subject = smk_import(data, 0); 201 char smack[SMK_LABELLEN];
201 if (rule->smk_subject == NULL) 202 struct smack_known *skp;
202 return -1;
203 203
204 rule->smk_object = smk_import(data + SMK_LABELLEN, 0); 204 if (import) {
205 if (rule->smk_object == NULL) 205 rule->smk_subject = smk_import(data, 0);
206 return -1; 206 if (rule->smk_subject == NULL)
207 return -1;
208
209 rule->smk_object = smk_import(data + SMK_LABELLEN, 0);
210 if (rule->smk_object == NULL)
211 return -1;
212 } else {
213 smk_parse_smack(data, 0, smack);
214 skp = smk_find_entry(smack);
215 if (skp == NULL)
216 return -1;
217 rule->smk_subject = skp->smk_known;
218
219 smk_parse_smack(data + SMK_LABELLEN, 0, smack);
220 skp = smk_find_entry(smack);
221 if (skp == NULL)
222 return -1;
223 rule->smk_object = skp->smk_known;
224 }
207 225
208 rule->smk_access = 0; 226 rule->smk_access = 0;
209 227
@@ -327,7 +345,7 @@ static ssize_t smk_write_load_list(struct file *file, const char __user *buf,
327 goto out; 345 goto out;
328 } 346 }
329 347
330 if (smk_parse_rule(data, rule)) 348 if (smk_parse_rule(data, rule, 1))
331 goto out_free_rule; 349 goto out_free_rule;
332 350
333 if (rule_list == NULL) { 351 if (rule_list == NULL) {
@@ -1499,14 +1517,11 @@ static ssize_t smk_write_access(struct file *file, const char __user *buf,
1499 char *data; 1517 char *data;
1500 int res; 1518 int res;
1501 1519
1502 if (!capable(CAP_MAC_ADMIN))
1503 return -EPERM;
1504
1505 data = simple_transaction_get(file, buf, count); 1520 data = simple_transaction_get(file, buf, count);
1506 if (IS_ERR(data)) 1521 if (IS_ERR(data))
1507 return PTR_ERR(data); 1522 return PTR_ERR(data);
1508 1523
1509 if (count < SMK_LOADLEN || smk_parse_rule(data, &rule)) 1524 if (count < SMK_LOADLEN || smk_parse_rule(data, &rule, 0))
1510 return -EINVAL; 1525 return -EINVAL;
1511 1526
1512 res = smk_access(rule.smk_subject, rule.smk_object, rule.smk_access, 1527 res = smk_access(rule.smk_subject, rule.smk_object, rule.smk_access,
@@ -1514,7 +1529,7 @@ static ssize_t smk_write_access(struct file *file, const char __user *buf,
1514 data[0] = res == 0 ? '1' : '0'; 1529 data[0] = res == 0 ? '1' : '0';
1515 data[1] = '\0'; 1530 data[1] = '\0';
1516 1531
1517 simple_transaction_set(file, 1); 1532 simple_transaction_set(file, 2);
1518 return SMK_LOADLEN; 1533 return SMK_LOADLEN;
1519} 1534}
1520 1535
@@ -1560,7 +1575,7 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
1560 [SMK_LOAD_SELF] = { 1575 [SMK_LOAD_SELF] = {
1561 "load-self", &smk_load_self_ops, S_IRUGO|S_IWUGO}, 1576 "load-self", &smk_load_self_ops, S_IRUGO|S_IWUGO},
1562 [SMK_ACCESSES] = { 1577 [SMK_ACCESSES] = {
1563 "access", &smk_access_ops, S_IRUGO|S_IWUSR}, 1578 "access", &smk_access_ops, S_IRUGO|S_IWUGO},
1564 /* last one */ 1579 /* last one */
1565 {""} 1580 {""}
1566 }; 1581 };