aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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