diff options
-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, |