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