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 | |
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
-rw-r--r-- | Documentation/kernel-parameters.txt | 6 | ||||
-rw-r--r-- | include/linux/audit.h | 29 | ||||
-rw-r--r-- | include/linux/security.h | 114 | ||||
-rw-r--r-- | include/linux/selinux.h | 134 | ||||
-rw-r--r-- | kernel/audit.c | 24 | ||||
-rw-r--r-- | kernel/audit.h | 25 | ||||
-rw-r--r-- | kernel/auditfilter.c | 99 | ||||
-rw-r--r-- | kernel/auditsc.c | 74 | ||||
-rw-r--r-- | net/netlink/af_netlink.c | 3 | ||||
-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 |
18 files changed, 503 insertions, 335 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 256a2162503c..4b0f1ae31a4c 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -366,6 +366,12 @@ and is between 256 and 4096 characters. It is defined in the file | |||
366 | possible to determine what the correct size should be. | 366 | possible to determine what the correct size should be. |
367 | This option provides an override for these situations. | 367 | This option provides an override for these situations. |
368 | 368 | ||
369 | security= [SECURITY] Choose a security module to enable at boot. | ||
370 | If this boot parameter is not specified, only the first | ||
371 | security module asking for security registration will be | ||
372 | loaded. An invalid security module name will be treated | ||
373 | as if no module has been chosen. | ||
374 | |||
369 | capability.disable= | 375 | capability.disable= |
370 | [SECURITY] Disable capabilities. This would normally | 376 | [SECURITY] Disable capabilities. This would normally |
371 | be used only if an alternative security model is to be | 377 | be used only if an alternative security model is to be |
diff --git a/include/linux/audit.h b/include/linux/audit.h index 2af9ec025015..4ccb048cae1d 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h | |||
@@ -353,6 +353,33 @@ struct netlink_skb_parms; | |||
353 | struct linux_binprm; | 353 | struct linux_binprm; |
354 | struct mq_attr; | 354 | struct mq_attr; |
355 | struct mqstat; | 355 | struct mqstat; |
356 | struct audit_watch; | ||
357 | struct audit_tree; | ||
358 | |||
359 | struct audit_krule { | ||
360 | int vers_ops; | ||
361 | u32 flags; | ||
362 | u32 listnr; | ||
363 | u32 action; | ||
364 | u32 mask[AUDIT_BITMASK_SIZE]; | ||
365 | u32 buflen; /* for data alloc on list rules */ | ||
366 | u32 field_count; | ||
367 | char *filterkey; /* ties events to rules */ | ||
368 | struct audit_field *fields; | ||
369 | struct audit_field *arch_f; /* quick access to arch field */ | ||
370 | struct audit_field *inode_f; /* quick access to an inode field */ | ||
371 | struct audit_watch *watch; /* associated watch */ | ||
372 | struct audit_tree *tree; /* associated watched tree */ | ||
373 | struct list_head rlist; /* entry in audit_{watch,tree}.rules list */ | ||
374 | }; | ||
375 | |||
376 | struct audit_field { | ||
377 | u32 type; | ||
378 | u32 val; | ||
379 | u32 op; | ||
380 | char *lsm_str; | ||
381 | void *lsm_rule; | ||
382 | }; | ||
356 | 383 | ||
357 | #define AUDITSC_INVALID 0 | 384 | #define AUDITSC_INVALID 0 |
358 | #define AUDITSC_SUCCESS 1 | 385 | #define AUDITSC_SUCCESS 1 |
@@ -536,6 +563,8 @@ extern void audit_log_d_path(struct audit_buffer *ab, | |||
536 | const char *prefix, | 563 | const char *prefix, |
537 | struct path *path); | 564 | struct path *path); |
538 | extern void audit_log_lost(const char *message); | 565 | extern void audit_log_lost(const char *message); |
566 | extern int audit_update_lsm_rules(void); | ||
567 | |||
539 | /* Private API (for audit.c only) */ | 568 | /* Private API (for audit.c only) */ |
540 | extern int audit_filter_user(struct netlink_skb_parms *cb, int type); | 569 | extern int audit_filter_user(struct netlink_skb_parms *cb, int type); |
541 | extern int audit_filter_type(int type); | 570 | extern int audit_filter_type(int type); |
diff --git a/include/linux/security.h b/include/linux/security.h index f5eb9ff47ac5..fea1f4aa4dd5 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
@@ -36,7 +36,11 @@ | |||
36 | 36 | ||
37 | extern unsigned securebits; | 37 | extern unsigned securebits; |
38 | 38 | ||
39 | /* Maximum number of letters for an LSM name string */ | ||
40 | #define SECURITY_NAME_MAX 10 | ||
41 | |||
39 | struct ctl_table; | 42 | struct ctl_table; |
43 | struct audit_krule; | ||
40 | 44 | ||
41 | /* | 45 | /* |
42 | * These functions are in security/capability.c and are used | 46 | * These functions are in security/capability.c and are used |
@@ -136,6 +140,12 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) | |||
136 | /** | 140 | /** |
137 | * struct security_operations - main security structure | 141 | * struct security_operations - main security structure |
138 | * | 142 | * |
143 | * Security module identifier. | ||
144 | * | ||
145 | * @name: | ||
146 | * A string that acts as a unique identifeir for the LSM with max number | ||
147 | * of characters = SECURITY_NAME_MAX. | ||
148 | * | ||
139 | * Security hooks for program execution operations. | 149 | * Security hooks for program execution operations. |
140 | * | 150 | * |
141 | * @bprm_alloc_security: | 151 | * @bprm_alloc_security: |
@@ -468,6 +478,11 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) | |||
468 | * @dentry is the dentry being changed. | 478 | * @dentry is the dentry being changed. |
469 | * Return 0 on success. If error is returned, then the operation | 479 | * Return 0 on success. If error is returned, then the operation |
470 | * causing setuid bit removal is failed. | 480 | * causing setuid bit removal is failed. |
481 | * @inode_getsecid: | ||
482 | * Get the secid associated with the node. | ||
483 | * @inode contains a pointer to the inode. | ||
484 | * @secid contains a pointer to the location where result will be saved. | ||
485 | * In case of failure, @secid will be set to zero. | ||
471 | * | 486 | * |
472 | * Security hooks for file operations | 487 | * Security hooks for file operations |
473 | * | 488 | * |
@@ -636,6 +651,8 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) | |||
636 | * @task_getsecid: | 651 | * @task_getsecid: |
637 | * Retrieve the security identifier of the process @p. | 652 | * Retrieve the security identifier of the process @p. |
638 | * @p contains the task_struct for the process and place is into @secid. | 653 | * @p contains the task_struct for the process and place is into @secid. |
654 | * In case of failure, @secid will be set to zero. | ||
655 | * | ||
639 | * @task_setgroups: | 656 | * @task_setgroups: |
640 | * Check permission before setting the supplementary group set of the | 657 | * Check permission before setting the supplementary group set of the |
641 | * current process. | 658 | * current process. |
@@ -997,6 +1014,11 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) | |||
997 | * @ipcp contains the kernel IPC permission structure | 1014 | * @ipcp contains the kernel IPC permission structure |
998 | * @flag contains the desired (requested) permission set | 1015 | * @flag contains the desired (requested) permission set |
999 | * Return 0 if permission is granted. | 1016 | * Return 0 if permission is granted. |
1017 | * @ipc_getsecid: | ||
1018 | * Get the secid associated with the ipc object. | ||
1019 | * @ipcp contains the kernel IPC permission structure. | ||
1020 | * @secid contains a pointer to the location where result will be saved. | ||
1021 | * In case of failure, @secid will be set to zero. | ||
1000 | * | 1022 | * |
1001 | * Security hooks for individual messages held in System V IPC message queues | 1023 | * Security hooks for individual messages held in System V IPC message queues |
1002 | * @msg_msg_alloc_security: | 1024 | * @msg_msg_alloc_security: |
@@ -1223,9 +1245,42 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) | |||
1223 | * @secdata contains the security context. | 1245 | * @secdata contains the security context. |
1224 | * @seclen contains the length of the security context. | 1246 | * @seclen contains the length of the security context. |
1225 | * | 1247 | * |
1248 | * Security hooks for Audit | ||
1249 | * | ||
1250 | * @audit_rule_init: | ||
1251 | * Allocate and initialize an LSM audit rule structure. | ||
1252 | * @field contains the required Audit action. Fields flags are defined in include/linux/audit.h | ||
1253 | * @op contains the operator the rule uses. | ||
1254 | * @rulestr contains the context where the rule will be applied to. | ||
1255 | * @lsmrule contains a pointer to receive the result. | ||
1256 | * Return 0 if @lsmrule has been successfully set, | ||
1257 | * -EINVAL in case of an invalid rule. | ||
1258 | * | ||
1259 | * @audit_rule_known: | ||
1260 | * Specifies whether given @rule contains any fields related to current LSM. | ||
1261 | * @rule contains the audit rule of interest. | ||
1262 | * Return 1 in case of relation found, 0 otherwise. | ||
1263 | * | ||
1264 | * @audit_rule_match: | ||
1265 | * Determine if given @secid matches a rule previously approved | ||
1266 | * by @audit_rule_known. | ||
1267 | * @secid contains the security id in question. | ||
1268 | * @field contains the field which relates to current LSM. | ||
1269 | * @op contains the operator that will be used for matching. | ||
1270 | * @rule points to the audit rule that will be checked against. | ||
1271 | * @actx points to the audit context associated with the check. | ||
1272 | * Return 1 if secid matches the rule, 0 if it does not, -ERRNO on failure. | ||
1273 | * | ||
1274 | * @audit_rule_free: | ||
1275 | * Deallocate the LSM audit rule structure previously allocated by | ||
1276 | * audit_rule_init. | ||
1277 | * @rule contains the allocated rule | ||
1278 | * | ||
1226 | * This is the main security structure. | 1279 | * This is the main security structure. |
1227 | */ | 1280 | */ |
1228 | struct security_operations { | 1281 | struct security_operations { |
1282 | char name[SECURITY_NAME_MAX + 1]; | ||
1283 | |||
1229 | int (*ptrace) (struct task_struct * parent, struct task_struct * child); | 1284 | int (*ptrace) (struct task_struct * parent, struct task_struct * child); |
1230 | int (*capget) (struct task_struct * target, | 1285 | int (*capget) (struct task_struct * target, |
1231 | kernel_cap_t * effective, | 1286 | kernel_cap_t * effective, |
@@ -1317,6 +1372,7 @@ struct security_operations { | |||
1317 | int (*inode_getsecurity)(const struct inode *inode, const char *name, void **buffer, bool alloc); | 1372 | int (*inode_getsecurity)(const struct inode *inode, const char *name, void **buffer, bool alloc); |
1318 | int (*inode_setsecurity)(struct inode *inode, const char *name, const void *value, size_t size, int flags); | 1373 | int (*inode_setsecurity)(struct inode *inode, const char *name, const void *value, size_t size, int flags); |
1319 | int (*inode_listsecurity)(struct inode *inode, char *buffer, size_t buffer_size); | 1374 | int (*inode_listsecurity)(struct inode *inode, char *buffer, size_t buffer_size); |
1375 | void (*inode_getsecid)(const struct inode *inode, u32 *secid); | ||
1320 | 1376 | ||
1321 | int (*file_permission) (struct file * file, int mask); | 1377 | int (*file_permission) (struct file * file, int mask); |
1322 | int (*file_alloc_security) (struct file * file); | 1378 | int (*file_alloc_security) (struct file * file); |
@@ -1369,6 +1425,7 @@ struct security_operations { | |||
1369 | void (*task_to_inode)(struct task_struct *p, struct inode *inode); | 1425 | void (*task_to_inode)(struct task_struct *p, struct inode *inode); |
1370 | 1426 | ||
1371 | int (*ipc_permission) (struct kern_ipc_perm * ipcp, short flag); | 1427 | int (*ipc_permission) (struct kern_ipc_perm * ipcp, short flag); |
1428 | void (*ipc_getsecid) (struct kern_ipc_perm *ipcp, u32 *secid); | ||
1372 | 1429 | ||
1373 | int (*msg_msg_alloc_security) (struct msg_msg * msg); | 1430 | int (*msg_msg_alloc_security) (struct msg_msg * msg); |
1374 | void (*msg_msg_free_security) (struct msg_msg * msg); | 1431 | void (*msg_msg_free_security) (struct msg_msg * msg); |
@@ -1480,10 +1537,18 @@ struct security_operations { | |||
1480 | 1537 | ||
1481 | #endif /* CONFIG_KEYS */ | 1538 | #endif /* CONFIG_KEYS */ |
1482 | 1539 | ||
1540 | #ifdef CONFIG_AUDIT | ||
1541 | int (*audit_rule_init)(u32 field, u32 op, char *rulestr, void **lsmrule); | ||
1542 | int (*audit_rule_known)(struct audit_krule *krule); | ||
1543 | int (*audit_rule_match)(u32 secid, u32 field, u32 op, void *lsmrule, | ||
1544 | struct audit_context *actx); | ||
1545 | void (*audit_rule_free)(void *lsmrule); | ||
1546 | #endif /* CONFIG_AUDIT */ | ||
1483 | }; | 1547 | }; |
1484 | 1548 | ||
1485 | /* prototypes */ | 1549 | /* prototypes */ |
1486 | extern int security_init (void); | 1550 | extern int security_init (void); |
1551 | extern int security_module_enable(struct security_operations *ops); | ||
1487 | extern int register_security (struct security_operations *ops); | 1552 | extern int register_security (struct security_operations *ops); |
1488 | extern int mod_reg_security (const char *name, struct security_operations *ops); | 1553 | extern int mod_reg_security (const char *name, struct security_operations *ops); |
1489 | extern struct dentry *securityfs_create_file(const char *name, mode_t mode, | 1554 | extern struct dentry *securityfs_create_file(const char *name, mode_t mode, |
@@ -1578,6 +1643,7 @@ int security_inode_killpriv(struct dentry *dentry); | |||
1578 | int security_inode_getsecurity(const struct inode *inode, const char *name, void **buffer, bool alloc); | 1643 | int security_inode_getsecurity(const struct inode *inode, const char *name, void **buffer, bool alloc); |
1579 | int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags); | 1644 | int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags); |
1580 | int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size); | 1645 | int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size); |
1646 | void security_inode_getsecid(const struct inode *inode, u32 *secid); | ||
1581 | int security_file_permission(struct file *file, int mask); | 1647 | int security_file_permission(struct file *file, int mask); |
1582 | int security_file_alloc(struct file *file); | 1648 | int security_file_alloc(struct file *file); |
1583 | void security_file_free(struct file *file); | 1649 | void security_file_free(struct file *file); |
@@ -1622,6 +1688,7 @@ int security_task_prctl(int option, unsigned long arg2, unsigned long arg3, | |||
1622 | void security_task_reparent_to_init(struct task_struct *p); | 1688 | void security_task_reparent_to_init(struct task_struct *p); |
1623 | void security_task_to_inode(struct task_struct *p, struct inode *inode); | 1689 | void security_task_to_inode(struct task_struct *p, struct inode *inode); |
1624 | int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag); | 1690 | int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag); |
1691 | void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid); | ||
1625 | int security_msg_msg_alloc(struct msg_msg *msg); | 1692 | int security_msg_msg_alloc(struct msg_msg *msg); |
1626 | void security_msg_msg_free(struct msg_msg *msg); | 1693 | void security_msg_msg_free(struct msg_msg *msg); |
1627 | int security_msg_queue_alloc(struct msg_queue *msq); | 1694 | int security_msg_queue_alloc(struct msg_queue *msq); |
@@ -2022,6 +2089,11 @@ static inline int security_inode_listsecurity(struct inode *inode, char *buffer, | |||
2022 | return 0; | 2089 | return 0; |
2023 | } | 2090 | } |
2024 | 2091 | ||
2092 | static inline void security_inode_getsecid(const struct inode *inode, u32 *secid) | ||
2093 | { | ||
2094 | *secid = 0; | ||
2095 | } | ||
2096 | |||
2025 | static inline int security_file_permission (struct file *file, int mask) | 2097 | static inline int security_file_permission (struct file *file, int mask) |
2026 | { | 2098 | { |
2027 | return 0; | 2099 | return 0; |
@@ -2137,7 +2209,9 @@ static inline int security_task_getsid (struct task_struct *p) | |||
2137 | } | 2209 | } |
2138 | 2210 | ||
2139 | static inline void security_task_getsecid (struct task_struct *p, u32 *secid) | 2211 | static inline void security_task_getsecid (struct task_struct *p, u32 *secid) |
2140 | { } | 2212 | { |
2213 | *secid = 0; | ||
2214 | } | ||
2141 | 2215 | ||
2142 | static inline int security_task_setgroups (struct group_info *group_info) | 2216 | static inline int security_task_setgroups (struct group_info *group_info) |
2143 | { | 2217 | { |
@@ -2216,6 +2290,11 @@ static inline int security_ipc_permission (struct kern_ipc_perm *ipcp, | |||
2216 | return 0; | 2290 | return 0; |
2217 | } | 2291 | } |
2218 | 2292 | ||
2293 | static inline void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid) | ||
2294 | { | ||
2295 | *secid = 0; | ||
2296 | } | ||
2297 | |||
2219 | static inline int security_msg_msg_alloc (struct msg_msg * msg) | 2298 | static inline int security_msg_msg_alloc (struct msg_msg * msg) |
2220 | { | 2299 | { |
2221 | return 0; | 2300 | return 0; |
@@ -2672,5 +2751,38 @@ static inline int security_key_permission(key_ref_t key_ref, | |||
2672 | #endif | 2751 | #endif |
2673 | #endif /* CONFIG_KEYS */ | 2752 | #endif /* CONFIG_KEYS */ |
2674 | 2753 | ||
2754 | #ifdef CONFIG_AUDIT | ||
2755 | #ifdef CONFIG_SECURITY | ||
2756 | int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule); | ||
2757 | int security_audit_rule_known(struct audit_krule *krule); | ||
2758 | int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule, | ||
2759 | struct audit_context *actx); | ||
2760 | void security_audit_rule_free(void *lsmrule); | ||
2761 | |||
2762 | #else | ||
2763 | |||
2764 | static inline int security_audit_rule_init(u32 field, u32 op, char *rulestr, | ||
2765 | void **lsmrule) | ||
2766 | { | ||
2767 | return 0; | ||
2768 | } | ||
2769 | |||
2770 | static inline int security_audit_rule_known(struct audit_krule *krule) | ||
2771 | { | ||
2772 | return 0; | ||
2773 | } | ||
2774 | |||
2775 | static inline int security_audit_rule_match(u32 secid, u32 field, u32 op, | ||
2776 | void *lsmrule, struct audit_context *actx) | ||
2777 | { | ||
2778 | return 0; | ||
2779 | } | ||
2780 | |||
2781 | static inline void security_audit_rule_free(void *lsmrule) | ||
2782 | { } | ||
2783 | |||
2784 | #endif /* CONFIG_SECURITY */ | ||
2785 | #endif /* CONFIG_AUDIT */ | ||
2786 | |||
2675 | #endif /* ! __LINUX_SECURITY_H */ | 2787 | #endif /* ! __LINUX_SECURITY_H */ |
2676 | 2788 | ||
diff --git a/include/linux/selinux.h b/include/linux/selinux.h index 8c2cc4c02526..20f965d4b041 100644 --- a/include/linux/selinux.h +++ b/include/linux/selinux.h | |||
@@ -16,99 +16,11 @@ | |||
16 | 16 | ||
17 | struct selinux_audit_rule; | 17 | struct selinux_audit_rule; |
18 | struct audit_context; | 18 | struct audit_context; |
19 | struct inode; | ||
20 | struct kern_ipc_perm; | 19 | struct kern_ipc_perm; |
21 | 20 | ||
22 | #ifdef CONFIG_SECURITY_SELINUX | 21 | #ifdef CONFIG_SECURITY_SELINUX |
23 | 22 | ||
24 | /** | 23 | /** |
25 | * selinux_audit_rule_init - alloc/init an selinux audit rule structure. | ||
26 | * @field: the field this rule refers to | ||
27 | * @op: the operater the rule uses | ||
28 | * @rulestr: the text "target" of the rule | ||
29 | * @rule: pointer to the new rule structure returned via this | ||
30 | * | ||
31 | * Returns 0 if successful, -errno if not. On success, the rule structure | ||
32 | * will be allocated internally. The caller must free this structure with | ||
33 | * selinux_audit_rule_free() after use. | ||
34 | */ | ||
35 | int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, | ||
36 | struct selinux_audit_rule **rule); | ||
37 | |||
38 | /** | ||
39 | * selinux_audit_rule_free - free an selinux audit rule structure. | ||
40 | * @rule: pointer to the audit rule to be freed | ||
41 | * | ||
42 | * This will free all memory associated with the given rule. | ||
43 | * If @rule is NULL, no operation is performed. | ||
44 | */ | ||
45 | void selinux_audit_rule_free(struct selinux_audit_rule *rule); | ||
46 | |||
47 | /** | ||
48 | * selinux_audit_rule_match - determine if a context ID matches a rule. | ||
49 | * @sid: the context ID to check | ||
50 | * @field: the field this rule refers to | ||
51 | * @op: the operater the rule uses | ||
52 | * @rule: pointer to the audit rule to check against | ||
53 | * @actx: the audit context (can be NULL) associated with the check | ||
54 | * | ||
55 | * Returns 1 if the context id matches the rule, 0 if it does not, and | ||
56 | * -errno on failure. | ||
57 | */ | ||
58 | int selinux_audit_rule_match(u32 sid, u32 field, u32 op, | ||
59 | struct selinux_audit_rule *rule, | ||
60 | struct audit_context *actx); | ||
61 | |||
62 | /** | ||
63 | * selinux_audit_set_callback - set the callback for policy reloads. | ||
64 | * @callback: the function to call when the policy is reloaded | ||
65 | * | ||
66 | * This sets the function callback function that will update the rules | ||
67 | * upon policy reloads. This callback should rebuild all existing rules | ||
68 | * using selinux_audit_rule_init(). | ||
69 | */ | ||
70 | void selinux_audit_set_callback(int (*callback)(void)); | ||
71 | |||
72 | /** | ||
73 | * selinux_sid_to_string - map a security context ID to a string | ||
74 | * @sid: security context ID to be converted. | ||
75 | * @ctx: address of context string to be returned | ||
76 | * @ctxlen: length of returned context string. | ||
77 | * | ||
78 | * Returns 0 if successful, -errno if not. On success, the context | ||
79 | * string will be allocated internally, and the caller must call | ||
80 | * kfree() on it after use. | ||
81 | */ | ||
82 | int selinux_sid_to_string(u32 sid, char **ctx, u32 *ctxlen); | ||
83 | |||
84 | /** | ||
85 | * selinux_get_inode_sid - get the inode's security context ID | ||
86 | * @inode: inode structure to get the sid from. | ||
87 | * @sid: pointer to security context ID to be filled in. | ||
88 | * | ||
89 | * Returns nothing | ||
90 | */ | ||
91 | void selinux_get_inode_sid(const struct inode *inode, u32 *sid); | ||
92 | |||
93 | /** | ||
94 | * selinux_get_ipc_sid - get the ipc security context ID | ||
95 | * @ipcp: ipc structure to get the sid from. | ||
96 | * @sid: pointer to security context ID to be filled in. | ||
97 | * | ||
98 | * Returns nothing | ||
99 | */ | ||
100 | void selinux_get_ipc_sid(const struct kern_ipc_perm *ipcp, u32 *sid); | ||
101 | |||
102 | /** | ||
103 | * selinux_get_task_sid - return the SID of task | ||
104 | * @tsk: the task whose SID will be returned | ||
105 | * @sid: pointer to security context ID to be filled in. | ||
106 | * | ||
107 | * Returns nothing | ||
108 | */ | ||
109 | void selinux_get_task_sid(struct task_struct *tsk, u32 *sid); | ||
110 | |||
111 | /** | ||
112 | * selinux_string_to_sid - map a security context string to a security ID | 24 | * selinux_string_to_sid - map a security context string to a security ID |
113 | * @str: the security context string to be mapped | 25 | * @str: the security context string to be mapped |
114 | * @sid: ID value returned via this. | 26 | * @sid: ID value returned via this. |
@@ -151,52 +63,6 @@ void selinux_secmark_refcount_inc(void); | |||
151 | void selinux_secmark_refcount_dec(void); | 63 | void selinux_secmark_refcount_dec(void); |
152 | #else | 64 | #else |
153 | 65 | ||
154 | static inline int selinux_audit_rule_init(u32 field, u32 op, | ||
155 | char *rulestr, | ||
156 | struct selinux_audit_rule **rule) | ||
157 | { | ||
158 | return -EOPNOTSUPP; | ||
159 | } | ||
160 | |||
161 | static inline void selinux_audit_rule_free(struct selinux_audit_rule *rule) | ||
162 | { | ||
163 | return; | ||
164 | } | ||
165 | |||
166 | static inline int selinux_audit_rule_match(u32 sid, u32 field, u32 op, | ||
167 | struct selinux_audit_rule *rule, | ||
168 | struct audit_context *actx) | ||
169 | { | ||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | static inline void selinux_audit_set_callback(int (*callback)(void)) | ||
174 | { | ||
175 | return; | ||
176 | } | ||
177 | |||
178 | static inline int selinux_sid_to_string(u32 sid, char **ctx, u32 *ctxlen) | ||
179 | { | ||
180 | *ctx = NULL; | ||
181 | *ctxlen = 0; | ||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | static inline void selinux_get_inode_sid(const struct inode *inode, u32 *sid) | ||
186 | { | ||
187 | *sid = 0; | ||
188 | } | ||
189 | |||
190 | static inline void selinux_get_ipc_sid(const struct kern_ipc_perm *ipcp, u32 *sid) | ||
191 | { | ||
192 | *sid = 0; | ||
193 | } | ||
194 | |||
195 | static inline void selinux_get_task_sid(struct task_struct *tsk, u32 *sid) | ||
196 | { | ||
197 | *sid = 0; | ||
198 | } | ||
199 | |||
200 | static inline int selinux_string_to_sid(const char *str, u32 *sid) | 66 | static inline int selinux_string_to_sid(const char *str, u32 *sid) |
201 | { | 67 | { |
202 | *sid = 0; | 68 | *sid = 0; |
diff --git a/kernel/audit.c b/kernel/audit.c index b782b046543d..a7b16086d36f 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
@@ -21,7 +21,7 @@ | |||
21 | * | 21 | * |
22 | * Written by Rickard E. (Rik) Faith <faith@redhat.com> | 22 | * Written by Rickard E. (Rik) Faith <faith@redhat.com> |
23 | * | 23 | * |
24 | * Goals: 1) Integrate fully with SELinux. | 24 | * Goals: 1) Integrate fully with Security Modules. |
25 | * 2) Minimal run-time overhead: | 25 | * 2) Minimal run-time overhead: |
26 | * a) Minimal when syscall auditing is disabled (audit_enable=0). | 26 | * a) Minimal when syscall auditing is disabled (audit_enable=0). |
27 | * b) Small when syscall auditing is enabled and no audit record | 27 | * b) Small when syscall auditing is enabled and no audit record |
@@ -55,7 +55,6 @@ | |||
55 | #include <net/netlink.h> | 55 | #include <net/netlink.h> |
56 | #include <linux/skbuff.h> | 56 | #include <linux/skbuff.h> |
57 | #include <linux/netlink.h> | 57 | #include <linux/netlink.h> |
58 | #include <linux/selinux.h> | ||
59 | #include <linux/inotify.h> | 58 | #include <linux/inotify.h> |
60 | #include <linux/freezer.h> | 59 | #include <linux/freezer.h> |
61 | #include <linux/tty.h> | 60 | #include <linux/tty.h> |
@@ -265,13 +264,13 @@ static int audit_log_config_change(char *function_name, int new, int old, | |||
265 | char *ctx = NULL; | 264 | char *ctx = NULL; |
266 | u32 len; | 265 | u32 len; |
267 | 266 | ||
268 | rc = selinux_sid_to_string(sid, &ctx, &len); | 267 | rc = security_secid_to_secctx(sid, &ctx, &len); |
269 | if (rc) { | 268 | if (rc) { |
270 | audit_log_format(ab, " sid=%u", sid); | 269 | audit_log_format(ab, " sid=%u", sid); |
271 | allow_changes = 0; /* Something weird, deny request */ | 270 | allow_changes = 0; /* Something weird, deny request */ |
272 | } else { | 271 | } else { |
273 | audit_log_format(ab, " subj=%s", ctx); | 272 | audit_log_format(ab, " subj=%s", ctx); |
274 | kfree(ctx); | 273 | security_release_secctx(ctx, len); |
275 | } | 274 | } |
276 | } | 275 | } |
277 | audit_log_format(ab, " res=%d", allow_changes); | 276 | audit_log_format(ab, " res=%d", allow_changes); |
@@ -550,12 +549,13 @@ static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type, | |||
550 | audit_log_format(*ab, "user pid=%d uid=%u auid=%u", | 549 | audit_log_format(*ab, "user pid=%d uid=%u auid=%u", |
551 | pid, uid, auid); | 550 | pid, uid, auid); |
552 | if (sid) { | 551 | if (sid) { |
553 | rc = selinux_sid_to_string(sid, &ctx, &len); | 552 | rc = security_secid_to_secctx(sid, &ctx, &len); |
554 | if (rc) | 553 | if (rc) |
555 | audit_log_format(*ab, " ssid=%u", sid); | 554 | audit_log_format(*ab, " ssid=%u", sid); |
556 | else | 555 | else { |
557 | audit_log_format(*ab, " subj=%s", ctx); | 556 | audit_log_format(*ab, " subj=%s", ctx); |
558 | kfree(ctx); | 557 | security_release_secctx(ctx, len); |
558 | } | ||
559 | } | 559 | } |
560 | 560 | ||
561 | return rc; | 561 | return rc; |
@@ -758,18 +758,18 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
758 | break; | 758 | break; |
759 | } | 759 | } |
760 | case AUDIT_SIGNAL_INFO: | 760 | case AUDIT_SIGNAL_INFO: |
761 | err = selinux_sid_to_string(audit_sig_sid, &ctx, &len); | 761 | err = security_secid_to_secctx(audit_sig_sid, &ctx, &len); |
762 | if (err) | 762 | if (err) |
763 | return err; | 763 | return err; |
764 | sig_data = kmalloc(sizeof(*sig_data) + len, GFP_KERNEL); | 764 | sig_data = kmalloc(sizeof(*sig_data) + len, GFP_KERNEL); |
765 | if (!sig_data) { | 765 | if (!sig_data) { |
766 | kfree(ctx); | 766 | security_release_secctx(ctx, len); |
767 | return -ENOMEM; | 767 | return -ENOMEM; |
768 | } | 768 | } |
769 | sig_data->uid = audit_sig_uid; | 769 | sig_data->uid = audit_sig_uid; |
770 | sig_data->pid = audit_sig_pid; | 770 | sig_data->pid = audit_sig_pid; |
771 | memcpy(sig_data->ctx, ctx, len); | 771 | memcpy(sig_data->ctx, ctx, len); |
772 | kfree(ctx); | 772 | security_release_secctx(ctx, len); |
773 | audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_SIGNAL_INFO, | 773 | audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_SIGNAL_INFO, |
774 | 0, 0, sig_data, sizeof(*sig_data) + len); | 774 | 0, 0, sig_data, sizeof(*sig_data) + len); |
775 | kfree(sig_data); | 775 | kfree(sig_data); |
@@ -881,10 +881,6 @@ static int __init audit_init(void) | |||
881 | audit_enabled = audit_default; | 881 | audit_enabled = audit_default; |
882 | audit_ever_enabled |= !!audit_default; | 882 | audit_ever_enabled |= !!audit_default; |
883 | 883 | ||
884 | /* Register the callback with selinux. This callback will be invoked | ||
885 | * when a new policy is loaded. */ | ||
886 | selinux_audit_set_callback(&selinux_audit_rule_update); | ||
887 | |||
888 | audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized"); | 884 | audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized"); |
889 | 885 | ||
890 | #ifdef CONFIG_AUDITSYSCALL | 886 | #ifdef CONFIG_AUDITSYSCALL |
diff --git a/kernel/audit.h b/kernel/audit.h index 2554bd524fd1..3cfc54ee3e1f 100644 --- a/kernel/audit.h +++ b/kernel/audit.h | |||
@@ -65,34 +65,9 @@ struct audit_watch { | |||
65 | struct list_head rules; /* associated rules */ | 65 | struct list_head rules; /* associated rules */ |
66 | }; | 66 | }; |
67 | 67 | ||
68 | struct audit_field { | ||
69 | u32 type; | ||
70 | u32 val; | ||
71 | u32 op; | ||
72 | char *se_str; | ||
73 | struct selinux_audit_rule *se_rule; | ||
74 | }; | ||
75 | |||
76 | struct audit_tree; | 68 | struct audit_tree; |
77 | struct audit_chunk; | 69 | struct audit_chunk; |
78 | 70 | ||
79 | struct audit_krule { | ||
80 | int vers_ops; | ||
81 | u32 flags; | ||
82 | u32 listnr; | ||
83 | u32 action; | ||
84 | u32 mask[AUDIT_BITMASK_SIZE]; | ||
85 | u32 buflen; /* for data alloc on list rules */ | ||
86 | u32 field_count; | ||
87 | char *filterkey; /* ties events to rules */ | ||
88 | struct audit_field *fields; | ||
89 | struct audit_field *arch_f; /* quick access to arch field */ | ||
90 | struct audit_field *inode_f; /* quick access to an inode field */ | ||
91 | struct audit_watch *watch; /* associated watch */ | ||
92 | struct audit_tree *tree; /* associated watched tree */ | ||
93 | struct list_head rlist; /* entry in audit_{watch,tree}.rules list */ | ||
94 | }; | ||
95 | |||
96 | struct audit_entry { | 71 | struct audit_entry { |
97 | struct list_head list; | 72 | struct list_head list; |
98 | struct rcu_head rcu; | 73 | struct rcu_head rcu; |
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 2f2914b7cc30..28fef6bf8534 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c | |||
@@ -28,7 +28,7 @@ | |||
28 | #include <linux/netlink.h> | 28 | #include <linux/netlink.h> |
29 | #include <linux/sched.h> | 29 | #include <linux/sched.h> |
30 | #include <linux/inotify.h> | 30 | #include <linux/inotify.h> |
31 | #include <linux/selinux.h> | 31 | #include <linux/security.h> |
32 | #include "audit.h" | 32 | #include "audit.h" |
33 | 33 | ||
34 | /* | 34 | /* |
@@ -38,7 +38,7 @@ | |||
38 | * Synchronizes writes and blocking reads of audit's filterlist | 38 | * Synchronizes writes and blocking reads of audit's filterlist |
39 | * data. Rcu is used to traverse the filterlist and access | 39 | * data. Rcu is used to traverse the filterlist and access |
40 | * contents of structs audit_entry, audit_watch and opaque | 40 | * contents of structs audit_entry, audit_watch and opaque |
41 | * selinux rules during filtering. If modified, these structures | 41 | * LSM rules during filtering. If modified, these structures |
42 | * must be copied and replace their counterparts in the filterlist. | 42 | * must be copied and replace their counterparts in the filterlist. |
43 | * An audit_parent struct is not accessed during filtering, so may | 43 | * An audit_parent struct is not accessed during filtering, so may |
44 | * be written directly provided audit_filter_mutex is held. | 44 | * be written directly provided audit_filter_mutex is held. |
@@ -139,8 +139,8 @@ static inline void audit_free_rule(struct audit_entry *e) | |||
139 | if (e->rule.fields) | 139 | if (e->rule.fields) |
140 | for (i = 0; i < e->rule.field_count; i++) { | 140 | for (i = 0; i < e->rule.field_count; i++) { |
141 | struct audit_field *f = &e->rule.fields[i]; | 141 | struct audit_field *f = &e->rule.fields[i]; |
142 | kfree(f->se_str); | 142 | kfree(f->lsm_str); |
143 | selinux_audit_rule_free(f->se_rule); | 143 | security_audit_rule_free(f->lsm_rule); |
144 | } | 144 | } |
145 | kfree(e->rule.fields); | 145 | kfree(e->rule.fields); |
146 | kfree(e->rule.filterkey); | 146 | kfree(e->rule.filterkey); |
@@ -554,8 +554,8 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, | |||
554 | f->op = data->fieldflags[i] & AUDIT_OPERATORS; | 554 | f->op = data->fieldflags[i] & AUDIT_OPERATORS; |
555 | f->type = data->fields[i]; | 555 | f->type = data->fields[i]; |
556 | f->val = data->values[i]; | 556 | f->val = data->values[i]; |
557 | f->se_str = NULL; | 557 | f->lsm_str = NULL; |
558 | f->se_rule = NULL; | 558 | f->lsm_rule = NULL; |
559 | switch(f->type) { | 559 | switch(f->type) { |
560 | case AUDIT_PID: | 560 | case AUDIT_PID: |
561 | case AUDIT_UID: | 561 | case AUDIT_UID: |
@@ -597,12 +597,12 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, | |||
597 | goto exit_free; | 597 | goto exit_free; |
598 | entry->rule.buflen += f->val; | 598 | entry->rule.buflen += f->val; |
599 | 599 | ||
600 | err = selinux_audit_rule_init(f->type, f->op, str, | 600 | err = security_audit_rule_init(f->type, f->op, str, |
601 | &f->se_rule); | 601 | (void **)&f->lsm_rule); |
602 | /* Keep currently invalid fields around in case they | 602 | /* Keep currently invalid fields around in case they |
603 | * become valid after a policy reload. */ | 603 | * become valid after a policy reload. */ |
604 | if (err == -EINVAL) { | 604 | if (err == -EINVAL) { |
605 | printk(KERN_WARNING "audit rule for selinux " | 605 | printk(KERN_WARNING "audit rule for LSM " |
606 | "\'%s\' is invalid\n", str); | 606 | "\'%s\' is invalid\n", str); |
607 | err = 0; | 607 | err = 0; |
608 | } | 608 | } |
@@ -610,7 +610,7 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, | |||
610 | kfree(str); | 610 | kfree(str); |
611 | goto exit_free; | 611 | goto exit_free; |
612 | } else | 612 | } else |
613 | f->se_str = str; | 613 | f->lsm_str = str; |
614 | break; | 614 | break; |
615 | case AUDIT_WATCH: | 615 | case AUDIT_WATCH: |
616 | str = audit_unpack_string(&bufp, &remain, f->val); | 616 | str = audit_unpack_string(&bufp, &remain, f->val); |
@@ -754,7 +754,7 @@ static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule) | |||
754 | case AUDIT_OBJ_LEV_LOW: | 754 | case AUDIT_OBJ_LEV_LOW: |
755 | case AUDIT_OBJ_LEV_HIGH: | 755 | case AUDIT_OBJ_LEV_HIGH: |
756 | data->buflen += data->values[i] = | 756 | data->buflen += data->values[i] = |
757 | audit_pack_string(&bufp, f->se_str); | 757 | audit_pack_string(&bufp, f->lsm_str); |
758 | break; | 758 | break; |
759 | case AUDIT_WATCH: | 759 | case AUDIT_WATCH: |
760 | data->buflen += data->values[i] = | 760 | data->buflen += data->values[i] = |
@@ -806,7 +806,7 @@ static int audit_compare_rule(struct audit_krule *a, struct audit_krule *b) | |||
806 | case AUDIT_OBJ_TYPE: | 806 | case AUDIT_OBJ_TYPE: |
807 | case AUDIT_OBJ_LEV_LOW: | 807 | case AUDIT_OBJ_LEV_LOW: |
808 | case AUDIT_OBJ_LEV_HIGH: | 808 | case AUDIT_OBJ_LEV_HIGH: |
809 | if (strcmp(a->fields[i].se_str, b->fields[i].se_str)) | 809 | if (strcmp(a->fields[i].lsm_str, b->fields[i].lsm_str)) |
810 | return 1; | 810 | return 1; |
811 | break; | 811 | break; |
812 | case AUDIT_WATCH: | 812 | case AUDIT_WATCH: |
@@ -862,28 +862,28 @@ out: | |||
862 | return new; | 862 | return new; |
863 | } | 863 | } |
864 | 864 | ||
865 | /* Duplicate selinux field information. The se_rule is opaque, so must be | 865 | /* Duplicate LSM field information. The lsm_rule is opaque, so must be |
866 | * re-initialized. */ | 866 | * re-initialized. */ |
867 | static inline int audit_dupe_selinux_field(struct audit_field *df, | 867 | static inline int audit_dupe_lsm_field(struct audit_field *df, |
868 | struct audit_field *sf) | 868 | struct audit_field *sf) |
869 | { | 869 | { |
870 | int ret = 0; | 870 | int ret = 0; |
871 | char *se_str; | 871 | char *lsm_str; |
872 | 872 | ||
873 | /* our own copy of se_str */ | 873 | /* our own copy of lsm_str */ |
874 | se_str = kstrdup(sf->se_str, GFP_KERNEL); | 874 | lsm_str = kstrdup(sf->lsm_str, GFP_KERNEL); |
875 | if (unlikely(!se_str)) | 875 | if (unlikely(!lsm_str)) |
876 | return -ENOMEM; | 876 | return -ENOMEM; |
877 | df->se_str = se_str; | 877 | df->lsm_str = lsm_str; |
878 | 878 | ||
879 | /* our own (refreshed) copy of se_rule */ | 879 | /* our own (refreshed) copy of lsm_rule */ |
880 | ret = selinux_audit_rule_init(df->type, df->op, df->se_str, | 880 | ret = security_audit_rule_init(df->type, df->op, df->lsm_str, |
881 | &df->se_rule); | 881 | (void **)&df->lsm_rule); |
882 | /* Keep currently invalid fields around in case they | 882 | /* Keep currently invalid fields around in case they |
883 | * become valid after a policy reload. */ | 883 | * become valid after a policy reload. */ |
884 | if (ret == -EINVAL) { | 884 | if (ret == -EINVAL) { |
885 | printk(KERN_WARNING "audit rule for selinux \'%s\' is " | 885 | printk(KERN_WARNING "audit rule for LSM \'%s\' is " |
886 | "invalid\n", df->se_str); | 886 | "invalid\n", df->lsm_str); |
887 | ret = 0; | 887 | ret = 0; |
888 | } | 888 | } |
889 | 889 | ||
@@ -891,7 +891,7 @@ static inline int audit_dupe_selinux_field(struct audit_field *df, | |||
891 | } | 891 | } |
892 | 892 | ||
893 | /* Duplicate an audit rule. This will be a deep copy with the exception | 893 | /* Duplicate an audit rule. This will be a deep copy with the exception |
894 | * of the watch - that pointer is carried over. The selinux specific fields | 894 | * of the watch - that pointer is carried over. The LSM specific fields |
895 | * will be updated in the copy. The point is to be able to replace the old | 895 | * will be updated in the copy. The point is to be able to replace the old |
896 | * rule with the new rule in the filterlist, then free the old rule. | 896 | * rule with the new rule in the filterlist, then free the old rule. |
897 | * The rlist element is undefined; list manipulations are handled apart from | 897 | * The rlist element is undefined; list manipulations are handled apart from |
@@ -930,7 +930,7 @@ static struct audit_entry *audit_dupe_rule(struct audit_krule *old, | |||
930 | new->tree = old->tree; | 930 | new->tree = old->tree; |
931 | memcpy(new->fields, old->fields, sizeof(struct audit_field) * fcount); | 931 | memcpy(new->fields, old->fields, sizeof(struct audit_field) * fcount); |
932 | 932 | ||
933 | /* deep copy this information, updating the se_rule fields, because | 933 | /* deep copy this information, updating the lsm_rule fields, because |
934 | * the originals will all be freed when the old rule is freed. */ | 934 | * the originals will all be freed when the old rule is freed. */ |
935 | for (i = 0; i < fcount; i++) { | 935 | for (i = 0; i < fcount; i++) { |
936 | switch (new->fields[i].type) { | 936 | switch (new->fields[i].type) { |
@@ -944,7 +944,7 @@ static struct audit_entry *audit_dupe_rule(struct audit_krule *old, | |||
944 | case AUDIT_OBJ_TYPE: | 944 | case AUDIT_OBJ_TYPE: |
945 | case AUDIT_OBJ_LEV_LOW: | 945 | case AUDIT_OBJ_LEV_LOW: |
946 | case AUDIT_OBJ_LEV_HIGH: | 946 | case AUDIT_OBJ_LEV_HIGH: |
947 | err = audit_dupe_selinux_field(&new->fields[i], | 947 | err = audit_dupe_lsm_field(&new->fields[i], |
948 | &old->fields[i]); | 948 | &old->fields[i]); |
949 | break; | 949 | break; |
950 | case AUDIT_FILTERKEY: | 950 | case AUDIT_FILTERKEY: |
@@ -1515,11 +1515,12 @@ static void audit_log_rule_change(uid_t loginuid, u32 sid, char *action, | |||
1515 | if (sid) { | 1515 | if (sid) { |
1516 | char *ctx = NULL; | 1516 | char *ctx = NULL; |
1517 | u32 len; | 1517 | u32 len; |
1518 | if (selinux_sid_to_string(sid, &ctx, &len)) | 1518 | if (security_secid_to_secctx(sid, &ctx, &len)) |
1519 | audit_log_format(ab, " ssid=%u", sid); | 1519 | audit_log_format(ab, " ssid=%u", sid); |
1520 | else | 1520 | else { |
1521 | audit_log_format(ab, " subj=%s", ctx); | 1521 | audit_log_format(ab, " subj=%s", ctx); |
1522 | kfree(ctx); | 1522 | security_release_secctx(ctx, len); |
1523 | } | ||
1523 | } | 1524 | } |
1524 | audit_log_format(ab, " op=%s rule key=", action); | 1525 | audit_log_format(ab, " op=%s rule key=", action); |
1525 | if (rule->filterkey) | 1526 | if (rule->filterkey) |
@@ -1761,38 +1762,12 @@ unlock_and_return: | |||
1761 | return result; | 1762 | return result; |
1762 | } | 1763 | } |
1763 | 1764 | ||
1764 | /* Check to see if the rule contains any selinux fields. Returns 1 if there | 1765 | /* This function will re-initialize the lsm_rule field of all applicable rules. |
1765 | are selinux fields specified in the rule, 0 otherwise. */ | 1766 | * It will traverse the filter lists serarching for rules that contain LSM |
1766 | static inline int audit_rule_has_selinux(struct audit_krule *rule) | ||
1767 | { | ||
1768 | int i; | ||
1769 | |||
1770 | for (i = 0; i < rule->field_count; i++) { | ||
1771 | struct audit_field *f = &rule->fields[i]; | ||
1772 | switch (f->type) { | ||
1773 | case AUDIT_SUBJ_USER: | ||
1774 | case AUDIT_SUBJ_ROLE: | ||
1775 | case AUDIT_SUBJ_TYPE: | ||
1776 | case AUDIT_SUBJ_SEN: | ||
1777 | case AUDIT_SUBJ_CLR: | ||
1778 | case AUDIT_OBJ_USER: | ||
1779 | case AUDIT_OBJ_ROLE: | ||
1780 | case AUDIT_OBJ_TYPE: | ||
1781 | case AUDIT_OBJ_LEV_LOW: | ||
1782 | case AUDIT_OBJ_LEV_HIGH: | ||
1783 | return 1; | ||
1784 | } | ||
1785 | } | ||
1786 | |||
1787 | return 0; | ||
1788 | } | ||
1789 | |||
1790 | /* This function will re-initialize the se_rule field of all applicable rules. | ||
1791 | * It will traverse the filter lists serarching for rules that contain selinux | ||
1792 | * specific filter fields. When such a rule is found, it is copied, the | 1767 | * specific filter fields. When such a rule is found, it is copied, the |
1793 | * selinux field is re-initialized, and the old rule is replaced with the | 1768 | * LSM field is re-initialized, and the old rule is replaced with the |
1794 | * updated rule. */ | 1769 | * updated rule. */ |
1795 | int selinux_audit_rule_update(void) | 1770 | int audit_update_lsm_rules(void) |
1796 | { | 1771 | { |
1797 | struct audit_entry *entry, *n, *nentry; | 1772 | struct audit_entry *entry, *n, *nentry; |
1798 | struct audit_watch *watch; | 1773 | struct audit_watch *watch; |
@@ -1804,7 +1779,7 @@ int selinux_audit_rule_update(void) | |||
1804 | 1779 | ||
1805 | for (i = 0; i < AUDIT_NR_FILTERS; i++) { | 1780 | for (i = 0; i < AUDIT_NR_FILTERS; i++) { |
1806 | list_for_each_entry_safe(entry, n, &audit_filter_list[i], list) { | 1781 | list_for_each_entry_safe(entry, n, &audit_filter_list[i], list) { |
1807 | if (!audit_rule_has_selinux(&entry->rule)) | 1782 | if (!security_audit_rule_known(&entry->rule)) |
1808 | continue; | 1783 | continue; |
1809 | 1784 | ||
1810 | watch = entry->rule.watch; | 1785 | watch = entry->rule.watch; |
@@ -1815,7 +1790,7 @@ int selinux_audit_rule_update(void) | |||
1815 | * return value */ | 1790 | * return value */ |
1816 | if (!err) | 1791 | if (!err) |
1817 | err = PTR_ERR(nentry); | 1792 | err = PTR_ERR(nentry); |
1818 | audit_panic("error updating selinux filters"); | 1793 | audit_panic("error updating LSM filters"); |
1819 | if (watch) | 1794 | if (watch) |
1820 | list_del(&entry->rule.rlist); | 1795 | list_del(&entry->rule.rlist); |
1821 | list_del_rcu(&entry->list); | 1796 | list_del_rcu(&entry->list); |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 782262e4107d..56e56ed594a8 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -61,7 +61,6 @@ | |||
61 | #include <linux/security.h> | 61 | #include <linux/security.h> |
62 | #include <linux/list.h> | 62 | #include <linux/list.h> |
63 | #include <linux/tty.h> | 63 | #include <linux/tty.h> |
64 | #include <linux/selinux.h> | ||
65 | #include <linux/binfmts.h> | 64 | #include <linux/binfmts.h> |
66 | #include <linux/highmem.h> | 65 | #include <linux/highmem.h> |
67 | #include <linux/syscalls.h> | 66 | #include <linux/syscalls.h> |
@@ -528,14 +527,14 @@ static int audit_filter_rules(struct task_struct *tsk, | |||
528 | match for now to avoid losing information that | 527 | match for now to avoid losing information that |
529 | may be wanted. An error message will also be | 528 | may be wanted. An error message will also be |
530 | logged upon error */ | 529 | logged upon error */ |
531 | if (f->se_rule) { | 530 | if (f->lsm_rule) { |
532 | if (need_sid) { | 531 | if (need_sid) { |
533 | selinux_get_task_sid(tsk, &sid); | 532 | security_task_getsecid(tsk, &sid); |
534 | need_sid = 0; | 533 | need_sid = 0; |
535 | } | 534 | } |
536 | result = selinux_audit_rule_match(sid, f->type, | 535 | result = security_audit_rule_match(sid, f->type, |
537 | f->op, | 536 | f->op, |
538 | f->se_rule, | 537 | f->lsm_rule, |
539 | ctx); | 538 | ctx); |
540 | } | 539 | } |
541 | break; | 540 | break; |
@@ -546,18 +545,18 @@ static int audit_filter_rules(struct task_struct *tsk, | |||
546 | case AUDIT_OBJ_LEV_HIGH: | 545 | case AUDIT_OBJ_LEV_HIGH: |
547 | /* The above note for AUDIT_SUBJ_USER...AUDIT_SUBJ_CLR | 546 | /* The above note for AUDIT_SUBJ_USER...AUDIT_SUBJ_CLR |
548 | also applies here */ | 547 | also applies here */ |
549 | if (f->se_rule) { | 548 | if (f->lsm_rule) { |
550 | /* Find files that match */ | 549 | /* Find files that match */ |
551 | if (name) { | 550 | if (name) { |
552 | result = selinux_audit_rule_match( | 551 | result = security_audit_rule_match( |
553 | name->osid, f->type, f->op, | 552 | name->osid, f->type, f->op, |
554 | f->se_rule, ctx); | 553 | f->lsm_rule, ctx); |
555 | } else if (ctx) { | 554 | } else if (ctx) { |
556 | for (j = 0; j < ctx->name_count; j++) { | 555 | for (j = 0; j < ctx->name_count; j++) { |
557 | if (selinux_audit_rule_match( | 556 | if (security_audit_rule_match( |
558 | ctx->names[j].osid, | 557 | ctx->names[j].osid, |
559 | f->type, f->op, | 558 | f->type, f->op, |
560 | f->se_rule, ctx)) { | 559 | f->lsm_rule, ctx)) { |
561 | ++result; | 560 | ++result; |
562 | break; | 561 | break; |
563 | } | 562 | } |
@@ -570,7 +569,7 @@ static int audit_filter_rules(struct task_struct *tsk, | |||
570 | aux = aux->next) { | 569 | aux = aux->next) { |
571 | if (aux->type == AUDIT_IPC) { | 570 | if (aux->type == AUDIT_IPC) { |
572 | struct audit_aux_data_ipcctl *axi = (void *)aux; | 571 | struct audit_aux_data_ipcctl *axi = (void *)aux; |
573 | if (selinux_audit_rule_match(axi->osid, f->type, f->op, f->se_rule, ctx)) { | 572 | if (security_audit_rule_match(axi->osid, f->type, f->op, f->lsm_rule, ctx)) { |
574 | ++result; | 573 | ++result; |
575 | break; | 574 | break; |
576 | } | 575 | } |
@@ -885,11 +884,11 @@ void audit_log_task_context(struct audit_buffer *ab) | |||
885 | int error; | 884 | int error; |
886 | u32 sid; | 885 | u32 sid; |
887 | 886 | ||
888 | selinux_get_task_sid(current, &sid); | 887 | security_task_getsecid(current, &sid); |
889 | if (!sid) | 888 | if (!sid) |
890 | return; | 889 | return; |
891 | 890 | ||
892 | error = selinux_sid_to_string(sid, &ctx, &len); | 891 | error = security_secid_to_secctx(sid, &ctx, &len); |
893 | if (error) { | 892 | if (error) { |
894 | if (error != -EINVAL) | 893 | if (error != -EINVAL) |
895 | goto error_path; | 894 | goto error_path; |
@@ -897,7 +896,7 @@ void audit_log_task_context(struct audit_buffer *ab) | |||
897 | } | 896 | } |
898 | 897 | ||
899 | audit_log_format(ab, " subj=%s", ctx); | 898 | audit_log_format(ab, " subj=%s", ctx); |
900 | kfree(ctx); | 899 | security_release_secctx(ctx, len); |
901 | return; | 900 | return; |
902 | 901 | ||
903 | error_path: | 902 | error_path: |
@@ -941,7 +940,7 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, | |||
941 | u32 sid, char *comm) | 940 | u32 sid, char *comm) |
942 | { | 941 | { |
943 | struct audit_buffer *ab; | 942 | struct audit_buffer *ab; |
944 | char *s = NULL; | 943 | char *ctx = NULL; |
945 | u32 len; | 944 | u32 len; |
946 | int rc = 0; | 945 | int rc = 0; |
947 | 946 | ||
@@ -951,15 +950,16 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, | |||
951 | 950 | ||
952 | audit_log_format(ab, "opid=%d oauid=%d ouid=%d oses=%d", pid, auid, | 951 | audit_log_format(ab, "opid=%d oauid=%d ouid=%d oses=%d", pid, auid, |
953 | uid, sessionid); | 952 | uid, sessionid); |
954 | if (selinux_sid_to_string(sid, &s, &len)) { | 953 | if (security_secid_to_secctx(sid, &ctx, &len)) { |
955 | audit_log_format(ab, " obj=(none)"); | 954 | audit_log_format(ab, " obj=(none)"); |
956 | rc = 1; | 955 | rc = 1; |
957 | } else | 956 | } else { |
958 | audit_log_format(ab, " obj=%s", s); | 957 | audit_log_format(ab, " obj=%s", ctx); |
958 | security_release_secctx(ctx, len); | ||
959 | } | ||
959 | audit_log_format(ab, " ocomm="); | 960 | audit_log_format(ab, " ocomm="); |
960 | audit_log_untrustedstring(ab, comm); | 961 | audit_log_untrustedstring(ab, comm); |
961 | audit_log_end(ab); | 962 | audit_log_end(ab); |
962 | kfree(s); | ||
963 | 963 | ||
964 | return rc; | 964 | return rc; |
965 | } | 965 | } |
@@ -1271,14 +1271,15 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
1271 | if (axi->osid != 0) { | 1271 | if (axi->osid != 0) { |
1272 | char *ctx = NULL; | 1272 | char *ctx = NULL; |
1273 | u32 len; | 1273 | u32 len; |
1274 | if (selinux_sid_to_string( | 1274 | if (security_secid_to_secctx( |
1275 | axi->osid, &ctx, &len)) { | 1275 | axi->osid, &ctx, &len)) { |
1276 | audit_log_format(ab, " osid=%u", | 1276 | audit_log_format(ab, " osid=%u", |
1277 | axi->osid); | 1277 | axi->osid); |
1278 | call_panic = 1; | 1278 | call_panic = 1; |
1279 | } else | 1279 | } else { |
1280 | audit_log_format(ab, " obj=%s", ctx); | 1280 | audit_log_format(ab, " obj=%s", ctx); |
1281 | kfree(ctx); | 1281 | security_release_secctx(ctx, len); |
1282 | } | ||
1282 | } | 1283 | } |
1283 | break; } | 1284 | break; } |
1284 | 1285 | ||
@@ -1392,13 +1393,14 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
1392 | if (n->osid != 0) { | 1393 | if (n->osid != 0) { |
1393 | char *ctx = NULL; | 1394 | char *ctx = NULL; |
1394 | u32 len; | 1395 | u32 len; |
1395 | if (selinux_sid_to_string( | 1396 | if (security_secid_to_secctx( |
1396 | n->osid, &ctx, &len)) { | 1397 | n->osid, &ctx, &len)) { |
1397 | audit_log_format(ab, " osid=%u", n->osid); | 1398 | audit_log_format(ab, " osid=%u", n->osid); |
1398 | call_panic = 2; | 1399 | call_panic = 2; |
1399 | } else | 1400 | } else { |
1400 | audit_log_format(ab, " obj=%s", ctx); | 1401 | audit_log_format(ab, " obj=%s", ctx); |
1401 | kfree(ctx); | 1402 | security_release_secctx(ctx, len); |
1403 | } | ||
1402 | } | 1404 | } |
1403 | 1405 | ||
1404 | audit_log_end(ab); | 1406 | audit_log_end(ab); |
@@ -1775,7 +1777,7 @@ static void audit_copy_inode(struct audit_names *name, const struct inode *inode | |||
1775 | name->uid = inode->i_uid; | 1777 | name->uid = inode->i_uid; |
1776 | name->gid = inode->i_gid; | 1778 | name->gid = inode->i_gid; |
1777 | name->rdev = inode->i_rdev; | 1779 | name->rdev = inode->i_rdev; |
1778 | selinux_get_inode_sid(inode, &name->osid); | 1780 | security_inode_getsecid(inode, &name->osid); |
1779 | } | 1781 | } |
1780 | 1782 | ||
1781 | /** | 1783 | /** |
@@ -2190,8 +2192,7 @@ int __audit_ipc_obj(struct kern_ipc_perm *ipcp) | |||
2190 | ax->uid = ipcp->uid; | 2192 | ax->uid = ipcp->uid; |
2191 | ax->gid = ipcp->gid; | 2193 | ax->gid = ipcp->gid; |
2192 | ax->mode = ipcp->mode; | 2194 | ax->mode = ipcp->mode; |
2193 | selinux_get_ipc_sid(ipcp, &ax->osid); | 2195 | security_ipc_getsecid(ipcp, &ax->osid); |
2194 | |||
2195 | ax->d.type = AUDIT_IPC; | 2196 | ax->d.type = AUDIT_IPC; |
2196 | ax->d.next = context->aux; | 2197 | ax->d.next = context->aux; |
2197 | context->aux = (void *)ax; | 2198 | context->aux = (void *)ax; |
@@ -2343,7 +2344,7 @@ void __audit_ptrace(struct task_struct *t) | |||
2343 | context->target_auid = audit_get_loginuid(t); | 2344 | context->target_auid = audit_get_loginuid(t); |
2344 | context->target_uid = t->uid; | 2345 | context->target_uid = t->uid; |
2345 | context->target_sessionid = audit_get_sessionid(t); | 2346 | context->target_sessionid = audit_get_sessionid(t); |
2346 | selinux_get_task_sid(t, &context->target_sid); | 2347 | security_task_getsecid(t, &context->target_sid); |
2347 | memcpy(context->target_comm, t->comm, TASK_COMM_LEN); | 2348 | memcpy(context->target_comm, t->comm, TASK_COMM_LEN); |
2348 | } | 2349 | } |
2349 | 2350 | ||
@@ -2371,7 +2372,7 @@ int __audit_signal_info(int sig, struct task_struct *t) | |||
2371 | audit_sig_uid = tsk->loginuid; | 2372 | audit_sig_uid = tsk->loginuid; |
2372 | else | 2373 | else |
2373 | audit_sig_uid = tsk->uid; | 2374 | audit_sig_uid = tsk->uid; |
2374 | selinux_get_task_sid(tsk, &audit_sig_sid); | 2375 | security_task_getsecid(tsk, &audit_sig_sid); |
2375 | } | 2376 | } |
2376 | if (!audit_signals || audit_dummy_context()) | 2377 | if (!audit_signals || audit_dummy_context()) |
2377 | return 0; | 2378 | return 0; |
@@ -2384,7 +2385,7 @@ int __audit_signal_info(int sig, struct task_struct *t) | |||
2384 | ctx->target_auid = audit_get_loginuid(t); | 2385 | ctx->target_auid = audit_get_loginuid(t); |
2385 | ctx->target_uid = t->uid; | 2386 | ctx->target_uid = t->uid; |
2386 | ctx->target_sessionid = audit_get_sessionid(t); | 2387 | ctx->target_sessionid = audit_get_sessionid(t); |
2387 | selinux_get_task_sid(t, &ctx->target_sid); | 2388 | security_task_getsecid(t, &ctx->target_sid); |
2388 | memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN); | 2389 | memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN); |
2389 | return 0; | 2390 | return 0; |
2390 | } | 2391 | } |
@@ -2405,7 +2406,7 @@ int __audit_signal_info(int sig, struct task_struct *t) | |||
2405 | axp->target_auid[axp->pid_count] = audit_get_loginuid(t); | 2406 | axp->target_auid[axp->pid_count] = audit_get_loginuid(t); |
2406 | axp->target_uid[axp->pid_count] = t->uid; | 2407 | axp->target_uid[axp->pid_count] = t->uid; |
2407 | axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t); | 2408 | axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t); |
2408 | selinux_get_task_sid(t, &axp->target_sid[axp->pid_count]); | 2409 | security_task_getsecid(t, &axp->target_sid[axp->pid_count]); |
2409 | memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN); | 2410 | memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN); |
2410 | axp->pid_count++; | 2411 | axp->pid_count++; |
2411 | 2412 | ||
@@ -2435,16 +2436,17 @@ void audit_core_dumps(long signr) | |||
2435 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND); | 2436 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND); |
2436 | audit_log_format(ab, "auid=%u uid=%u gid=%u ses=%u", | 2437 | audit_log_format(ab, "auid=%u uid=%u gid=%u ses=%u", |
2437 | auid, current->uid, current->gid, sessionid); | 2438 | auid, current->uid, current->gid, sessionid); |
2438 | selinux_get_task_sid(current, &sid); | 2439 | security_task_getsecid(current, &sid); |
2439 | if (sid) { | 2440 | if (sid) { |
2440 | char *ctx = NULL; | 2441 | char *ctx = NULL; |
2441 | u32 len; | 2442 | u32 len; |
2442 | 2443 | ||
2443 | if (selinux_sid_to_string(sid, &ctx, &len)) | 2444 | if (security_secid_to_secctx(sid, &ctx, &len)) |
2444 | audit_log_format(ab, " ssid=%u", sid); | 2445 | audit_log_format(ab, " ssid=%u", sid); |
2445 | else | 2446 | else { |
2446 | audit_log_format(ab, " subj=%s", ctx); | 2447 | audit_log_format(ab, " subj=%s", ctx); |
2447 | kfree(ctx); | 2448 | security_release_secctx(ctx, len); |
2449 | } | ||
2448 | } | 2450 | } |
2449 | audit_log_format(ab, " pid=%d comm=", current->pid); | 2451 | audit_log_format(ab, " pid=%d comm=", current->pid); |
2450 | audit_log_untrustedstring(ab, current->comm); | 2452 | audit_log_untrustedstring(ab, current->comm); |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 36f75d873898..46f3e44bb83a 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -54,7 +54,6 @@ | |||
54 | #include <linux/mm.h> | 54 | #include <linux/mm.h> |
55 | #include <linux/types.h> | 55 | #include <linux/types.h> |
56 | #include <linux/audit.h> | 56 | #include <linux/audit.h> |
57 | #include <linux/selinux.h> | ||
58 | #include <linux/mutex.h> | 57 | #include <linux/mutex.h> |
59 | 58 | ||
60 | #include <net/net_namespace.h> | 59 | #include <net/net_namespace.h> |
@@ -1249,7 +1248,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1249 | NETLINK_CB(skb).pid = nlk->pid; | 1248 | NETLINK_CB(skb).pid = nlk->pid; |
1250 | NETLINK_CB(skb).dst_group = dst_group; | 1249 | NETLINK_CB(skb).dst_group = dst_group; |
1251 | NETLINK_CB(skb).loginuid = audit_get_loginuid(current); | 1250 | NETLINK_CB(skb).loginuid = audit_get_loginuid(current); |
1252 | selinux_get_task_sid(current, &(NETLINK_CB(skb).sid)); | 1251 | security_task_getsecid(current, &(NETLINK_CB(skb).sid)); |
1253 | memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); | 1252 | memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); |
1254 | 1253 | ||
1255 | /* What can I do? Netlink is asynchronous, so that | 1254 | /* What can I do? Netlink is asynchronous, so that |
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); |