diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-18 21:18:30 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-18 21:18:30 -0400 |
commit | 3925e6fc1f774048404fdd910b0345b06c699eb4 (patch) | |
tree | c9a58417d9492f39f7fe81d4721d674c34dd8be2 /security | |
parent | 334d094504c2fe1c44211ecb49146ae6bca8c321 (diff) | |
parent | 7cea51be4e91edad05bd834f3235b45c57783f0d (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6:
security: fix up documentation for security_module_enable
Security: Introduce security= boot parameter
Audit: Final renamings and cleanup
SELinux: use new audit hooks, remove redundant exports
Audit: internally use the new LSM audit hooks
LSM/Audit: Introduce generic Audit LSM hooks
SELinux: remove redundant exports
Netlink: Use generic LSM hook
Audit: use new LSM hooks instead of SELinux exports
SELinux: setup new inode/ipc getsecid hooks
LSM: Introduce inode_getsecid and ipc_getsecid hooks
Diffstat (limited to 'security')
-rw-r--r-- | security/dummy.c | 51 | ||||
-rw-r--r-- | security/security.c | 73 | ||||
-rw-r--r-- | security/selinux/exports.c | 42 | ||||
-rw-r--r-- | security/selinux/hooks.c | 34 | ||||
-rw-r--r-- | security/selinux/include/audit.h | 65 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 45 | ||||
-rw-r--r-- | security/smack/smack.h | 2 | ||||
-rw-r--r-- | security/smack/smack_lsm.c | 7 | ||||
-rw-r--r-- | security/smack/smackfs.c | 11 |
9 files changed, 269 insertions, 61 deletions
diff --git a/security/dummy.c b/security/dummy.c index 480366f9c41d..98d5f969cdc8 100644 --- a/security/dummy.c +++ b/security/dummy.c | |||
@@ -424,6 +424,11 @@ static int dummy_inode_listsecurity(struct inode *inode, char *buffer, size_t bu | |||
424 | return 0; | 424 | return 0; |
425 | } | 425 | } |
426 | 426 | ||
427 | static void dummy_inode_getsecid(const struct inode *inode, u32 *secid) | ||
428 | { | ||
429 | *secid = 0; | ||
430 | } | ||
431 | |||
427 | static int dummy_file_permission (struct file *file, int mask) | 432 | static int dummy_file_permission (struct file *file, int mask) |
428 | { | 433 | { |
429 | return 0; | 434 | return 0; |
@@ -542,7 +547,9 @@ static int dummy_task_getsid (struct task_struct *p) | |||
542 | } | 547 | } |
543 | 548 | ||
544 | static void dummy_task_getsecid (struct task_struct *p, u32 *secid) | 549 | static void dummy_task_getsecid (struct task_struct *p, u32 *secid) |
545 | { } | 550 | { |
551 | *secid = 0; | ||
552 | } | ||
546 | 553 | ||
547 | static int dummy_task_setgroups (struct group_info *group_info) | 554 | static int dummy_task_setgroups (struct group_info *group_info) |
548 | { | 555 | { |
@@ -616,6 +623,11 @@ static int dummy_ipc_permission (struct kern_ipc_perm *ipcp, short flag) | |||
616 | return 0; | 623 | return 0; |
617 | } | 624 | } |
618 | 625 | ||
626 | static void dummy_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid) | ||
627 | { | ||
628 | *secid = 0; | ||
629 | } | ||
630 | |||
619 | static int dummy_msg_msg_alloc_security (struct msg_msg *msg) | 631 | static int dummy_msg_msg_alloc_security (struct msg_msg *msg) |
620 | { | 632 | { |
621 | return 0; | 633 | return 0; |
@@ -983,7 +995,33 @@ static inline int dummy_key_permission(key_ref_t key_ref, | |||
983 | } | 995 | } |
984 | #endif /* CONFIG_KEYS */ | 996 | #endif /* CONFIG_KEYS */ |
985 | 997 | ||
986 | struct security_operations dummy_security_ops; | 998 | #ifdef CONFIG_AUDIT |
999 | static inline int dummy_audit_rule_init(u32 field, u32 op, char *rulestr, | ||
1000 | void **lsmrule) | ||
1001 | { | ||
1002 | return 0; | ||
1003 | } | ||
1004 | |||
1005 | static inline int dummy_audit_rule_known(struct audit_krule *krule) | ||
1006 | { | ||
1007 | return 0; | ||
1008 | } | ||
1009 | |||
1010 | static inline int dummy_audit_rule_match(u32 secid, u32 field, u32 op, | ||
1011 | void *lsmrule, | ||
1012 | struct audit_context *actx) | ||
1013 | { | ||
1014 | return 0; | ||
1015 | } | ||
1016 | |||
1017 | static inline void dummy_audit_rule_free(void *lsmrule) | ||
1018 | { } | ||
1019 | |||
1020 | #endif /* CONFIG_AUDIT */ | ||
1021 | |||
1022 | struct security_operations dummy_security_ops = { | ||
1023 | .name = "dummy", | ||
1024 | }; | ||
987 | 1025 | ||
988 | #define set_to_dummy_if_null(ops, function) \ | 1026 | #define set_to_dummy_if_null(ops, function) \ |
989 | do { \ | 1027 | do { \ |
@@ -1060,6 +1098,7 @@ void security_fixup_ops (struct security_operations *ops) | |||
1060 | set_to_dummy_if_null(ops, inode_getsecurity); | 1098 | set_to_dummy_if_null(ops, inode_getsecurity); |
1061 | set_to_dummy_if_null(ops, inode_setsecurity); | 1099 | set_to_dummy_if_null(ops, inode_setsecurity); |
1062 | set_to_dummy_if_null(ops, inode_listsecurity); | 1100 | set_to_dummy_if_null(ops, inode_listsecurity); |
1101 | set_to_dummy_if_null(ops, inode_getsecid); | ||
1063 | set_to_dummy_if_null(ops, file_permission); | 1102 | set_to_dummy_if_null(ops, file_permission); |
1064 | set_to_dummy_if_null(ops, file_alloc_security); | 1103 | set_to_dummy_if_null(ops, file_alloc_security); |
1065 | set_to_dummy_if_null(ops, file_free_security); | 1104 | set_to_dummy_if_null(ops, file_free_security); |
@@ -1096,6 +1135,7 @@ void security_fixup_ops (struct security_operations *ops) | |||
1096 | set_to_dummy_if_null(ops, task_reparent_to_init); | 1135 | set_to_dummy_if_null(ops, task_reparent_to_init); |
1097 | set_to_dummy_if_null(ops, task_to_inode); | 1136 | set_to_dummy_if_null(ops, task_to_inode); |
1098 | set_to_dummy_if_null(ops, ipc_permission); | 1137 | set_to_dummy_if_null(ops, ipc_permission); |
1138 | set_to_dummy_if_null(ops, ipc_getsecid); | ||
1099 | set_to_dummy_if_null(ops, msg_msg_alloc_security); | 1139 | set_to_dummy_if_null(ops, msg_msg_alloc_security); |
1100 | set_to_dummy_if_null(ops, msg_msg_free_security); | 1140 | set_to_dummy_if_null(ops, msg_msg_free_security); |
1101 | set_to_dummy_if_null(ops, msg_queue_alloc_security); | 1141 | set_to_dummy_if_null(ops, msg_queue_alloc_security); |
@@ -1170,6 +1210,11 @@ void security_fixup_ops (struct security_operations *ops) | |||
1170 | set_to_dummy_if_null(ops, key_free); | 1210 | set_to_dummy_if_null(ops, key_free); |
1171 | set_to_dummy_if_null(ops, key_permission); | 1211 | set_to_dummy_if_null(ops, key_permission); |
1172 | #endif /* CONFIG_KEYS */ | 1212 | #endif /* CONFIG_KEYS */ |
1173 | 1213 | #ifdef CONFIG_AUDIT | |
1214 | set_to_dummy_if_null(ops, audit_rule_init); | ||
1215 | set_to_dummy_if_null(ops, audit_rule_known); | ||
1216 | set_to_dummy_if_null(ops, audit_rule_match); | ||
1217 | set_to_dummy_if_null(ops, audit_rule_free); | ||
1218 | #endif | ||
1174 | } | 1219 | } |
1175 | 1220 | ||
diff --git a/security/security.c b/security/security.c index 54affd0ce6ad..2e250c7028eb 100644 --- a/security/security.c +++ b/security/security.c | |||
@@ -17,6 +17,8 @@ | |||
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | #include <linux/security.h> | 18 | #include <linux/security.h> |
19 | 19 | ||
20 | /* Boot-time LSM user choice */ | ||
21 | static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1]; | ||
20 | 22 | ||
21 | /* things that live in dummy.c */ | 23 | /* things that live in dummy.c */ |
22 | extern struct security_operations dummy_security_ops; | 24 | extern struct security_operations dummy_security_ops; |
@@ -67,13 +69,47 @@ int __init security_init(void) | |||
67 | return 0; | 69 | return 0; |
68 | } | 70 | } |
69 | 71 | ||
72 | /* Save user chosen LSM */ | ||
73 | static int __init choose_lsm(char *str) | ||
74 | { | ||
75 | strncpy(chosen_lsm, str, SECURITY_NAME_MAX); | ||
76 | return 1; | ||
77 | } | ||
78 | __setup("security=", choose_lsm); | ||
79 | |||
80 | /** | ||
81 | * security_module_enable - Load given security module on boot ? | ||
82 | * @ops: a pointer to the struct security_operations that is to be checked. | ||
83 | * | ||
84 | * Each LSM must pass this method before registering its own operations | ||
85 | * to avoid security registration races. This method may also be used | ||
86 | * to check if your LSM is currently loaded during kernel initialization. | ||
87 | * | ||
88 | * Return true if: | ||
89 | * -The passed LSM is the one chosen by user at boot time, | ||
90 | * -or user didsn't specify a specific LSM and we're the first to ask | ||
91 | * for registeration permissoin, | ||
92 | * -or the passed LSM is currently loaded. | ||
93 | * Otherwise, return false. | ||
94 | */ | ||
95 | int __init security_module_enable(struct security_operations *ops) | ||
96 | { | ||
97 | if (!*chosen_lsm) | ||
98 | strncpy(chosen_lsm, ops->name, SECURITY_NAME_MAX); | ||
99 | else if (strncmp(ops->name, chosen_lsm, SECURITY_NAME_MAX)) | ||
100 | return 0; | ||
101 | |||
102 | return 1; | ||
103 | } | ||
104 | |||
70 | /** | 105 | /** |
71 | * register_security - registers a security framework with the kernel | 106 | * register_security - registers a security framework with the kernel |
72 | * @ops: a pointer to the struct security_options that is to be registered | 107 | * @ops: a pointer to the struct security_options that is to be registered |
73 | * | 108 | * |
74 | * This function is to allow a security module to register itself with the | 109 | * This function is to allow a security module to register itself with the |
75 | * kernel security subsystem. Some rudimentary checking is done on the @ops | 110 | * kernel security subsystem. Some rudimentary checking is done on the @ops |
76 | * value passed to this function. | 111 | * value passed to this function. You'll need to check first if your LSM |
112 | * is allowed to register its @ops by calling security_module_enable(@ops). | ||
77 | * | 113 | * |
78 | * If there is already a security module registered with the kernel, | 114 | * If there is already a security module registered with the kernel, |
79 | * an error will be returned. Otherwise 0 is returned on success. | 115 | * an error will be returned. Otherwise 0 is returned on success. |
@@ -523,6 +559,11 @@ int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer | |||
523 | return security_ops->inode_listsecurity(inode, buffer, buffer_size); | 559 | return security_ops->inode_listsecurity(inode, buffer, buffer_size); |
524 | } | 560 | } |
525 | 561 | ||
562 | void security_inode_getsecid(const struct inode *inode, u32 *secid) | ||
563 | { | ||
564 | security_ops->inode_getsecid(inode, secid); | ||
565 | } | ||
566 | |||
526 | int security_file_permission(struct file *file, int mask) | 567 | int security_file_permission(struct file *file, int mask) |
527 | { | 568 | { |
528 | return security_ops->file_permission(file, mask); | 569 | return security_ops->file_permission(file, mask); |
@@ -712,6 +753,11 @@ int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag) | |||
712 | return security_ops->ipc_permission(ipcp, flag); | 753 | return security_ops->ipc_permission(ipcp, flag); |
713 | } | 754 | } |
714 | 755 | ||
756 | void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid) | ||
757 | { | ||
758 | security_ops->ipc_getsecid(ipcp, secid); | ||
759 | } | ||
760 | |||
715 | int security_msg_msg_alloc(struct msg_msg *msg) | 761 | int security_msg_msg_alloc(struct msg_msg *msg) |
716 | { | 762 | { |
717 | return security_ops->msg_msg_alloc_security(msg); | 763 | return security_ops->msg_msg_alloc_security(msg); |
@@ -1111,3 +1157,28 @@ int security_key_permission(key_ref_t key_ref, | |||
1111 | } | 1157 | } |
1112 | 1158 | ||
1113 | #endif /* CONFIG_KEYS */ | 1159 | #endif /* CONFIG_KEYS */ |
1160 | |||
1161 | #ifdef CONFIG_AUDIT | ||
1162 | |||
1163 | int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule) | ||
1164 | { | ||
1165 | return security_ops->audit_rule_init(field, op, rulestr, lsmrule); | ||
1166 | } | ||
1167 | |||
1168 | int security_audit_rule_known(struct audit_krule *krule) | ||
1169 | { | ||
1170 | return security_ops->audit_rule_known(krule); | ||
1171 | } | ||
1172 | |||
1173 | void security_audit_rule_free(void *lsmrule) | ||
1174 | { | ||
1175 | security_ops->audit_rule_free(lsmrule); | ||
1176 | } | ||
1177 | |||
1178 | int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule, | ||
1179 | struct audit_context *actx) | ||
1180 | { | ||
1181 | return security_ops->audit_rule_match(secid, field, op, lsmrule, actx); | ||
1182 | } | ||
1183 | |||
1184 | #endif /* CONFIG_AUDIT */ | ||
diff --git a/security/selinux/exports.c b/security/selinux/exports.c index 87d2bb3ea355..64af2d3409ef 100644 --- a/security/selinux/exports.c +++ b/security/selinux/exports.c | |||
@@ -25,48 +25,6 @@ | |||
25 | /* SECMARK reference count */ | 25 | /* SECMARK reference count */ |
26 | extern atomic_t selinux_secmark_refcount; | 26 | extern atomic_t selinux_secmark_refcount; |
27 | 27 | ||
28 | int selinux_sid_to_string(u32 sid, char **ctx, u32 *ctxlen) | ||
29 | { | ||
30 | if (selinux_enabled) | ||
31 | return security_sid_to_context(sid, ctx, ctxlen); | ||
32 | else { | ||
33 | *ctx = NULL; | ||
34 | *ctxlen = 0; | ||
35 | } | ||
36 | |||
37 | return 0; | ||
38 | } | ||
39 | |||
40 | void selinux_get_inode_sid(const struct inode *inode, u32 *sid) | ||
41 | { | ||
42 | if (selinux_enabled) { | ||
43 | struct inode_security_struct *isec = inode->i_security; | ||
44 | *sid = isec->sid; | ||
45 | return; | ||
46 | } | ||
47 | *sid = 0; | ||
48 | } | ||
49 | |||
50 | void selinux_get_ipc_sid(const struct kern_ipc_perm *ipcp, u32 *sid) | ||
51 | { | ||
52 | if (selinux_enabled) { | ||
53 | struct ipc_security_struct *isec = ipcp->security; | ||
54 | *sid = isec->sid; | ||
55 | return; | ||
56 | } | ||
57 | *sid = 0; | ||
58 | } | ||
59 | |||
60 | void selinux_get_task_sid(struct task_struct *tsk, u32 *sid) | ||
61 | { | ||
62 | if (selinux_enabled) { | ||
63 | struct task_security_struct *tsec = tsk->security; | ||
64 | *sid = tsec->sid; | ||
65 | return; | ||
66 | } | ||
67 | *sid = 0; | ||
68 | } | ||
69 | |||
70 | int selinux_string_to_sid(char *str, u32 *sid) | 28 | int selinux_string_to_sid(char *str, u32 *sid) |
71 | { | 29 | { |
72 | if (selinux_enabled) | 30 | if (selinux_enabled) |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 34f2d46c7984..f9927f02bc3d 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -83,6 +83,7 @@ | |||
83 | #include "netport.h" | 83 | #include "netport.h" |
84 | #include "xfrm.h" | 84 | #include "xfrm.h" |
85 | #include "netlabel.h" | 85 | #include "netlabel.h" |
86 | #include "audit.h" | ||
86 | 87 | ||
87 | #define XATTR_SELINUX_SUFFIX "selinux" | 88 | #define XATTR_SELINUX_SUFFIX "selinux" |
88 | #define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX | 89 | #define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX |
@@ -2792,6 +2793,12 @@ static int selinux_inode_killpriv(struct dentry *dentry) | |||
2792 | return secondary_ops->inode_killpriv(dentry); | 2793 | return secondary_ops->inode_killpriv(dentry); |
2793 | } | 2794 | } |
2794 | 2795 | ||
2796 | static void selinux_inode_getsecid(const struct inode *inode, u32 *secid) | ||
2797 | { | ||
2798 | struct inode_security_struct *isec = inode->i_security; | ||
2799 | *secid = isec->sid; | ||
2800 | } | ||
2801 | |||
2795 | /* file security operations */ | 2802 | /* file security operations */ |
2796 | 2803 | ||
2797 | static int selinux_revalidate_file_permission(struct file *file, int mask) | 2804 | static int selinux_revalidate_file_permission(struct file *file, int mask) |
@@ -3183,7 +3190,8 @@ static int selinux_task_getsid(struct task_struct *p) | |||
3183 | 3190 | ||
3184 | static void selinux_task_getsecid(struct task_struct *p, u32 *secid) | 3191 | static void selinux_task_getsecid(struct task_struct *p, u32 *secid) |
3185 | { | 3192 | { |
3186 | selinux_get_task_sid(p, secid); | 3193 | struct task_security_struct *tsec = p->security; |
3194 | *secid = tsec->sid; | ||
3187 | } | 3195 | } |
3188 | 3196 | ||
3189 | static int selinux_task_setgroups(struct group_info *group_info) | 3197 | static int selinux_task_setgroups(struct group_info *group_info) |
@@ -4149,7 +4157,7 @@ static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff * | |||
4149 | goto out; | 4157 | goto out; |
4150 | 4158 | ||
4151 | if (sock && family == PF_UNIX) | 4159 | if (sock && family == PF_UNIX) |
4152 | selinux_get_inode_sid(SOCK_INODE(sock), &peer_secid); | 4160 | selinux_inode_getsecid(SOCK_INODE(sock), &peer_secid); |
4153 | else if (skb) | 4161 | else if (skb) |
4154 | selinux_skb_peerlbl_sid(skb, family, &peer_secid); | 4162 | selinux_skb_peerlbl_sid(skb, family, &peer_secid); |
4155 | 4163 | ||
@@ -5026,6 +5034,12 @@ static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag) | |||
5026 | return ipc_has_perm(ipcp, av); | 5034 | return ipc_has_perm(ipcp, av); |
5027 | } | 5035 | } |
5028 | 5036 | ||
5037 | static void selinux_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid) | ||
5038 | { | ||
5039 | struct ipc_security_struct *isec = ipcp->security; | ||
5040 | *secid = isec->sid; | ||
5041 | } | ||
5042 | |||
5029 | /* module stacking operations */ | 5043 | /* module stacking operations */ |
5030 | static int selinux_register_security (const char *name, struct security_operations *ops) | 5044 | static int selinux_register_security (const char *name, struct security_operations *ops) |
5031 | { | 5045 | { |
@@ -5281,6 +5295,8 @@ static int selinux_key_permission(key_ref_t key_ref, | |||
5281 | #endif | 5295 | #endif |
5282 | 5296 | ||
5283 | static struct security_operations selinux_ops = { | 5297 | static struct security_operations selinux_ops = { |
5298 | .name = "selinux", | ||
5299 | |||
5284 | .ptrace = selinux_ptrace, | 5300 | .ptrace = selinux_ptrace, |
5285 | .capget = selinux_capget, | 5301 | .capget = selinux_capget, |
5286 | .capset_check = selinux_capset_check, | 5302 | .capset_check = selinux_capset_check, |
@@ -5342,6 +5358,7 @@ static struct security_operations selinux_ops = { | |||
5342 | .inode_listsecurity = selinux_inode_listsecurity, | 5358 | .inode_listsecurity = selinux_inode_listsecurity, |
5343 | .inode_need_killpriv = selinux_inode_need_killpriv, | 5359 | .inode_need_killpriv = selinux_inode_need_killpriv, |
5344 | .inode_killpriv = selinux_inode_killpriv, | 5360 | .inode_killpriv = selinux_inode_killpriv, |
5361 | .inode_getsecid = selinux_inode_getsecid, | ||
5345 | 5362 | ||
5346 | .file_permission = selinux_file_permission, | 5363 | .file_permission = selinux_file_permission, |
5347 | .file_alloc_security = selinux_file_alloc_security, | 5364 | .file_alloc_security = selinux_file_alloc_security, |
@@ -5382,6 +5399,7 @@ static struct security_operations selinux_ops = { | |||
5382 | .task_to_inode = selinux_task_to_inode, | 5399 | .task_to_inode = selinux_task_to_inode, |
5383 | 5400 | ||
5384 | .ipc_permission = selinux_ipc_permission, | 5401 | .ipc_permission = selinux_ipc_permission, |
5402 | .ipc_getsecid = selinux_ipc_getsecid, | ||
5385 | 5403 | ||
5386 | .msg_msg_alloc_security = selinux_msg_msg_alloc_security, | 5404 | .msg_msg_alloc_security = selinux_msg_msg_alloc_security, |
5387 | .msg_msg_free_security = selinux_msg_msg_free_security, | 5405 | .msg_msg_free_security = selinux_msg_msg_free_security, |
@@ -5463,12 +5481,24 @@ static struct security_operations selinux_ops = { | |||
5463 | .key_free = selinux_key_free, | 5481 | .key_free = selinux_key_free, |
5464 | .key_permission = selinux_key_permission, | 5482 | .key_permission = selinux_key_permission, |
5465 | #endif | 5483 | #endif |
5484 | |||
5485 | #ifdef CONFIG_AUDIT | ||
5486 | .audit_rule_init = selinux_audit_rule_init, | ||
5487 | .audit_rule_known = selinux_audit_rule_known, | ||
5488 | .audit_rule_match = selinux_audit_rule_match, | ||
5489 | .audit_rule_free = selinux_audit_rule_free, | ||
5490 | #endif | ||
5466 | }; | 5491 | }; |
5467 | 5492 | ||
5468 | static __init int selinux_init(void) | 5493 | static __init int selinux_init(void) |
5469 | { | 5494 | { |
5470 | struct task_security_struct *tsec; | 5495 | struct task_security_struct *tsec; |
5471 | 5496 | ||
5497 | if (!security_module_enable(&selinux_ops)) { | ||
5498 | selinux_enabled = 0; | ||
5499 | return 0; | ||
5500 | } | ||
5501 | |||
5472 | if (!selinux_enabled) { | 5502 | if (!selinux_enabled) { |
5473 | printk(KERN_INFO "SELinux: Disabled at boot.\n"); | 5503 | printk(KERN_INFO "SELinux: Disabled at boot.\n"); |
5474 | return 0; | 5504 | return 0; |
diff --git a/security/selinux/include/audit.h b/security/selinux/include/audit.h new file mode 100644 index 000000000000..6c8b9ef15579 --- /dev/null +++ b/security/selinux/include/audit.h | |||
@@ -0,0 +1,65 @@ | |||
1 | /* | ||
2 | * SELinux support for the Audit LSM hooks | ||
3 | * | ||
4 | * Most of below header was moved from include/linux/selinux.h which | ||
5 | * is released under below copyrights: | ||
6 | * | ||
7 | * Author: James Morris <jmorris@redhat.com> | ||
8 | * | ||
9 | * Copyright (C) 2005 Red Hat, Inc., James Morris <jmorris@redhat.com> | ||
10 | * Copyright (C) 2006 Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com> | ||
11 | * Copyright (C) 2006 IBM Corporation, Timothy R. Chavez <tinytim@us.ibm.com> | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License version 2, | ||
15 | * as published by the Free Software Foundation. | ||
16 | */ | ||
17 | |||
18 | #ifndef _SELINUX_AUDIT_H | ||
19 | #define _SELINUX_AUDIT_H | ||
20 | |||
21 | /** | ||
22 | * selinux_audit_rule_init - alloc/init an selinux audit rule structure. | ||
23 | * @field: the field this rule refers to | ||
24 | * @op: the operater the rule uses | ||
25 | * @rulestr: the text "target" of the rule | ||
26 | * @rule: pointer to the new rule structure returned via this | ||
27 | * | ||
28 | * Returns 0 if successful, -errno if not. On success, the rule structure | ||
29 | * will be allocated internally. The caller must free this structure with | ||
30 | * selinux_audit_rule_free() after use. | ||
31 | */ | ||
32 | int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **rule); | ||
33 | |||
34 | /** | ||
35 | * selinux_audit_rule_free - free an selinux audit rule structure. | ||
36 | * @rule: pointer to the audit rule to be freed | ||
37 | * | ||
38 | * This will free all memory associated with the given rule. | ||
39 | * If @rule is NULL, no operation is performed. | ||
40 | */ | ||
41 | void selinux_audit_rule_free(void *rule); | ||
42 | |||
43 | /** | ||
44 | * selinux_audit_rule_match - determine if a context ID matches a rule. | ||
45 | * @sid: the context ID to check | ||
46 | * @field: the field this rule refers to | ||
47 | * @op: the operater the rule uses | ||
48 | * @rule: pointer to the audit rule to check against | ||
49 | * @actx: the audit context (can be NULL) associated with the check | ||
50 | * | ||
51 | * Returns 1 if the context id matches the rule, 0 if it does not, and | ||
52 | * -errno on failure. | ||
53 | */ | ||
54 | int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *rule, | ||
55 | struct audit_context *actx); | ||
56 | |||
57 | /** | ||
58 | * selinux_audit_rule_known - check to see if rule contains selinux fields. | ||
59 | * @rule: rule to be checked | ||
60 | * Returns 1 if there are selinux fields specified in the rule, 0 otherwise. | ||
61 | */ | ||
62 | int selinux_audit_rule_known(struct audit_krule *krule); | ||
63 | |||
64 | #endif /* _SELINUX_AUDIT_H */ | ||
65 | |||
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 33425b1ac8d6..b341b8fd8c7c 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -57,6 +57,7 @@ | |||
57 | #include "netlabel.h" | 57 | #include "netlabel.h" |
58 | #include "xfrm.h" | 58 | #include "xfrm.h" |
59 | #include "ebitmap.h" | 59 | #include "ebitmap.h" |
60 | #include "audit.h" | ||
60 | 61 | ||
61 | extern void selnl_notify_policyload(u32 seqno); | 62 | extern void selnl_notify_policyload(u32 seqno); |
62 | unsigned int policydb_loaded_version; | 63 | unsigned int policydb_loaded_version; |
@@ -2296,21 +2297,23 @@ struct selinux_audit_rule { | |||
2296 | struct context au_ctxt; | 2297 | struct context au_ctxt; |
2297 | }; | 2298 | }; |
2298 | 2299 | ||
2299 | void selinux_audit_rule_free(struct selinux_audit_rule *rule) | 2300 | void selinux_audit_rule_free(void *vrule) |
2300 | { | 2301 | { |
2302 | struct selinux_audit_rule *rule = vrule; | ||
2303 | |||
2301 | if (rule) { | 2304 | if (rule) { |
2302 | context_destroy(&rule->au_ctxt); | 2305 | context_destroy(&rule->au_ctxt); |
2303 | kfree(rule); | 2306 | kfree(rule); |
2304 | } | 2307 | } |
2305 | } | 2308 | } |
2306 | 2309 | ||
2307 | int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, | 2310 | int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) |
2308 | struct selinux_audit_rule **rule) | ||
2309 | { | 2311 | { |
2310 | struct selinux_audit_rule *tmprule; | 2312 | struct selinux_audit_rule *tmprule; |
2311 | struct role_datum *roledatum; | 2313 | struct role_datum *roledatum; |
2312 | struct type_datum *typedatum; | 2314 | struct type_datum *typedatum; |
2313 | struct user_datum *userdatum; | 2315 | struct user_datum *userdatum; |
2316 | struct selinux_audit_rule **rule = (struct selinux_audit_rule **)vrule; | ||
2314 | int rc = 0; | 2317 | int rc = 0; |
2315 | 2318 | ||
2316 | *rule = NULL; | 2319 | *rule = NULL; |
@@ -2397,12 +2400,37 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, | |||
2397 | return rc; | 2400 | return rc; |
2398 | } | 2401 | } |
2399 | 2402 | ||
2400 | int selinux_audit_rule_match(u32 sid, u32 field, u32 op, | 2403 | /* Check to see if the rule contains any selinux fields */ |
2401 | struct selinux_audit_rule *rule, | 2404 | int selinux_audit_rule_known(struct audit_krule *rule) |
2405 | { | ||
2406 | int i; | ||
2407 | |||
2408 | for (i = 0; i < rule->field_count; i++) { | ||
2409 | struct audit_field *f = &rule->fields[i]; | ||
2410 | switch (f->type) { | ||
2411 | case AUDIT_SUBJ_USER: | ||
2412 | case AUDIT_SUBJ_ROLE: | ||
2413 | case AUDIT_SUBJ_TYPE: | ||
2414 | case AUDIT_SUBJ_SEN: | ||
2415 | case AUDIT_SUBJ_CLR: | ||
2416 | case AUDIT_OBJ_USER: | ||
2417 | case AUDIT_OBJ_ROLE: | ||
2418 | case AUDIT_OBJ_TYPE: | ||
2419 | case AUDIT_OBJ_LEV_LOW: | ||
2420 | case AUDIT_OBJ_LEV_HIGH: | ||
2421 | return 1; | ||
2422 | } | ||
2423 | } | ||
2424 | |||
2425 | return 0; | ||
2426 | } | ||
2427 | |||
2428 | int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule, | ||
2402 | struct audit_context *actx) | 2429 | struct audit_context *actx) |
2403 | { | 2430 | { |
2404 | struct context *ctxt; | 2431 | struct context *ctxt; |
2405 | struct mls_level *level; | 2432 | struct mls_level *level; |
2433 | struct selinux_audit_rule *rule = vrule; | ||
2406 | int match = 0; | 2434 | int match = 0; |
2407 | 2435 | ||
2408 | if (!rule) { | 2436 | if (!rule) { |
@@ -2509,7 +2537,7 @@ out: | |||
2509 | return match; | 2537 | return match; |
2510 | } | 2538 | } |
2511 | 2539 | ||
2512 | static int (*aurule_callback)(void) = NULL; | 2540 | static int (*aurule_callback)(void) = audit_update_lsm_rules; |
2513 | 2541 | ||
2514 | static int aurule_avc_callback(u32 event, u32 ssid, u32 tsid, | 2542 | static int aurule_avc_callback(u32 event, u32 ssid, u32 tsid, |
2515 | u16 class, u32 perms, u32 *retained) | 2543 | u16 class, u32 perms, u32 *retained) |
@@ -2534,11 +2562,6 @@ static int __init aurule_init(void) | |||
2534 | } | 2562 | } |
2535 | __initcall(aurule_init); | 2563 | __initcall(aurule_init); |
2536 | 2564 | ||
2537 | void selinux_audit_set_callback(int (*callback)(void)) | ||
2538 | { | ||
2539 | aurule_callback = callback; | ||
2540 | } | ||
2541 | |||
2542 | #ifdef CONFIG_NETLABEL | 2565 | #ifdef CONFIG_NETLABEL |
2543 | /** | 2566 | /** |
2544 | * security_netlbl_cache_add - Add an entry to the NetLabel cache | 2567 | * security_netlbl_cache_add - Add an entry to the NetLabel cache |
diff --git a/security/smack/smack.h b/security/smack/smack.h index 62c1e982849d..4a4477f5afdc 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h | |||
@@ -15,6 +15,7 @@ | |||
15 | 15 | ||
16 | #include <linux/capability.h> | 16 | #include <linux/capability.h> |
17 | #include <linux/spinlock.h> | 17 | #include <linux/spinlock.h> |
18 | #include <linux/security.h> | ||
18 | #include <net/netlabel.h> | 19 | #include <net/netlabel.h> |
19 | 20 | ||
20 | /* | 21 | /* |
@@ -187,6 +188,7 @@ extern struct smack_known smack_known_star; | |||
187 | extern struct smack_known smack_known_unset; | 188 | extern struct smack_known smack_known_unset; |
188 | 189 | ||
189 | extern struct smk_list_entry *smack_list; | 190 | extern struct smk_list_entry *smack_list; |
191 | extern struct security_operations smack_ops; | ||
190 | 192 | ||
191 | /* | 193 | /* |
192 | * Stricly for CIPSO level manipulation. | 194 | * Stricly for CIPSO level manipulation. |
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index e2d6f7cd9254..93f5b0ce662a 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
@@ -2424,7 +2424,9 @@ static void smack_release_secctx(char *secdata, u32 seclen) | |||
2424 | { | 2424 | { |
2425 | } | 2425 | } |
2426 | 2426 | ||
2427 | static struct security_operations smack_ops = { | 2427 | struct security_operations smack_ops = { |
2428 | .name = "smack", | ||
2429 | |||
2428 | .ptrace = smack_ptrace, | 2430 | .ptrace = smack_ptrace, |
2429 | .capget = cap_capget, | 2431 | .capget = cap_capget, |
2430 | .capset_check = cap_capset_check, | 2432 | .capset_check = cap_capset_check, |
@@ -2557,6 +2559,9 @@ static struct security_operations smack_ops = { | |||
2557 | */ | 2559 | */ |
2558 | static __init int smack_init(void) | 2560 | static __init int smack_init(void) |
2559 | { | 2561 | { |
2562 | if (!security_module_enable(&smack_ops)) | ||
2563 | return 0; | ||
2564 | |||
2560 | printk(KERN_INFO "Smack: Initializing.\n"); | 2565 | printk(KERN_INFO "Smack: Initializing.\n"); |
2561 | 2566 | ||
2562 | /* | 2567 | /* |
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index cfae8afcc262..6ba283783b70 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c | |||
@@ -965,12 +965,21 @@ static struct vfsmount *smackfs_mount; | |||
965 | * | 965 | * |
966 | * register the smackfs | 966 | * register the smackfs |
967 | * | 967 | * |
968 | * Returns 0 unless the registration fails. | 968 | * Do not register smackfs if Smack wasn't enabled |
969 | * on boot. We can not put this method normally under the | ||
970 | * smack_init() code path since the security subsystem get | ||
971 | * initialized before the vfs caches. | ||
972 | * | ||
973 | * Returns true if we were not chosen on boot or if | ||
974 | * we were chosen and filesystem registration succeeded. | ||
969 | */ | 975 | */ |
970 | static int __init init_smk_fs(void) | 976 | static int __init init_smk_fs(void) |
971 | { | 977 | { |
972 | int err; | 978 | int err; |
973 | 979 | ||
980 | if (!security_module_enable(&smack_ops)) | ||
981 | return 0; | ||
982 | |||
974 | err = register_filesystem(&smk_fs_type); | 983 | err = register_filesystem(&smk_fs_type); |
975 | if (!err) { | 984 | if (!err) { |
976 | smackfs_mount = kern_mount(&smk_fs_type); | 985 | smackfs_mount = kern_mount(&smk_fs_type); |