aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/security.h16
-rw-r--r--include/linux/selinux.h15
-rw-r--r--kernel/auditsc.c68
-rw-r--r--security/dummy.c6
-rw-r--r--security/selinux/exports.c11
-rw-r--r--security/selinux/hooks.c8
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
1890static 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
1895static inline int security_msg_msg_alloc (struct msg_msg * msg) 1884static 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
2535static inline int security_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size)
2536{
2537 return -EOPNOTSUPP;
2538}
2539
2540static inline int security_msg_msg_alloc (struct msg_msg * msg) 2524static 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 @@
16struct selinux_audit_rule; 16struct selinux_audit_rule;
17struct audit_context; 17struct audit_context;
18struct inode; 18struct inode;
19struct 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 */
99void selinux_get_inode_sid(const struct inode *inode, u32 *sid); 100void 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 */
109void selinux_get_ipc_sid(const struct kern_ipc_perm *ipcp, u32 *sid);
110
101#else 111#else
102 112
103static inline int selinux_audit_rule_init(u32 field, u32 op, 113static 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
154static 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
113struct audit_aux_data_socketcall { 113struct 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
585static void audit_log_exit(struct audit_context *context, struct task_struct *tsk) 580static 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
954void audit_inode_context(int idx, const struct inode *inode) 960static 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
1144static 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
1169error_path:
1170 kfree(ctx);
1171 audit_panic("error in audit_ipc_context");
1172ret:
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
566static int dummy_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size)
567{
568 return -EOPNOTSUPP;
569}
570
571static int dummy_msg_msg_alloc_security (struct msg_msg *msg) 566static 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
54void 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
4055static 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 */
4063static int selinux_register_security (const char *name, struct security_operations *ops) 4056static 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,