diff options
author | Steve Grubb <sgrubb@redhat.com> | 2006-04-02 17:07:33 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2006-05-01 06:10:04 -0400 |
commit | 073115d6b29c7910feaa08241c6484637f5ca958 (patch) | |
tree | 5fd32da9f54b3c12b65d3c0142fb9bdf87dc01c3 /kernel | |
parent | ce29b682e228c70cdc91a1b2935c5adb2087bab8 (diff) |
[PATCH] Rework of IPC auditing
1) The audit_ipc_perms() function has been split into two different
functions:
- audit_ipc_obj()
- audit_ipc_set_perm()
There's a key shift here... The audit_ipc_obj() collects the uid, gid,
mode, and SElinux context label of the current ipc object. This
audit_ipc_obj() hook is now found in several places. Most notably, it
is hooked in ipcperms(), which is called in various places around the
ipc code permforming a MAC check. Additionally there are several places
where *checkid() is used to validate that an operation is being
performed on a valid object while not necessarily having a nearby
ipcperms() call. In these locations, audit_ipc_obj() is called to
ensure that the information is captured by the audit system.
The audit_set_new_perm() function is called any time the permissions on
the ipc object changes. In this case, the NEW permissions are recorded
(and note that an audit_ipc_obj() call exists just a few lines before
each instance).
2) Support for an AUDIT_IPC_SET_PERM audit message type. This allows
for separate auxiliary audit records for normal operations on an IPC
object and permissions changes. Note that the same struct
audit_aux_data_ipcctl is used and populated, however there are separate
audit_log_format statements based on the type of the message. Finally,
the AUDIT_IPC block of code in audit_free_aux() was extended to handle
aux messages of this new type. No more mem leaks I hope ;-)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/auditsc.c | 54 |
1 files changed, 51 insertions, 3 deletions
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index d94e0404113c..a300736ee037 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -646,6 +646,25 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
646 | } | 646 | } |
647 | break; } | 647 | break; } |
648 | 648 | ||
649 | case AUDIT_IPC_SET_PERM: { | ||
650 | struct audit_aux_data_ipcctl *axi = (void *)aux; | ||
651 | audit_log_format(ab, | ||
652 | " new qbytes=%lx new iuid=%u new igid=%u new mode=%x", | ||
653 | axi->qbytes, axi->uid, axi->gid, axi->mode); | ||
654 | if (axi->osid != 0) { | ||
655 | char *ctx = NULL; | ||
656 | u32 len; | ||
657 | if (selinux_ctxid_to_string( | ||
658 | axi->osid, &ctx, &len)) { | ||
659 | audit_log_format(ab, " osid=%u", | ||
660 | axi->osid); | ||
661 | call_panic = 1; | ||
662 | } else | ||
663 | audit_log_format(ab, " obj=%s", ctx); | ||
664 | kfree(ctx); | ||
665 | } | ||
666 | break; } | ||
667 | |||
649 | case AUDIT_SOCKETCALL: { | 668 | case AUDIT_SOCKETCALL: { |
650 | int i; | 669 | int i; |
651 | struct audit_aux_data_socketcall *axs = (void *)aux; | 670 | struct audit_aux_data_socketcall *axs = (void *)aux; |
@@ -1148,7 +1167,36 @@ uid_t audit_get_loginuid(struct audit_context *ctx) | |||
1148 | } | 1167 | } |
1149 | 1168 | ||
1150 | /** | 1169 | /** |
1151 | * audit_ipc_perms - record audit data for ipc | 1170 | * audit_ipc_obj - record audit data for ipc object |
1171 | * @ipcp: ipc permissions | ||
1172 | * | ||
1173 | * Returns 0 for success or NULL context or < 0 on error. | ||
1174 | */ | ||
1175 | int audit_ipc_obj(struct kern_ipc_perm *ipcp) | ||
1176 | { | ||
1177 | struct audit_aux_data_ipcctl *ax; | ||
1178 | struct audit_context *context = current->audit_context; | ||
1179 | |||
1180 | if (likely(!context)) | ||
1181 | return 0; | ||
1182 | |||
1183 | ax = kmalloc(sizeof(*ax), GFP_ATOMIC); | ||
1184 | if (!ax) | ||
1185 | return -ENOMEM; | ||
1186 | |||
1187 | ax->uid = ipcp->uid; | ||
1188 | ax->gid = ipcp->gid; | ||
1189 | ax->mode = ipcp->mode; | ||
1190 | selinux_get_ipc_sid(ipcp, &ax->osid); | ||
1191 | |||
1192 | ax->d.type = AUDIT_IPC; | ||
1193 | ax->d.next = context->aux; | ||
1194 | context->aux = (void *)ax; | ||
1195 | return 0; | ||
1196 | } | ||
1197 | |||
1198 | /** | ||
1199 | * audit_ipc_set_perm - record audit data for new ipc permissions | ||
1152 | * @qbytes: msgq bytes | 1200 | * @qbytes: msgq bytes |
1153 | * @uid: msgq user id | 1201 | * @uid: msgq user id |
1154 | * @gid: msgq group id | 1202 | * @gid: msgq group id |
@@ -1156,7 +1204,7 @@ uid_t audit_get_loginuid(struct audit_context *ctx) | |||
1156 | * | 1204 | * |
1157 | * Returns 0 for success or NULL context or < 0 on error. | 1205 | * Returns 0 for success or NULL context or < 0 on error. |
1158 | */ | 1206 | */ |
1159 | int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode, struct kern_ipc_perm *ipcp) | 1207 | int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode, struct kern_ipc_perm *ipcp) |
1160 | { | 1208 | { |
1161 | struct audit_aux_data_ipcctl *ax; | 1209 | struct audit_aux_data_ipcctl *ax; |
1162 | struct audit_context *context = current->audit_context; | 1210 | struct audit_context *context = current->audit_context; |
@@ -1174,7 +1222,7 @@ int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode, str | |||
1174 | ax->mode = mode; | 1222 | ax->mode = mode; |
1175 | selinux_get_ipc_sid(ipcp, &ax->osid); | 1223 | selinux_get_ipc_sid(ipcp, &ax->osid); |
1176 | 1224 | ||
1177 | ax->d.type = AUDIT_IPC; | 1225 | ax->d.type = AUDIT_IPC_SET_PERM; |
1178 | ax->d.next = context->aux; | 1226 | ax->d.next = context->aux; |
1179 | context->aux = (void *)ax; | 1227 | context->aux = (void *)ax; |
1180 | return 0; | 1228 | return 0; |