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); |
