aboutsummaryrefslogtreecommitdiffstats
path: root/security/smack/smack_lsm.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/smack/smack_lsm.c')
-rw-r--r--security/smack/smack_lsm.c178
1 files changed, 162 insertions, 16 deletions
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 77ec16a3b68b..b5c8f9237008 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
@@ -574,8 +575,8 @@ static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
574 * 575 *
575 * Returns 0 if access is permitted, an error code otherwise 576 * Returns 0 if access is permitted, an error code otherwise
576 */ 577 */
577static int smack_inode_setxattr(struct dentry *dentry, char *name, 578static int smack_inode_setxattr(struct dentry *dentry, const char *name,
578 void *value, size_t size, int flags) 579 const void *value, size_t size, int flags)
579{ 580{
580 int rc = 0; 581 int rc = 0;
581 582
@@ -604,8 +605,8 @@ static int smack_inode_setxattr(struct dentry *dentry, char *name,
604 * Set the pointer in the inode blob to the entry found 605 * Set the pointer in the inode blob to the entry found
605 * in the master label list. 606 * in the master label list.
606 */ 607 */
607static void smack_inode_post_setxattr(struct dentry *dentry, char *name, 608static void smack_inode_post_setxattr(struct dentry *dentry, const char *name,
608 void *value, size_t size, int flags) 609 const void *value, size_t size, int flags)
609{ 610{
610 struct inode_smack *isp; 611 struct inode_smack *isp;
611 char *nsp; 612 char *nsp;
@@ -641,7 +642,7 @@ static void smack_inode_post_setxattr(struct dentry *dentry, char *name,
641 * 642 *
642 * Returns 0 if access is permitted, an error code otherwise 643 * Returns 0 if access is permitted, an error code otherwise
643 */ 644 */
644static int smack_inode_getxattr(struct dentry *dentry, char *name) 645static int smack_inode_getxattr(struct dentry *dentry, const char *name)
645{ 646{
646 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ); 647 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ);
647} 648}
@@ -655,7 +656,7 @@ static int smack_inode_getxattr(struct dentry *dentry, char *name)
655 * 656 *
656 * Returns 0 if access is permitted, an error code otherwise 657 * Returns 0 if access is permitted, an error code otherwise
657 */ 658 */
658static int smack_inode_removexattr(struct dentry *dentry, char *name) 659static int smack_inode_removexattr(struct dentry *dentry, const char *name)
659{ 660{
660 int rc = 0; 661 int rc = 0;
661 662
@@ -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 */
761static 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 */
@@ -1118,15 +1131,6 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info,
1118 int sig, u32 secid) 1131 int sig, u32 secid)
1119{ 1132{
1120 /* 1133 /*
1121 * Special cases where signals really ought to go through
1122 * in spite of policy. Stephen Smalley suggests it may
1123 * make sense to change the caller so that it doesn't
1124 * bother with the LSM hook in these cases.
1125 */
1126 if (info != SEND_SIG_NOINFO &&
1127 (is_si_special(info) || SI_FROMKERNEL(info)))
1128 return 0;
1129 /*
1130 * Sending a signal requires that the sender 1134 * Sending a signal requires that the sender
1131 * can write the receiver. 1135 * can write the receiver.
1132 */ 1136 */
@@ -1805,6 +1809,18 @@ static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag)
1805 return smk_curacc(isp, may); 1809 return smk_curacc(isp, may);
1806} 1810}
1807 1811
1812/**
1813 * smack_ipc_getsecid - Extract smack security id
1814 * @ipcp: the object permissions
1815 * @secid: where result will be saved
1816 */
1817static void smack_ipc_getsecid(struct kern_ipc_perm *ipp, u32 *secid)
1818{
1819 char *smack = ipp->security;
1820
1821 *secid = smack_to_secid(smack);
1822}
1823
1808/* module stacking operations */ 1824/* module stacking operations */
1809 1825
1810/** 1826/**
@@ -2382,6 +2398,124 @@ static int smack_key_permission(key_ref_t key_ref,
2382#endif /* CONFIG_KEYS */ 2398#endif /* CONFIG_KEYS */
2383 2399
2384/* 2400/*
2401 * Smack Audit hooks
2402 *
2403 * Audit requires a unique representation of each Smack specific
2404 * rule. This unique representation is used to distinguish the
2405 * object to be audited from remaining kernel objects and also
2406 * works as a glue between the audit hooks.
2407 *
2408 * Since repository entries are added but never deleted, we'll use
2409 * the smack_known label address related to the given audit rule as
2410 * the needed unique representation. This also better fits the smack
2411 * model where nearly everything is a label.
2412 */
2413#ifdef CONFIG_AUDIT
2414
2415/**
2416 * smack_audit_rule_init - Initialize a smack audit rule
2417 * @field: audit rule fields given from user-space (audit.h)
2418 * @op: required testing operator (=, !=, >, <, ...)
2419 * @rulestr: smack label to be audited
2420 * @vrule: pointer to save our own audit rule representation
2421 *
2422 * Prepare to audit cases where (@field @op @rulestr) is true.
2423 * The label to be audited is created if necessay.
2424 */
2425static int smack_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
2426{
2427 char **rule = (char **)vrule;
2428 *rule = NULL;
2429
2430 if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
2431 return -EINVAL;
2432
2433 if (op != AUDIT_EQUAL && op != AUDIT_NOT_EQUAL)
2434 return -EINVAL;
2435
2436 *rule = smk_import(rulestr, 0);
2437
2438 return 0;
2439}
2440
2441/**
2442 * smack_audit_rule_known - Distinguish Smack audit rules
2443 * @krule: rule of interest, in Audit kernel representation format
2444 *
2445 * This is used to filter Smack rules from remaining Audit ones.
2446 * If it's proved that this rule belongs to us, the
2447 * audit_rule_match hook will be called to do the final judgement.
2448 */
2449static int smack_audit_rule_known(struct audit_krule *krule)
2450{
2451 struct audit_field *f;
2452 int i;
2453
2454 for (i = 0; i < krule->field_count; i++) {
2455 f = &krule->fields[i];
2456
2457 if (f->type == AUDIT_SUBJ_USER || f->type == AUDIT_OBJ_USER)
2458 return 1;
2459 }
2460
2461 return 0;
2462}
2463
2464/**
2465 * smack_audit_rule_match - Audit given object ?
2466 * @secid: security id for identifying the object to test
2467 * @field: audit rule flags given from user-space
2468 * @op: required testing operator
2469 * @vrule: smack internal rule presentation
2470 * @actx: audit context associated with the check
2471 *
2472 * The core Audit hook. It's used to take the decision of
2473 * whether to audit or not to audit a given object.
2474 */
2475static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule,
2476 struct audit_context *actx)
2477{
2478 char *smack;
2479 char *rule = vrule;
2480
2481 if (!rule) {
2482 audit_log(actx, GFP_KERNEL, AUDIT_SELINUX_ERR,
2483 "Smack: missing rule\n");
2484 return -ENOENT;
2485 }
2486
2487 if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
2488 return 0;
2489
2490 smack = smack_from_secid(secid);
2491
2492 /*
2493 * No need to do string comparisons. If a match occurs,
2494 * both pointers will point to the same smack_known
2495 * label.
2496 */
2497 if (op == AUDIT_EQUAL)
2498 return (rule == smack);
2499 if (op == AUDIT_NOT_EQUAL)
2500 return (rule != smack);
2501
2502 return 0;
2503}
2504
2505/**
2506 * smack_audit_rule_free - free smack rule representation
2507 * @vrule: rule to be freed.
2508 *
2509 * No memory was allocated.
2510 */
2511static void smack_audit_rule_free(void *vrule)
2512{
2513 /* No-op */
2514}
2515
2516#endif /* CONFIG_AUDIT */
2517
2518/*
2385 * smack_secid_to_secctx - return the smack label for a secid 2519 * smack_secid_to_secctx - return the smack label for a secid
2386 * @secid: incoming integer 2520 * @secid: incoming integer
2387 * @secdata: destination 2521 * @secdata: destination
@@ -2406,7 +2540,7 @@ static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
2406 * 2540 *
2407 * Exists for audit and networking code. 2541 * Exists for audit and networking code.
2408 */ 2542 */
2409static int smack_secctx_to_secid(char *secdata, u32 seclen, u32 *secid) 2543static int smack_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
2410{ 2544{
2411 *secid = smack_to_secid(secdata); 2545 *secid = smack_to_secid(secdata);
2412 return 0; 2546 return 0;
@@ -2467,6 +2601,7 @@ struct security_operations smack_ops = {
2467 .inode_getsecurity = smack_inode_getsecurity, 2601 .inode_getsecurity = smack_inode_getsecurity,
2468 .inode_setsecurity = smack_inode_setsecurity, 2602 .inode_setsecurity = smack_inode_setsecurity,
2469 .inode_listsecurity = smack_inode_listsecurity, 2603 .inode_listsecurity = smack_inode_listsecurity,
2604 .inode_getsecid = smack_inode_getsecid,
2470 2605
2471 .file_permission = smack_file_permission, 2606 .file_permission = smack_file_permission,
2472 .file_alloc_security = smack_file_alloc_security, 2607 .file_alloc_security = smack_file_alloc_security,
@@ -2498,6 +2633,7 @@ struct security_operations smack_ops = {
2498 .task_prctl = cap_task_prctl, 2633 .task_prctl = cap_task_prctl,
2499 2634
2500 .ipc_permission = smack_ipc_permission, 2635 .ipc_permission = smack_ipc_permission,
2636 .ipc_getsecid = smack_ipc_getsecid,
2501 2637
2502 .msg_msg_alloc_security = smack_msg_msg_alloc_security, 2638 .msg_msg_alloc_security = smack_msg_msg_alloc_security,
2503 .msg_msg_free_security = smack_msg_msg_free_security, 2639 .msg_msg_free_security = smack_msg_msg_free_security,
@@ -2542,12 +2678,22 @@ struct security_operations smack_ops = {
2542 .sk_free_security = smack_sk_free_security, 2678 .sk_free_security = smack_sk_free_security,
2543 .sock_graft = smack_sock_graft, 2679 .sock_graft = smack_sock_graft,
2544 .inet_conn_request = smack_inet_conn_request, 2680 .inet_conn_request = smack_inet_conn_request,
2681
2545 /* key management security hooks */ 2682 /* key management security hooks */
2546#ifdef CONFIG_KEYS 2683#ifdef CONFIG_KEYS
2547 .key_alloc = smack_key_alloc, 2684 .key_alloc = smack_key_alloc,
2548 .key_free = smack_key_free, 2685 .key_free = smack_key_free,
2549 .key_permission = smack_key_permission, 2686 .key_permission = smack_key_permission,
2550#endif /* CONFIG_KEYS */ 2687#endif /* CONFIG_KEYS */
2688
2689 /* Audit hooks */
2690#ifdef CONFIG_AUDIT
2691 .audit_rule_init = smack_audit_rule_init,
2692 .audit_rule_known = smack_audit_rule_known,
2693 .audit_rule_match = smack_audit_rule_match,
2694 .audit_rule_free = smack_audit_rule_free,
2695#endif /* CONFIG_AUDIT */
2696
2551 .secid_to_secctx = smack_secid_to_secctx, 2697 .secid_to_secctx = smack_secid_to_secctx,
2552 .secctx_to_secid = smack_secctx_to_secid, 2698 .secctx_to_secid = smack_secctx_to_secid,
2553 .release_secctx = smack_release_secctx, 2699 .release_secctx = smack_release_secctx,