diff options
author | Jarkko Sakkinen <jarkko.j.sakkinen@gmail.com> | 2011-10-18 14:21:36 -0400 |
---|---|---|
committer | Casey Schaufler <cschaufler@cschaufler-intel.(none)> | 2011-10-20 19:07:31 -0400 |
commit | 0e94ae17c857b3835a2b8ea46ce44b5da4e2cc5d (patch) | |
tree | eac36ba696cf33bbbe3fcd490589ef453d9c8ef1 /security | |
parent | d86b2b61d4dea614d6f319772a90a8f98b55ed67 (diff) |
Smack: allow to access /smack/access as normal user
Allow query access as a normal user removing the need
for CAP_MAC_ADMIN. Give RW access to /smack/access
for UGO. Do not import smack labels in access check.
Signed-off-by: Jarkko Sakkinen <jarkko.j.sakkinen@gmail.com>
Signed-off-by: Casey Schaufler <cschaufler@cschaufler-intel.(none)>
Diffstat (limited to 'security')
-rw-r--r-- | security/smack/smack.h | 1 | ||||
-rw-r--r-- | security/smack/smack_access.c | 27 | ||||
-rw-r--r-- | security/smack/smackfs.c | 45 |
3 files changed, 50 insertions, 23 deletions
diff --git a/security/smack/smack.h b/security/smack/smack.h index 9da2b2dfdefb..2ad00657b801 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h | |||
@@ -208,6 +208,7 @@ int smk_curacc(char *, u32, struct smk_audit_info *); | |||
208 | int smack_to_cipso(const char *, struct smack_cipso *); | 208 | int smack_to_cipso(const char *, struct smack_cipso *); |
209 | char *smack_from_cipso(u32, char *); | 209 | char *smack_from_cipso(u32, char *); |
210 | char *smack_from_secid(const u32); | 210 | char *smack_from_secid(const u32); |
211 | void smk_parse_smack(const char *string, int len, char *smack); | ||
211 | char *smk_import(const char *, int); | 212 | char *smk_import(const char *, int); |
212 | struct smack_known *smk_import_entry(const char *, int); | 213 | struct smack_known *smk_import_entry(const char *, int); |
213 | struct smack_known *smk_find_entry(const char *); | 214 | struct smack_known *smk_find_entry(const char *); |
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c index a885f628f56e..cc7cb6edba08 100644 --- a/security/smack/smack_access.c +++ b/security/smack/smack_access.c | |||
@@ -353,17 +353,13 @@ struct smack_known *smk_find_entry(const char *string) | |||
353 | } | 353 | } |
354 | 354 | ||
355 | /** | 355 | /** |
356 | * smk_import_entry - import a label, return the list entry | 356 | * smk_parse_smack - parse smack label from a text string |
357 | * @string: a text string that might be a Smack label | 357 | * @string: a text string that might contain a Smack label |
358 | * @len: the maximum size, or zero if it is NULL terminated. | 358 | * @len: the maximum size, or zero if it is NULL terminated. |
359 | * | 359 | * @smack: parsed smack label, or NULL if parse error |
360 | * Returns a pointer to the entry in the label list that | ||
361 | * matches the passed string, adding it if necessary. | ||
362 | */ | 360 | */ |
363 | struct smack_known *smk_import_entry(const char *string, int len) | 361 | void smk_parse_smack(const char *string, int len, char *smack) |
364 | { | 362 | { |
365 | struct smack_known *skp; | ||
366 | char smack[SMK_LABELLEN]; | ||
367 | int found; | 363 | int found; |
368 | int i; | 364 | int i; |
369 | 365 | ||
@@ -381,7 +377,22 @@ struct smack_known *smk_import_entry(const char *string, int len) | |||
381 | } else | 377 | } else |
382 | smack[i] = string[i]; | 378 | smack[i] = string[i]; |
383 | } | 379 | } |
380 | } | ||
381 | |||
382 | /** | ||
383 | * smk_import_entry - import a label, return the list entry | ||
384 | * @string: a text string that might be a Smack label | ||
385 | * @len: the maximum size, or zero if it is NULL terminated. | ||
386 | * | ||
387 | * Returns a pointer to the entry in the label list that | ||
388 | * matches the passed string, adding it if necessary. | ||
389 | */ | ||
390 | struct smack_known *smk_import_entry(const char *string, int len) | ||
391 | { | ||
392 | struct smack_known *skp; | ||
393 | char smack[SMK_LABELLEN]; | ||
384 | 394 | ||
395 | smk_parse_smack(string, len, smack); | ||
385 | if (smack[0] == '\0') | 396 | if (smack[0] == '\0') |
386 | return NULL; | 397 | return NULL; |
387 | 398 | ||
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index 381eecffe516..6aceef518a41 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 | */ |
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 | 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, |
@@ -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 | }; |