Commit 9c7aa6aa74fa8a5cda36e54cbbe4fffe0214497d

Authored by Steve Grubb
Committed by Al Viro
1 parent 1b50eed9ca

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

Showing 6 changed files with 47 additions and 77 deletions Side-by-side Diff

include/linux/security.h
... ... @@ -869,11 +869,6 @@
869 869 * @ipcp contains the kernel IPC permission structure
870 870 * @flag contains the desired (requested) permission set
871 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 873 * Security hooks for individual messages held in System V IPC message queues
879 874 * @msg_msg_alloc_security:
... ... @@ -1223,7 +1218,6 @@
1223 1218 void (*task_to_inode)(struct task_struct *p, struct inode *inode);
1224 1219  
1225 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 1222 int (*msg_msg_alloc_security) (struct msg_msg * msg);
1229 1223 void (*msg_msg_free_security) (struct msg_msg * msg);
... ... @@ -1887,11 +1881,6 @@
1887 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 1884 static inline int security_msg_msg_alloc (struct msg_msg * msg)
1896 1885 {
1897 1886 return security_ops->msg_msg_alloc_security (msg);
... ... @@ -2530,11 +2519,6 @@
2530 2519 short flag)
2531 2520 {
2532 2521 return 0;
2533   -}
2534   -
2535   -static inline int security_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size)
2536   -{
2537   - return -EOPNOTSUPP;
2538 2522 }
2539 2523  
2540 2524 static inline int security_msg_msg_alloc (struct msg_msg * msg)
include/linux/selinux.h
... ... @@ -16,6 +16,7 @@
16 16 struct selinux_audit_rule;
17 17 struct audit_context;
18 18 struct inode;
  19 +struct kern_ipc_perm;
19 20  
20 21 #ifdef CONFIG_SECURITY_SELINUX
21 22  
... ... @@ -98,6 +99,15 @@
98 99 */
99 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 111 #else
102 112  
103 113 static inline int selinux_audit_rule_init(u32 field, u32 op,
... ... @@ -137,6 +147,11 @@
137 147 }
138 148  
139 149 static inline void selinux_get_inode_sid(const struct inode *inode, u32 *sid)
  150 +{
  151 + *sid = 0;
  152 +}
  153 +
  154 +static inline void selinux_get_ipc_sid(const struct kern_ipc_perm *ipcp, u32 *sid)
140 155 {
141 156 *sid = 0;
142 157 }
... ... @@ -107,7 +107,7 @@
107 107 uid_t uid;
108 108 gid_t gid;
109 109 mode_t mode;
110   - char *ctx;
  110 + u32 osid;
111 111 };
112 112  
113 113 struct audit_aux_data_socketcall {
... ... @@ -432,11 +432,6 @@
432 432 dput(axi->dentry);
433 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 436 context->aux = aux->next;
442 437 kfree(aux);
... ... @@ -584,7 +579,7 @@
584 579  
585 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 583 struct audit_buffer *ab;
589 584 struct audit_aux_data *aux;
590 585 const char *tty;
... ... @@ -635,8 +630,20 @@
635 630 case AUDIT_IPC: {
636 631 struct audit_aux_data_ipcctl *axi = (void *)aux;
637 632 audit_log_format(ab,
638   - " qbytes=%lx iuid=%u igid=%u mode=%x obj=%s",
639   - axi->qbytes, axi->uid, axi->gid, axi->mode, axi->ctx);
  633 + " qbytes=%lx iuid=%u igid=%u mode=%x",
  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 647 break; }
641 648  
642 649 case AUDIT_SOCKETCALL: {
... ... @@ -671,7 +678,6 @@
671 678 }
672 679 }
673 680 for (i = 0; i < context->name_count; i++) {
674   - int call_panic = 0;
675 681 unsigned long ino = context->names[i].ino;
676 682 unsigned long pino = context->names[i].pino;
677 683  
678 684  
679 685  
... ... @@ -708,16 +714,16 @@
708 714 context->names[i].osid, &ctx, &len)) {
709 715 audit_log_format(ab, " obj=%u",
710 716 context->names[i].osid);
711   - call_panic = 1;
  717 + call_panic = 2;
712 718 } else
713 719 audit_log_format(ab, " obj=%s", ctx);
714 720 kfree(ctx);
715 721 }
716 722  
717 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 @@
951 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 962 struct audit_context *context = current->audit_context;
957 963  
... ... @@ -1141,38 +1147,6 @@
1141 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 1151 * audit_ipc_perms - record audit data for ipc
1178 1152 * @qbytes: msgq bytes
... ... @@ -1198,7 +1172,7 @@
1198 1172 ax->uid = uid;
1199 1173 ax->gid = gid;
1200 1174 ax->mode = mode;
1201   - ax->ctx = audit_ipc_context(ipcp);
  1175 + selinux_get_ipc_sid(ipcp, &ax->osid);
1202 1176  
1203 1177 ax->d.type = AUDIT_IPC;
1204 1178 ax->d.next = context->aux;
... ... @@ -563,11 +563,6 @@
563 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 566 static int dummy_msg_msg_alloc_security (struct msg_msg *msg)
572 567 {
573 568 return 0;
... ... @@ -976,7 +971,6 @@
976 971 set_to_dummy_if_null(ops, task_reparent_to_init);
977 972 set_to_dummy_if_null(ops, task_to_inode);
978 973 set_to_dummy_if_null(ops, ipc_permission);
979   - set_to_dummy_if_null(ops, ipc_getsecurity);
980 974 set_to_dummy_if_null(ops, msg_msg_alloc_security);
981 975 set_to_dummy_if_null(ops, msg_msg_free_security);
982 976 set_to_dummy_if_null(ops, msg_queue_alloc_security);
security/selinux/exports.c
... ... @@ -15,6 +15,7 @@
15 15 #include <linux/module.h>
16 16 #include <linux/selinux.h>
17 17 #include <linux/fs.h>
  18 +#include <linux/ipc.h>
18 19  
19 20 #include "security.h"
20 21 #include "objsec.h"
... ... @@ -44,6 +45,16 @@
44 45 {
45 46 if (selinux_enabled) {
46 47 struct inode_security_struct *isec = inode->i_security;
  48 + *sid = isec->sid;
  49 + return;
  50 + }
  51 + *sid = 0;
  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;
47 58 *sid = isec->sid;
48 59 return;
49 60 }
security/selinux/hooks.c
... ... @@ -4052,13 +4052,6 @@
4052 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 4055 /* module stacking operations */
4063 4056 static int selinux_register_security (const char *name, struct security_operations *ops)
4064 4057 {
... ... @@ -4321,7 +4314,6 @@
4321 4314 .task_to_inode = selinux_task_to_inode,
4322 4315  
4323 4316 .ipc_permission = selinux_ipc_permission,
4324   - .ipc_getsecurity = selinux_ipc_getsecurity,
4325 4317  
4326 4318 .msg_msg_alloc_security = selinux_msg_msg_alloc_security,
4327 4319 .msg_msg_free_security = selinux_msg_msg_free_security,