diff options
-rw-r--r-- | security/smack/smack_lsm.c | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 92baee53a7dc..fe0ae1bf1650 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/pipe_fs_i.h> | 26 | #include <linux/pipe_fs_i.h> |
27 | #include <net/netlabel.h> | 27 | #include <net/netlabel.h> |
28 | #include <net/cipso_ipv4.h> | 28 | #include <net/cipso_ipv4.h> |
29 | #include <linux/audit.h> | ||
29 | 30 | ||
30 | #include "smack.h" | 31 | #include "smack.h" |
31 | 32 | ||
@@ -752,6 +753,18 @@ static int smack_inode_listsecurity(struct inode *inode, char *buffer, | |||
752 | return -EINVAL; | 753 | return -EINVAL; |
753 | } | 754 | } |
754 | 755 | ||
756 | /** | ||
757 | * smack_inode_getsecid - Extract inode's security id | ||
758 | * @inode: inode to extract the info from | ||
759 | * @secid: where result will be saved | ||
760 | */ | ||
761 | static void smack_inode_getsecid(const struct inode *inode, u32 *secid) | ||
762 | { | ||
763 | struct inode_smack *isp = inode->i_security; | ||
764 | |||
765 | *secid = smack_to_secid(isp->smk_inode); | ||
766 | } | ||
767 | |||
755 | /* | 768 | /* |
756 | * File Hooks | 769 | * File Hooks |
757 | */ | 770 | */ |
@@ -1805,6 +1818,18 @@ static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag) | |||
1805 | return smk_curacc(isp, may); | 1818 | return smk_curacc(isp, may); |
1806 | } | 1819 | } |
1807 | 1820 | ||
1821 | /** | ||
1822 | * smack_ipc_getsecid - Extract smack security id | ||
1823 | * @ipcp: the object permissions | ||
1824 | * @secid: where result will be saved | ||
1825 | */ | ||
1826 | static void smack_ipc_getsecid(struct kern_ipc_perm *ipp, u32 *secid) | ||
1827 | { | ||
1828 | char *smack = ipp->security; | ||
1829 | |||
1830 | *secid = smack_to_secid(smack); | ||
1831 | } | ||
1832 | |||
1808 | /* module stacking operations */ | 1833 | /* module stacking operations */ |
1809 | 1834 | ||
1810 | /** | 1835 | /** |
@@ -2382,6 +2407,124 @@ static int smack_key_permission(key_ref_t key_ref, | |||
2382 | #endif /* CONFIG_KEYS */ | 2407 | #endif /* CONFIG_KEYS */ |
2383 | 2408 | ||
2384 | /* | 2409 | /* |
2410 | * Smack Audit hooks | ||
2411 | * | ||
2412 | * Audit requires a unique representation of each Smack specific | ||
2413 | * rule. This unique representation is used to distinguish the | ||
2414 | * object to be audited from remaining kernel objects and also | ||
2415 | * works as a glue between the audit hooks. | ||
2416 | * | ||
2417 | * Since repository entries are added but never deleted, we'll use | ||
2418 | * the smack_known label address related to the given audit rule as | ||
2419 | * the needed unique representation. This also better fits the smack | ||
2420 | * model where nearly everything is a label. | ||
2421 | */ | ||
2422 | #ifdef CONFIG_AUDIT | ||
2423 | |||
2424 | /** | ||
2425 | * smack_audit_rule_init - Initialize a smack audit rule | ||
2426 | * @field: audit rule fields given from user-space (audit.h) | ||
2427 | * @op: required testing operator (=, !=, >, <, ...) | ||
2428 | * @rulestr: smack label to be audited | ||
2429 | * @vrule: pointer to save our own audit rule representation | ||
2430 | * | ||
2431 | * Prepare to audit cases where (@field @op @rulestr) is true. | ||
2432 | * The label to be audited is created if necessay. | ||
2433 | */ | ||
2434 | static int smack_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) | ||
2435 | { | ||
2436 | char **rule = (char **)vrule; | ||
2437 | *rule = NULL; | ||
2438 | |||
2439 | if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER) | ||
2440 | return -EINVAL; | ||
2441 | |||
2442 | if (op != AUDIT_EQUAL && op != AUDIT_NOT_EQUAL) | ||
2443 | return -EINVAL; | ||
2444 | |||
2445 | *rule = smk_import(rulestr, 0); | ||
2446 | |||
2447 | return 0; | ||
2448 | } | ||
2449 | |||
2450 | /** | ||
2451 | * smack_audit_rule_known - Distinguish Smack audit rules | ||
2452 | * @krule: rule of interest, in Audit kernel representation format | ||
2453 | * | ||
2454 | * This is used to filter Smack rules from remaining Audit ones. | ||
2455 | * If it's proved that this rule belongs to us, the | ||
2456 | * audit_rule_match hook will be called to do the final judgement. | ||
2457 | */ | ||
2458 | static int smack_audit_rule_known(struct audit_krule *krule) | ||
2459 | { | ||
2460 | struct audit_field *f; | ||
2461 | int i; | ||
2462 | |||
2463 | for (i = 0; i < krule->field_count; i++) { | ||
2464 | f = &krule->fields[i]; | ||
2465 | |||
2466 | if (f->type == AUDIT_SUBJ_USER || f->type == AUDIT_OBJ_USER) | ||
2467 | return 1; | ||
2468 | } | ||
2469 | |||
2470 | return 0; | ||
2471 | } | ||
2472 | |||
2473 | /** | ||
2474 | * smack_audit_rule_match - Audit given object ? | ||
2475 | * @secid: security id for identifying the object to test | ||
2476 | * @field: audit rule flags given from user-space | ||
2477 | * @op: required testing operator | ||
2478 | * @vrule: smack internal rule presentation | ||
2479 | * @actx: audit context associated with the check | ||
2480 | * | ||
2481 | * The core Audit hook. It's used to take the decision of | ||
2482 | * whether to audit or not to audit a given object. | ||
2483 | */ | ||
2484 | static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule, | ||
2485 | struct audit_context *actx) | ||
2486 | { | ||
2487 | char *smack; | ||
2488 | char *rule = vrule; | ||
2489 | |||
2490 | if (!rule) { | ||
2491 | audit_log(actx, GFP_KERNEL, AUDIT_SELINUX_ERR, | ||
2492 | "Smack: missing rule\n"); | ||
2493 | return -ENOENT; | ||
2494 | } | ||
2495 | |||
2496 | if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER) | ||
2497 | return 0; | ||
2498 | |||
2499 | smack = smack_from_secid(secid); | ||
2500 | |||
2501 | /* | ||
2502 | * No need to do string comparisons. If a match occurs, | ||
2503 | * both pointers will point to the same smack_known | ||
2504 | * label. | ||
2505 | */ | ||
2506 | if (op == AUDIT_EQUAL) | ||
2507 | return (rule == smack); | ||
2508 | if (op == AUDIT_NOT_EQUAL) | ||
2509 | return (rule != smack); | ||
2510 | |||
2511 | return 0; | ||
2512 | } | ||
2513 | |||
2514 | /** | ||
2515 | * smack_audit_rule_free - free smack rule representation | ||
2516 | * @vrule: rule to be freed. | ||
2517 | * | ||
2518 | * No memory was allocated. | ||
2519 | */ | ||
2520 | static void smack_audit_rule_free(void *vrule) | ||
2521 | { | ||
2522 | /* No-op */ | ||
2523 | } | ||
2524 | |||
2525 | #endif /* CONFIG_AUDIT */ | ||
2526 | |||
2527 | /* | ||
2385 | * smack_secid_to_secctx - return the smack label for a secid | 2528 | * smack_secid_to_secctx - return the smack label for a secid |
2386 | * @secid: incoming integer | 2529 | * @secid: incoming integer |
2387 | * @secdata: destination | 2530 | * @secdata: destination |
@@ -2467,6 +2610,7 @@ struct security_operations smack_ops = { | |||
2467 | .inode_getsecurity = smack_inode_getsecurity, | 2610 | .inode_getsecurity = smack_inode_getsecurity, |
2468 | .inode_setsecurity = smack_inode_setsecurity, | 2611 | .inode_setsecurity = smack_inode_setsecurity, |
2469 | .inode_listsecurity = smack_inode_listsecurity, | 2612 | .inode_listsecurity = smack_inode_listsecurity, |
2613 | .inode_getsecid = smack_inode_getsecid, | ||
2470 | 2614 | ||
2471 | .file_permission = smack_file_permission, | 2615 | .file_permission = smack_file_permission, |
2472 | .file_alloc_security = smack_file_alloc_security, | 2616 | .file_alloc_security = smack_file_alloc_security, |
@@ -2498,6 +2642,7 @@ struct security_operations smack_ops = { | |||
2498 | .task_prctl = cap_task_prctl, | 2642 | .task_prctl = cap_task_prctl, |
2499 | 2643 | ||
2500 | .ipc_permission = smack_ipc_permission, | 2644 | .ipc_permission = smack_ipc_permission, |
2645 | .ipc_getsecid = smack_ipc_getsecid, | ||
2501 | 2646 | ||
2502 | .msg_msg_alloc_security = smack_msg_msg_alloc_security, | 2647 | .msg_msg_alloc_security = smack_msg_msg_alloc_security, |
2503 | .msg_msg_free_security = smack_msg_msg_free_security, | 2648 | .msg_msg_free_security = smack_msg_msg_free_security, |
@@ -2542,12 +2687,22 @@ struct security_operations smack_ops = { | |||
2542 | .sk_free_security = smack_sk_free_security, | 2687 | .sk_free_security = smack_sk_free_security, |
2543 | .sock_graft = smack_sock_graft, | 2688 | .sock_graft = smack_sock_graft, |
2544 | .inet_conn_request = smack_inet_conn_request, | 2689 | .inet_conn_request = smack_inet_conn_request, |
2690 | |||
2545 | /* key management security hooks */ | 2691 | /* key management security hooks */ |
2546 | #ifdef CONFIG_KEYS | 2692 | #ifdef CONFIG_KEYS |
2547 | .key_alloc = smack_key_alloc, | 2693 | .key_alloc = smack_key_alloc, |
2548 | .key_free = smack_key_free, | 2694 | .key_free = smack_key_free, |
2549 | .key_permission = smack_key_permission, | 2695 | .key_permission = smack_key_permission, |
2550 | #endif /* CONFIG_KEYS */ | 2696 | #endif /* CONFIG_KEYS */ |
2697 | |||
2698 | /* Audit hooks */ | ||
2699 | #ifdef CONFIG_AUDIT | ||
2700 | .audit_rule_init = smack_audit_rule_init, | ||
2701 | .audit_rule_known = smack_audit_rule_known, | ||
2702 | .audit_rule_match = smack_audit_rule_match, | ||
2703 | .audit_rule_free = smack_audit_rule_free, | ||
2704 | #endif /* CONFIG_AUDIT */ | ||
2705 | |||
2551 | .secid_to_secctx = smack_secid_to_secctx, | 2706 | .secid_to_secctx = smack_secid_to_secctx, |
2552 | .secctx_to_secid = smack_secctx_to_secid, | 2707 | .secctx_to_secid = smack_secctx_to_secid, |
2553 | .release_secctx = smack_release_secctx, | 2708 | .release_secctx = smack_release_secctx, |