| @@ -191,19 +191,37 @@ static int smk_set_access(struct smack_rule *srp, struct list_head *rule_list, · 190 unmodified lines |
| 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 | 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 | */ |
| 198 | | −static int smk_parse_rule(const char *data, struct smack_rule *rule) |
| 199 | +static int smk_parse_rule(const char *data, struct smack_rule *rule, int import) |
| 199 | 200 | { |
| 200 | | − rule->smk_subject = smk_import(data, 0); |
| 201 | | − if (rule->smk_subject == NULL) |
| 202 | | − return -1; |
| 201 | + char smack[SMK_LABELLEN]; |
| 202 | + struct smack_known *skp; |
| 203 | 203 | |
| 204 | | − rule->smk_object = smk_import(data + SMK_LABELLEN, 0); |
| 205 | | − if (rule->smk_object == NULL) |
| 206 | | − return -1; |
| 204 | + if (import) { |
| 205 | + rule->smk_subject = smk_import(data, 0); |
| 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 | 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, · 117 unmodified lines |
| 327 | 345 | goto out; |
| 328 | 346 | } |
| 329 | 347 | |
| 330 | | − if (smk_parse_rule(data, rule)) |
| 348 | + if (smk_parse_rule(data, rule, 1)) |
| 331 | 349 | goto out_free_rule; |
| 332 | 350 | |
| 333 | 351 | if (rule_list == NULL) { |
| @@ -1499,14 +1517,11 @@ static ssize_t smk_write_access(struct file *file, const char __user *buf, · 1165 unmodified lines |
| 1499 | 1517 | char *data; |
| 1500 | 1518 | int res; |
| 1501 | 1519 | |
| 1502 | | − if (!capable(CAP_MAC_ADMIN)) |
| 1503 | | − return -EPERM; |
| 1504 | | − |
| 1505 | 1520 | data = simple_transaction_get(file, buf, count); |
| 1506 | 1521 | if (IS_ERR(data)) |
| 1507 | 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 | 1525 | return -EINVAL; |
| 1511 | 1526 | |
| 1512 | 1527 | res = smk_access(rule.smk_subject, rule.smk_object, rule.smk_access, |
| @@ -1560,7 +1575,7 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent) · 47 unmodified lines |
| 1560 | 1575 | [SMK_LOAD_SELF] = { |
| 1561 | 1576 | "load-self", &smk_load_self_ops, S_IRUGO|S_IWUGO}, |
| 1562 | 1577 | [SMK_ACCESSES] = { |
| 1563 | | − "access", &smk_access_ops, S_IRUGO|S_IWUSR}, |
| 1578 | + "access", &smk_access_ops, S_IRUGO|S_IWUGO}, |
| 1564 | 1579 | /* last one */ |
| 1565 | 1580 | {""} |
| 1566 | 1581 | }; |