diff options
author | Steve Grubb <sgrubb@redhat.com> | 2006-03-31 15:22:49 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2006-05-01 06:09:56 -0400 |
commit | 9c7aa6aa74fa8a5cda36e54cbbe4fffe0214497d (patch) | |
tree | 1e1489ed5080ea4aff6206bfa904f549de8e56ca | |
parent | 1b50eed9cac0e8e5e4d3a522d8aa267f7f8f8acb (diff) |
[PATCH] change lspp ipc auditing
Hi,
The patch below converts IPC auditing to collect sid's and convert to context
string only if it needs to output an audit record. This patch depends on the
inode audit change patch already being applied.
Signed-off-by: Steve Grubb <sgrubb@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | include/linux/security.h | 16 | ||||
-rw-r--r-- | include/linux/selinux.h | 15 | ||||
-rw-r--r-- | kernel/auditsc.c | 68 | ||||
-rw-r--r-- | security/dummy.c | 6 | ||||
-rw-r--r-- | security/selinux/exports.c | 11 | ||||
-rw-r--r-- | security/selinux/hooks.c | 8 |
6 files changed, 47 insertions, 77 deletions
diff --git a/include/linux/security.h b/include/linux/security.h index aaa0a5cdbf75..1bab48f6aeac 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
@@ -869,11 +869,6 @@ struct swap_info_struct; | |||
869 | * @ipcp contains the kernel IPC permission structure | 869 | * @ipcp contains the kernel IPC permission structure |
870 | * @flag contains the desired (requested) permission set | 870 | * @flag contains the desired (requested) permission set |
871 | * Return 0 if permission is granted. | 871 | * Return 0 if permission is granted. |
872 | * @ipc_getsecurity: | ||
873 | * Copy the security label associated with the ipc object into | ||
874 | * @buffer. @buffer may be NULL to request the size of the buffer | ||
875 | * required. @size indicates the size of @buffer in bytes. Return | ||
876 | * number of bytes used/required on success. | ||
877 | * | 872 | * |
878 | * Security hooks for individual messages held in System V IPC message queues | 873 | * Security hooks for individual messages held in System V IPC message queues |
879 | * @msg_msg_alloc_security: | 874 | * @msg_msg_alloc_security: |
@@ -1223,7 +1218,6 @@ struct security_operations { | |||
1223 | void (*task_to_inode)(struct task_struct *p, struct inode *inode); | 1218 | void (*task_to_inode)(struct task_struct *p, struct inode *inode); |
1224 | 1219 | ||
1225 | int (*ipc_permission) (struct kern_ipc_perm * ipcp, short flag); | 1220 | int (*ipc_permission) (struct kern_ipc_perm * ipcp, short flag); |
1226 | int (*ipc_getsecurity)(struct kern_ipc_perm *ipcp, void *buffer, size_t size); | ||
1227 | 1221 | ||
1228 | int (*msg_msg_alloc_security) (struct msg_msg * msg); | 1222 | int (*msg_msg_alloc_security) (struct msg_msg * msg); |
1229 | void (*msg_msg_free_security) (struct msg_msg * msg); | 1223 | void (*msg_msg_free_security) (struct msg_msg * msg); |
@@ -1887,11 +1881,6 @@ static inline int security_ipc_permission (struct kern_ipc_perm *ipcp, | |||
1887 | return security_ops->ipc_permission (ipcp, flag); | 1881 | return security_ops->ipc_permission (ipcp, flag); |
1888 | } | 1882 | } |
1889 | 1883 | ||
1890 | static inline int security_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size) | ||
1891 | { | ||
1892 | return security_ops->ipc_getsecurity(ipcp, buffer, size); | ||
1893 | } | ||
1894 | |||
1895 | static inline int security_msg_msg_alloc (struct msg_msg * msg) | 1884 | static inline int security_msg_msg_alloc (struct msg_msg * msg) |
1896 | { | 1885 | { |
1897 | return security_ops->msg_msg_alloc_security (msg); | 1886 | return security_ops->msg_msg_alloc_security (msg); |
@@ -2532,11 +2521,6 @@ static inline int security_ipc_permission (struct kern_ipc_perm *ipcp, | |||
2532 | return 0; | 2521 | return 0; |
2533 | } | 2522 | } |
2534 | 2523 | ||
2535 | static inline int security_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size) | ||
2536 | { | ||
2537 | return -EOPNOTSUPP; | ||
2538 | } | ||
2539 | |||
2540 | static inline int security_msg_msg_alloc (struct msg_msg * msg) | 2524 | static inline int security_msg_msg_alloc (struct msg_msg * msg) |
2541 | { | 2525 | { |
2542 | return 0; | 2526 | return 0; |
diff --git a/include/linux/selinux.h b/include/linux/selinux.h index 84a6c7404687..413d66773b91 100644 --- a/include/linux/selinux.h +++ b/include/linux/selinux.h | |||
@@ -16,6 +16,7 @@ | |||
16 | struct selinux_audit_rule; | 16 | struct selinux_audit_rule; |
17 | struct audit_context; | 17 | struct audit_context; |
18 | struct inode; | 18 | struct inode; |
19 | struct kern_ipc_perm; | ||
19 | 20 | ||
20 | #ifdef CONFIG_SECURITY_SELINUX | 21 | #ifdef CONFIG_SECURITY_SELINUX |
21 | 22 | ||
@@ -98,6 +99,15 @@ int selinux_ctxid_to_string(u32 ctxid, char **ctx, u32 *ctxlen); | |||
98 | */ | 99 | */ |
99 | void selinux_get_inode_sid(const struct inode *inode, u32 *sid); | 100 | void selinux_get_inode_sid(const struct inode *inode, u32 *sid); |
100 | 101 | ||
102 | /** | ||
103 | * selinux_get_ipc_sid - get the ipc security context ID | ||
104 | * @ipcp: ipc structure to get the sid from. | ||
105 | * @sid: pointer to security context ID to be filled in. | ||
106 | * | ||
107 | * Returns nothing | ||
108 | */ | ||
109 | void selinux_get_ipc_sid(const struct kern_ipc_perm *ipcp, u32 *sid); | ||
110 | |||
101 | #else | 111 | #else |
102 | 112 | ||
103 | static inline int selinux_audit_rule_init(u32 field, u32 op, | 113 | static inline int selinux_audit_rule_init(u32 field, u32 op, |
@@ -141,6 +151,11 @@ static inline void selinux_get_inode_sid(const struct inode *inode, u32 *sid) | |||
141 | *sid = 0; | 151 | *sid = 0; |
142 | } | 152 | } |
143 | 153 | ||
154 | static inline void selinux_get_ipc_sid(const struct kern_ipc_perm *ipcp, u32 *sid) | ||
155 | { | ||
156 | *sid = 0; | ||
157 | } | ||
158 | |||
144 | #endif /* CONFIG_SECURITY_SELINUX */ | 159 | #endif /* CONFIG_SECURITY_SELINUX */ |
145 | 160 | ||
146 | #endif /* _LINUX_SELINUX_H */ | 161 | #endif /* _LINUX_SELINUX_H */ |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 2e123a8a0d60..b4f7223811fe 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -107,7 +107,7 @@ struct audit_aux_data_ipcctl { | |||
107 | uid_t uid; | 107 | uid_t uid; |
108 | gid_t gid; | 108 | gid_t gid; |
109 | mode_t mode; | 109 | mode_t mode; |
110 | char *ctx; | 110 | u32 osid; |
111 | }; | 111 | }; |
112 | 112 | ||
113 | struct audit_aux_data_socketcall { | 113 | struct audit_aux_data_socketcall { |
@@ -432,11 +432,6 @@ static inline void audit_free_aux(struct audit_context *context) | |||
432 | dput(axi->dentry); | 432 | dput(axi->dentry); |
433 | mntput(axi->mnt); | 433 | mntput(axi->mnt); |
434 | } | 434 | } |
435 | if ( aux->type == AUDIT_IPC ) { | ||
436 | struct audit_aux_data_ipcctl *axi = (void *)aux; | ||
437 | if (axi->ctx) | ||
438 | kfree(axi->ctx); | ||
439 | } | ||
440 | 435 | ||
441 | context->aux = aux->next; | 436 | context->aux = aux->next; |
442 | kfree(aux); | 437 | kfree(aux); |
@@ -584,7 +579,7 @@ static void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk | |||
584 | 579 | ||
585 | static void audit_log_exit(struct audit_context *context, struct task_struct *tsk) | 580 | static void audit_log_exit(struct audit_context *context, struct task_struct *tsk) |
586 | { | 581 | { |
587 | int i; | 582 | int i, call_panic = 0; |
588 | struct audit_buffer *ab; | 583 | struct audit_buffer *ab; |
589 | struct audit_aux_data *aux; | 584 | struct audit_aux_data *aux; |
590 | const char *tty; | 585 | const char *tty; |
@@ -635,8 +630,20 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
635 | case AUDIT_IPC: { | 630 | case AUDIT_IPC: { |
636 | struct audit_aux_data_ipcctl *axi = (void *)aux; | 631 | struct audit_aux_data_ipcctl *axi = (void *)aux; |
637 | audit_log_format(ab, | 632 | audit_log_format(ab, |
638 | " qbytes=%lx iuid=%u igid=%u mode=%x obj=%s", | 633 | " qbytes=%lx iuid=%u igid=%u mode=%x", |
639 | axi->qbytes, axi->uid, axi->gid, axi->mode, axi->ctx); | 634 | axi->qbytes, axi->uid, axi->gid, axi->mode); |
635 | if (axi->osid != 0) { | ||
636 | char *ctx = NULL; | ||
637 | u32 len; | ||
638 | if (selinux_ctxid_to_string( | ||
639 | axi->osid, &ctx, &len)) { | ||
640 | audit_log_format(ab, " obj=%u", | ||
641 | axi->osid); | ||
642 | call_panic = 1; | ||
643 | } else | ||
644 | audit_log_format(ab, " obj=%s", ctx); | ||
645 | kfree(ctx); | ||
646 | } | ||
640 | break; } | 647 | break; } |
641 | 648 | ||
642 | case AUDIT_SOCKETCALL: { | 649 | case AUDIT_SOCKETCALL: { |
@@ -671,7 +678,6 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
671 | } | 678 | } |
672 | } | 679 | } |
673 | for (i = 0; i < context->name_count; i++) { | 680 | for (i = 0; i < context->name_count; i++) { |
674 | int call_panic = 0; | ||
675 | unsigned long ino = context->names[i].ino; | 681 | unsigned long ino = context->names[i].ino; |
676 | unsigned long pino = context->names[i].pino; | 682 | unsigned long pino = context->names[i].pino; |
677 | 683 | ||
@@ -708,16 +714,16 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
708 | context->names[i].osid, &ctx, &len)) { | 714 | context->names[i].osid, &ctx, &len)) { |
709 | audit_log_format(ab, " obj=%u", | 715 | audit_log_format(ab, " obj=%u", |
710 | context->names[i].osid); | 716 | context->names[i].osid); |
711 | call_panic = 1; | 717 | call_panic = 2; |
712 | } else | 718 | } else |
713 | audit_log_format(ab, " obj=%s", ctx); | 719 | audit_log_format(ab, " obj=%s", ctx); |
714 | kfree(ctx); | 720 | kfree(ctx); |
715 | } | 721 | } |
716 | 722 | ||
717 | audit_log_end(ab); | 723 | audit_log_end(ab); |
718 | if (call_panic) | ||
719 | audit_panic("error converting sid to string"); | ||
720 | } | 724 | } |
725 | if (call_panic) | ||
726 | audit_panic("error converting sid to string"); | ||
721 | } | 727 | } |
722 | 728 | ||
723 | /** | 729 | /** |
@@ -951,7 +957,7 @@ void audit_putname(const char *name) | |||
951 | #endif | 957 | #endif |
952 | } | 958 | } |
953 | 959 | ||
954 | void audit_inode_context(int idx, const struct inode *inode) | 960 | static void audit_inode_context(int idx, const struct inode *inode) |
955 | { | 961 | { |
956 | struct audit_context *context = current->audit_context; | 962 | struct audit_context *context = current->audit_context; |
957 | 963 | ||
@@ -1141,38 +1147,6 @@ uid_t audit_get_loginuid(struct audit_context *ctx) | |||
1141 | return ctx ? ctx->loginuid : -1; | 1147 | return ctx ? ctx->loginuid : -1; |
1142 | } | 1148 | } |
1143 | 1149 | ||
1144 | static char *audit_ipc_context(struct kern_ipc_perm *ipcp) | ||
1145 | { | ||
1146 | struct audit_context *context = current->audit_context; | ||
1147 | char *ctx = NULL; | ||
1148 | int len = 0; | ||
1149 | |||
1150 | if (likely(!context)) | ||
1151 | return NULL; | ||
1152 | |||
1153 | len = security_ipc_getsecurity(ipcp, NULL, 0); | ||
1154 | if (len == -EOPNOTSUPP) | ||
1155 | goto ret; | ||
1156 | if (len < 0) | ||
1157 | goto error_path; | ||
1158 | |||
1159 | ctx = kmalloc(len, GFP_ATOMIC); | ||
1160 | if (!ctx) | ||
1161 | goto error_path; | ||
1162 | |||
1163 | len = security_ipc_getsecurity(ipcp, ctx, len); | ||
1164 | if (len < 0) | ||
1165 | goto error_path; | ||
1166 | |||
1167 | return ctx; | ||
1168 | |||
1169 | error_path: | ||
1170 | kfree(ctx); | ||
1171 | audit_panic("error in audit_ipc_context"); | ||
1172 | ret: | ||
1173 | return NULL; | ||
1174 | } | ||
1175 | |||
1176 | /** | 1150 | /** |
1177 | * audit_ipc_perms - record audit data for ipc | 1151 | * audit_ipc_perms - record audit data for ipc |
1178 | * @qbytes: msgq bytes | 1152 | * @qbytes: msgq bytes |
@@ -1198,7 +1172,7 @@ int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode, str | |||
1198 | ax->uid = uid; | 1172 | ax->uid = uid; |
1199 | ax->gid = gid; | 1173 | ax->gid = gid; |
1200 | ax->mode = mode; | 1174 | ax->mode = mode; |
1201 | ax->ctx = audit_ipc_context(ipcp); | 1175 | selinux_get_ipc_sid(ipcp, &ax->osid); |
1202 | 1176 | ||
1203 | ax->d.type = AUDIT_IPC; | 1177 | ax->d.type = AUDIT_IPC; |
1204 | ax->d.next = context->aux; | 1178 | ax->d.next = context->aux; |
diff --git a/security/dummy.c b/security/dummy.c index fd99429278e9..8ccccccc12ac 100644 --- a/security/dummy.c +++ b/security/dummy.c | |||
@@ -563,11 +563,6 @@ static int dummy_ipc_permission (struct kern_ipc_perm *ipcp, short flag) | |||
563 | return 0; | 563 | return 0; |
564 | } | 564 | } |
565 | 565 | ||
566 | static int dummy_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size) | ||
567 | { | ||
568 | return -EOPNOTSUPP; | ||
569 | } | ||
570 | |||
571 | static int dummy_msg_msg_alloc_security (struct msg_msg *msg) | 566 | static int dummy_msg_msg_alloc_security (struct msg_msg *msg) |
572 | { | 567 | { |
573 | return 0; | 568 | return 0; |
@@ -976,7 +971,6 @@ void security_fixup_ops (struct security_operations *ops) | |||
976 | set_to_dummy_if_null(ops, task_reparent_to_init); | 971 | set_to_dummy_if_null(ops, task_reparent_to_init); |
977 | set_to_dummy_if_null(ops, task_to_inode); | 972 | set_to_dummy_if_null(ops, task_to_inode); |
978 | set_to_dummy_if_null(ops, ipc_permission); | 973 | set_to_dummy_if_null(ops, ipc_permission); |
979 | set_to_dummy_if_null(ops, ipc_getsecurity); | ||
980 | set_to_dummy_if_null(ops, msg_msg_alloc_security); | 974 | set_to_dummy_if_null(ops, msg_msg_alloc_security); |
981 | set_to_dummy_if_null(ops, msg_msg_free_security); | 975 | set_to_dummy_if_null(ops, msg_msg_free_security); |
982 | set_to_dummy_if_null(ops, msg_queue_alloc_security); | 976 | set_to_dummy_if_null(ops, msg_queue_alloc_security); |
diff --git a/security/selinux/exports.c b/security/selinux/exports.c index 07ddce7bf374..7357cf247f60 100644 --- a/security/selinux/exports.c +++ b/security/selinux/exports.c | |||
@@ -15,6 +15,7 @@ | |||
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 | #include <linux/fs.h> |
18 | #include <linux/ipc.h> | ||
18 | 19 | ||
19 | #include "security.h" | 20 | #include "security.h" |
20 | #include "objsec.h" | 21 | #include "objsec.h" |
@@ -50,3 +51,13 @@ void selinux_get_inode_sid(const struct inode *inode, u32 *sid) | |||
50 | *sid = 0; | 51 | *sid = 0; |
51 | } | 52 | } |
52 | 53 | ||
54 | void selinux_get_ipc_sid(const struct kern_ipc_perm *ipcp, u32 *sid) | ||
55 | { | ||
56 | if (selinux_enabled) { | ||
57 | struct ipc_security_struct *isec = ipcp->security; | ||
58 | *sid = isec->sid; | ||
59 | return; | ||
60 | } | ||
61 | *sid = 0; | ||
62 | } | ||
63 | |||
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index b61b9554bc27..3cf368a16448 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -4052,13 +4052,6 @@ static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag) | |||
4052 | return ipc_has_perm(ipcp, av); | 4052 | return ipc_has_perm(ipcp, av); |
4053 | } | 4053 | } |
4054 | 4054 | ||
4055 | static int selinux_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size) | ||
4056 | { | ||
4057 | struct ipc_security_struct *isec = ipcp->security; | ||
4058 | |||
4059 | return selinux_getsecurity(isec->sid, buffer, size); | ||
4060 | } | ||
4061 | |||
4062 | /* module stacking operations */ | 4055 | /* module stacking operations */ |
4063 | static int selinux_register_security (const char *name, struct security_operations *ops) | 4056 | static int selinux_register_security (const char *name, struct security_operations *ops) |
4064 | { | 4057 | { |
@@ -4321,7 +4314,6 @@ static struct security_operations selinux_ops = { | |||
4321 | .task_to_inode = selinux_task_to_inode, | 4314 | .task_to_inode = selinux_task_to_inode, |
4322 | 4315 | ||
4323 | .ipc_permission = selinux_ipc_permission, | 4316 | .ipc_permission = selinux_ipc_permission, |
4324 | .ipc_getsecurity = selinux_ipc_getsecurity, | ||
4325 | 4317 | ||
4326 | .msg_msg_alloc_security = selinux_msg_msg_alloc_security, | 4318 | .msg_msg_alloc_security = selinux_msg_msg_alloc_security, |
4327 | .msg_msg_free_security = selinux_msg_msg_free_security, | 4319 | .msg_msg_free_security = selinux_msg_msg_free_security, |