aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-04-18 21:18:30 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-18 21:18:30 -0400
commit3925e6fc1f774048404fdd910b0345b06c699eb4 (patch)
treec9a58417d9492f39f7fe81d4721d674c34dd8be2
parent334d094504c2fe1c44211ecb49146ae6bca8c321 (diff)
parent7cea51be4e91edad05bd834f3235b45c57783f0d (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.txt6
-rw-r--r--include/linux/audit.h29
-rw-r--r--include/linux/security.h114
-rw-r--r--include/linux/selinux.h134
-rw-r--r--kernel/audit.c24
-rw-r--r--kernel/audit.h25
-rw-r--r--kernel/auditfilter.c99
-rw-r--r--kernel/auditsc.c74
-rw-r--r--net/netlink/af_netlink.c3
-rw-r--r--security/dummy.c51
-rw-r--r--security/security.c73
-rw-r--r--security/selinux/exports.c42
-rw-r--r--security/selinux/hooks.c34
-rw-r--r--security/selinux/include/audit.h65
-rw-r--r--security/selinux/ss/services.c45
-rw-r--r--security/smack/smack.h2
-rw-r--r--security/smack/smack_lsm.c7
-rw-r--r--security/smack/smackfs.c11
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;
353struct linux_binprm; 353struct linux_binprm;
354struct mq_attr; 354struct mq_attr;
355struct mqstat; 355struct mqstat;
356struct audit_watch;
357struct audit_tree;
358
359struct 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
376struct 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);
538extern void audit_log_lost(const char *message); 565extern void audit_log_lost(const char *message);
566extern int audit_update_lsm_rules(void);
567
539 /* Private API (for audit.c only) */ 568 /* Private API (for audit.c only) */
540extern int audit_filter_user(struct netlink_skb_parms *cb, int type); 569extern int audit_filter_user(struct netlink_skb_parms *cb, int type);
541extern int audit_filter_type(int type); 570extern 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
37extern unsigned securebits; 37extern unsigned securebits;
38 38
39/* Maximum number of letters for an LSM name string */
40#define SECURITY_NAME_MAX 10
41
39struct ctl_table; 42struct ctl_table;
43struct 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 */
1228struct security_operations { 1281struct 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 */
1486extern int security_init (void); 1550extern int security_init (void);
1551extern int security_module_enable(struct security_operations *ops);
1487extern int register_security (struct security_operations *ops); 1552extern int register_security (struct security_operations *ops);
1488extern int mod_reg_security (const char *name, struct security_operations *ops); 1553extern int mod_reg_security (const char *name, struct security_operations *ops);
1489extern struct dentry *securityfs_create_file(const char *name, mode_t mode, 1554extern struct dentry *securityfs_create_file(const char *name, mode_t mode,
@@ -1578,6 +1643,7 @@ int security_inode_killpriv(struct dentry *dentry);
1578int security_inode_getsecurity(const struct inode *inode, const char *name, void **buffer, bool alloc); 1643int security_inode_getsecurity(const struct inode *inode, const char *name, void **buffer, bool alloc);
1579int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags); 1644int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags);
1580int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size); 1645int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size);
1646void security_inode_getsecid(const struct inode *inode, u32 *secid);
1581int security_file_permission(struct file *file, int mask); 1647int security_file_permission(struct file *file, int mask);
1582int security_file_alloc(struct file *file); 1648int security_file_alloc(struct file *file);
1583void security_file_free(struct file *file); 1649void security_file_free(struct file *file);
@@ -1622,6 +1688,7 @@ int security_task_prctl(int option, unsigned long arg2, unsigned long arg3,
1622void security_task_reparent_to_init(struct task_struct *p); 1688void security_task_reparent_to_init(struct task_struct *p);
1623void security_task_to_inode(struct task_struct *p, struct inode *inode); 1689void security_task_to_inode(struct task_struct *p, struct inode *inode);
1624int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag); 1690int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag);
1691void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid);
1625int security_msg_msg_alloc(struct msg_msg *msg); 1692int security_msg_msg_alloc(struct msg_msg *msg);
1626void security_msg_msg_free(struct msg_msg *msg); 1693void security_msg_msg_free(struct msg_msg *msg);
1627int security_msg_queue_alloc(struct msg_queue *msq); 1694int 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
2092static inline void security_inode_getsecid(const struct inode *inode, u32 *secid)
2093{
2094 *secid = 0;
2095}
2096
2025static inline int security_file_permission (struct file *file, int mask) 2097static 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
2139static inline void security_task_getsecid (struct task_struct *p, u32 *secid) 2211static inline void security_task_getsecid (struct task_struct *p, u32 *secid)
2140{ } 2212{
2213 *secid = 0;
2214}
2141 2215
2142static inline int security_task_setgroups (struct group_info *group_info) 2216static 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
2293static inline void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid)
2294{
2295 *secid = 0;
2296}
2297
2219static inline int security_msg_msg_alloc (struct msg_msg * msg) 2298static 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
2756int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule);
2757int security_audit_rule_known(struct audit_krule *krule);
2758int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule,
2759 struct audit_context *actx);
2760void security_audit_rule_free(void *lsmrule);
2761
2762#else
2763
2764static inline int security_audit_rule_init(u32 field, u32 op, char *rulestr,
2765 void **lsmrule)
2766{
2767 return 0;
2768}
2769
2770static inline int security_audit_rule_known(struct audit_krule *krule)
2771{
2772 return 0;
2773}
2774
2775static 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
2781static 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
17struct selinux_audit_rule; 17struct selinux_audit_rule;
18struct audit_context; 18struct audit_context;
19struct inode;
20struct kern_ipc_perm; 19struct 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 */
35int 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 */
45void 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 */
58int 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 */
70void 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 */
82int 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 */
91void 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 */
100void 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 */
109void 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);
151void selinux_secmark_refcount_dec(void); 63void selinux_secmark_refcount_dec(void);
152#else 64#else
153 65
154static 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
161static inline void selinux_audit_rule_free(struct selinux_audit_rule *rule)
162{
163 return;
164}
165
166static 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
173static inline void selinux_audit_set_callback(int (*callback)(void))
174{
175 return;
176}
177
178static inline int selinux_sid_to_string(u32 sid, char **ctx, u32 *ctxlen)
179{
180 *ctx = NULL;
181 *ctxlen = 0;
182 return 0;
183}
184
185static inline void selinux_get_inode_sid(const struct inode *inode, u32 *sid)
186{
187 *sid = 0;
188}
189
190static inline void selinux_get_ipc_sid(const struct kern_ipc_perm *ipcp, u32 *sid)
191{
192 *sid = 0;
193}
194
195static inline void selinux_get_task_sid(struct task_struct *tsk, u32 *sid)
196{
197 *sid = 0;
198}
199
200static inline int selinux_string_to_sid(const char *str, u32 *sid) 66static 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
68struct audit_field {
69 u32 type;
70 u32 val;
71 u32 op;
72 char *se_str;
73 struct selinux_audit_rule *se_rule;
74};
75
76struct audit_tree; 68struct audit_tree;
77struct audit_chunk; 69struct audit_chunk;
78 70
79struct 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
96struct audit_entry { 71struct 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. */
867static inline int audit_dupe_selinux_field(struct audit_field *df, 867static 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
1766static 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. */
1795int selinux_audit_rule_update(void) 1770int 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
903error_path: 902error_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
427static void dummy_inode_getsecid(const struct inode *inode, u32 *secid)
428{
429 *secid = 0;
430}
431
427static int dummy_file_permission (struct file *file, int mask) 432static 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
544static void dummy_task_getsecid (struct task_struct *p, u32 *secid) 549static void dummy_task_getsecid (struct task_struct *p, u32 *secid)
545{ } 550{
551 *secid = 0;
552}
546 553
547static int dummy_task_setgroups (struct group_info *group_info) 554static 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
626static void dummy_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid)
627{
628 *secid = 0;
629}
630
619static int dummy_msg_msg_alloc_security (struct msg_msg *msg) 631static 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
986struct security_operations dummy_security_ops; 998#ifdef CONFIG_AUDIT
999static inline int dummy_audit_rule_init(u32 field, u32 op, char *rulestr,
1000 void **lsmrule)
1001{
1002 return 0;
1003}
1004
1005static inline int dummy_audit_rule_known(struct audit_krule *krule)
1006{
1007 return 0;
1008}
1009
1010static 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
1017static inline void dummy_audit_rule_free(void *lsmrule)
1018{ }
1019
1020#endif /* CONFIG_AUDIT */
1021
1022struct 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 */
21static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1];
20 22
21/* things that live in dummy.c */ 23/* things that live in dummy.c */
22extern struct security_operations dummy_security_ops; 24extern 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 */
73static 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 */
95int __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
562void security_inode_getsecid(const struct inode *inode, u32 *secid)
563{
564 security_ops->inode_getsecid(inode, secid);
565}
566
526int security_file_permission(struct file *file, int mask) 567int 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
756void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid)
757{
758 security_ops->ipc_getsecid(ipcp, secid);
759}
760
715int security_msg_msg_alloc(struct msg_msg *msg) 761int 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
1163int 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
1168int security_audit_rule_known(struct audit_krule *krule)
1169{
1170 return security_ops->audit_rule_known(krule);
1171}
1172
1173void security_audit_rule_free(void *lsmrule)
1174{
1175 security_ops->audit_rule_free(lsmrule);
1176}
1177
1178int 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 */
26extern atomic_t selinux_secmark_refcount; 26extern atomic_t selinux_secmark_refcount;
27 27
28int 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
40void 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
50void 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
60void 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
70int selinux_string_to_sid(char *str, u32 *sid) 28int 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
2796static 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
2797static int selinux_revalidate_file_permission(struct file *file, int mask) 2804static 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
3184static void selinux_task_getsecid(struct task_struct *p, u32 *secid) 3191static 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
3189static int selinux_task_setgroups(struct group_info *group_info) 3197static 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
5037static 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 */
5030static int selinux_register_security (const char *name, struct security_operations *ops) 5044static 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
5283static struct security_operations selinux_ops = { 5297static 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
5468static __init int selinux_init(void) 5493static __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 */
32int 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 */
41void 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 */
54int 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 */
62int 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
61extern void selnl_notify_policyload(u32 seqno); 62extern void selnl_notify_policyload(u32 seqno);
62unsigned int policydb_loaded_version; 63unsigned 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
2299void selinux_audit_rule_free(struct selinux_audit_rule *rule) 2300void 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
2307int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, 2310int 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
2400int 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, 2404int 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
2428int 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
2512static int (*aurule_callback)(void) = NULL; 2540static int (*aurule_callback)(void) = audit_update_lsm_rules;
2513 2541
2514static int aurule_avc_callback(u32 event, u32 ssid, u32 tsid, 2542static 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
2537void 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;
187extern struct smack_known smack_known_unset; 188extern struct smack_known smack_known_unset;
188 189
189extern struct smk_list_entry *smack_list; 190extern struct smk_list_entry *smack_list;
191extern 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
2427static struct security_operations smack_ops = { 2427struct 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 */
2558static __init int smack_init(void) 2560static __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 */
970static int __init init_smk_fs(void) 976static 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);