aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Grubb <sgrubb@redhat.com>2006-04-03 14:06:13 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2006-05-01 06:09:53 -0400
commit1b50eed9cac0e8e5e4d3a522d8aa267f7f8f8acb (patch)
treec66a1c3be846e34f1aac5db640b7ccb8770e8a80
parent3dc7e3153eddfcf7ba8b50628775ba516e5f759f (diff)
[PATCH] audit inode patch
Previously, we were gathering the context instead of the sid. Now in this patch, we gather just the sid and convert to context only if an audit event is being output. This patch brings the performance hit from 146% down to 23% Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--include/linux/selinux.h34
-rw-r--r--kernel/auditsc.c53
-rw-r--r--security/selinux/exports.c24
3 files changed, 74 insertions, 37 deletions
diff --git a/include/linux/selinux.h b/include/linux/selinux.h
index 9d684b1728b0..84a6c7404687 100644
--- a/include/linux/selinux.h
+++ b/include/linux/selinux.h
@@ -15,6 +15,7 @@
15 15
16struct selinux_audit_rule; 16struct selinux_audit_rule;
17struct audit_context; 17struct audit_context;
18struct inode;
18 19
19#ifdef CONFIG_SECURITY_SELINUX 20#ifdef CONFIG_SECURITY_SELINUX
20 21
@@ -76,6 +77,27 @@ void selinux_audit_set_callback(int (*callback)(void));
76 */ 77 */
77void selinux_task_ctxid(struct task_struct *tsk, u32 *ctxid); 78void selinux_task_ctxid(struct task_struct *tsk, u32 *ctxid);
78 79
80/**
81 * selinux_ctxid_to_string - map a security context ID to a string
82 * @ctxid: security context ID to be converted.
83 * @ctx: address of context string to be returned
84 * @ctxlen: length of returned context string.
85 *
86 * Returns 0 if successful, -errno if not. On success, the context
87 * string will be allocated internally, and the caller must call
88 * kfree() on it after use.
89 */
90int selinux_ctxid_to_string(u32 ctxid, char **ctx, u32 *ctxlen);
91
92/**
93 * selinux_get_inode_sid - get the inode's security context ID
94 * @inode: inode structure to get the sid from.
95 * @sid: pointer to security context ID to be filled in.
96 *
97 * Returns nothing
98 */
99void selinux_get_inode_sid(const struct inode *inode, u32 *sid);
100
79#else 101#else
80 102
81static inline int selinux_audit_rule_init(u32 field, u32 op, 103static inline int selinux_audit_rule_init(u32 field, u32 op,
@@ -107,6 +129,18 @@ static inline void selinux_task_ctxid(struct task_struct *tsk, u32 *ctxid)
107 *ctxid = 0; 129 *ctxid = 0;
108} 130}
109 131
132static inline int selinux_ctxid_to_string(u32 ctxid, char **ctx, u32 *ctxlen)
133{
134 *ctx = NULL;
135 *ctxlen = 0;
136 return 0;
137}
138
139static inline void selinux_get_inode_sid(const struct inode *inode, u32 *sid)
140{
141 *sid = 0;
142}
143
110#endif /* CONFIG_SECURITY_SELINUX */ 144#endif /* CONFIG_SECURITY_SELINUX */
111 145
112#endif /* _LINUX_SELINUX_H */ 146#endif /* _LINUX_SELINUX_H */
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index d3d97d28b69a..2e123a8a0d60 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -90,7 +90,7 @@ struct audit_names {
90 uid_t uid; 90 uid_t uid;
91 gid_t gid; 91 gid_t gid;
92 dev_t rdev; 92 dev_t rdev;
93 char *ctx; 93 u32 osid;
94}; 94};
95 95
96struct audit_aux_data { 96struct audit_aux_data {
@@ -410,9 +410,6 @@ static inline void audit_free_names(struct audit_context *context)
410#endif 410#endif
411 411
412 for (i = 0; i < context->name_count; i++) { 412 for (i = 0; i < context->name_count; i++) {
413 char *p = context->names[i].ctx;
414 context->names[i].ctx = NULL;
415 kfree(p);
416 if (context->names[i].name) 413 if (context->names[i].name)
417 __putname(context->names[i].name); 414 __putname(context->names[i].name);
418 } 415 }
@@ -674,6 +671,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
674 } 671 }
675 } 672 }
676 for (i = 0; i < context->name_count; i++) { 673 for (i = 0; i < context->name_count; i++) {
674 int call_panic = 0;
677 unsigned long ino = context->names[i].ino; 675 unsigned long ino = context->names[i].ino;
678 unsigned long pino = context->names[i].pino; 676 unsigned long pino = context->names[i].pino;
679 677
@@ -703,12 +701,22 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
703 context->names[i].gid, 701 context->names[i].gid,
704 MAJOR(context->names[i].rdev), 702 MAJOR(context->names[i].rdev),
705 MINOR(context->names[i].rdev)); 703 MINOR(context->names[i].rdev));
706 if (context->names[i].ctx) { 704 if (context->names[i].osid != 0) {
707 audit_log_format(ab, " obj=%s", 705 char *ctx = NULL;
708 context->names[i].ctx); 706 u32 len;
707 if (selinux_ctxid_to_string(
708 context->names[i].osid, &ctx, &len)) {
709 audit_log_format(ab, " obj=%u",
710 context->names[i].osid);
711 call_panic = 1;
712 } else
713 audit_log_format(ab, " obj=%s", ctx);
714 kfree(ctx);
709 } 715 }
710 716
711 audit_log_end(ab); 717 audit_log_end(ab);
718 if (call_panic)
719 audit_panic("error converting sid to string");
712 } 720 }
713} 721}
714 722
@@ -946,37 +954,8 @@ void audit_putname(const char *name)
946void audit_inode_context(int idx, const struct inode *inode) 954void audit_inode_context(int idx, const struct inode *inode)
947{ 955{
948 struct audit_context *context = current->audit_context; 956 struct audit_context *context = current->audit_context;
949 const char *suffix = security_inode_xattr_getsuffix();
950 char *ctx = NULL;
951 int len = 0;
952
953 if (!suffix)
954 goto ret;
955
956 len = security_inode_getsecurity(inode, suffix, NULL, 0, 0);
957 if (len == -EOPNOTSUPP)
958 goto ret;
959 if (len < 0)
960 goto error_path;
961
962 ctx = kmalloc(len, GFP_KERNEL);
963 if (!ctx)
964 goto error_path;
965
966 len = security_inode_getsecurity(inode, suffix, ctx, len, 0);
967 if (len < 0)
968 goto error_path;
969
970 kfree(context->names[idx].ctx);
971 context->names[idx].ctx = ctx;
972 goto ret;
973 957
974error_path: 958 selinux_get_inode_sid(inode, &context->names[idx].osid);
975 if (ctx)
976 kfree(ctx);
977 audit_panic("error in audit_inode_context");
978ret:
979 return;
980} 959}
981 960
982 961
diff --git a/security/selinux/exports.c b/security/selinux/exports.c
index 333c4c7824d8..07ddce7bf374 100644
--- a/security/selinux/exports.c
+++ b/security/selinux/exports.c
@@ -14,6 +14,7 @@
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/selinux.h> 16#include <linux/selinux.h>
17#include <linux/fs.h>
17 18
18#include "security.h" 19#include "security.h"
19#include "objsec.h" 20#include "objsec.h"
@@ -26,3 +27,26 @@ void selinux_task_ctxid(struct task_struct *tsk, u32 *ctxid)
26 else 27 else
27 *ctxid = 0; 28 *ctxid = 0;
28} 29}
30
31int selinux_ctxid_to_string(u32 ctxid, char **ctx, u32 *ctxlen)
32{
33 if (selinux_enabled)
34 return security_sid_to_context(ctxid, ctx, ctxlen);
35 else {
36 *ctx = NULL;
37 *ctxlen = 0;
38 }
39
40 return 0;
41}
42
43void selinux_get_inode_sid(const struct inode *inode, u32 *sid)
44{
45 if (selinux_enabled) {
46 struct inode_security_struct *isec = inode->i_security;
47 *sid = isec->sid;
48 return;
49 }
50 *sid = 0;
51}
52