diff options
-rw-r--r-- | include/linux/selinux.h | 34 | ||||
-rw-r--r-- | kernel/auditsc.c | 53 | ||||
-rw-r--r-- | security/selinux/exports.c | 24 |
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 | ||
16 | struct selinux_audit_rule; | 16 | struct selinux_audit_rule; |
17 | struct audit_context; | 17 | struct audit_context; |
18 | struct 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 | */ |
77 | void selinux_task_ctxid(struct task_struct *tsk, u32 *ctxid); | 78 | void 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 | */ | ||
90 | int 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 | */ | ||
99 | void selinux_get_inode_sid(const struct inode *inode, u32 *sid); | ||
100 | |||
79 | #else | 101 | #else |
80 | 102 | ||
81 | static inline int selinux_audit_rule_init(u32 field, u32 op, | 103 | static 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 | ||
132 | static inline int selinux_ctxid_to_string(u32 ctxid, char **ctx, u32 *ctxlen) | ||
133 | { | ||
134 | *ctx = NULL; | ||
135 | *ctxlen = 0; | ||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | static 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 | ||
96 | struct audit_aux_data { | 96 | struct 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) | |||
946 | void audit_inode_context(int idx, const struct inode *inode) | 954 | void 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 | ||
974 | error_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"); | ||
978 | ret: | ||
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 | |||
31 | int 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 | |||
43 | void 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 | |||