aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/auditsc.c
diff options
context:
space:
mode:
authorGeorge C. Wilson <ltcgcw@us.ibm.com>2006-05-24 17:09:55 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2006-06-20 05:25:26 -0400
commit20ca73bc792be9625af184cbec36e1372611d1c3 (patch)
tree98a1232ad3c9baa14676b2b48fab79a3df4a20b0 /kernel/auditsc.c
parent8ba8e0fbe6321961f6ba04e2fd7215b37d935c83 (diff)
[PATCH] Audit of POSIX Message Queue Syscalls v.2
This patch adds audit support to POSIX message queues. It applies cleanly to the lspp.b15 branch of Al Viro's git tree. There are new auxiliary data structures, and collection and emission routines in kernel/auditsc.c. New hooks in ipc/mqueue.c collect arguments from the syscalls. I tested the patch by building the examples from the POSIX MQ library tarball. Build them -lrt, not against the old MQ library in the tarball. Here's the URL: http://www.geocities.com/wronski12/posix_ipc/libmqueue-4.41.tar.gz Do auditctl -a exit,always -S for mq_open, mq_timedsend, mq_timedreceive, mq_notify, mq_getsetattr. mq_unlink has no new hooks. Please see the corresponding userspace patch to get correct output from auditd for the new record types. [fixes folded] Signed-off-by: George Wilson <ltcgcw@us.ibm.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'kernel/auditsc.c')
-rw-r--r--kernel/auditsc.c274
1 files changed, 273 insertions, 1 deletions
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 4503c4663cf8..14e295a4121b 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina. 4 * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
5 * Copyright 2005 Hewlett-Packard Development Company, L.P. 5 * Copyright 2005 Hewlett-Packard Development Company, L.P.
6 * Copyright (C) 2005 IBM Corporation 6 * Copyright (C) 2005, 2006 IBM Corporation
7 * All Rights Reserved. 7 * All Rights Reserved.
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
@@ -29,6 +29,9 @@
29 * this file -- see entry.S) is based on a GPL'd patch written by 29 * this file -- see entry.S) is based on a GPL'd patch written by
30 * okir@suse.de and Copyright 2003 SuSE Linux AG. 30 * okir@suse.de and Copyright 2003 SuSE Linux AG.
31 * 31 *
32 * POSIX message queue support added by George Wilson <ltcgcw@us.ibm.com>,
33 * 2006.
34 *
32 * The support of additional filter rules compares (>, <, >=, <=) was 35 * The support of additional filter rules compares (>, <, >=, <=) was
33 * added by Dustin Kirkland <dustin.kirkland@us.ibm.com>, 2005. 36 * added by Dustin Kirkland <dustin.kirkland@us.ibm.com>, 2005.
34 * 37 *
@@ -49,6 +52,7 @@
49#include <linux/module.h> 52#include <linux/module.h>
50#include <linux/mount.h> 53#include <linux/mount.h>
51#include <linux/socket.h> 54#include <linux/socket.h>
55#include <linux/mqueue.h>
52#include <linux/audit.h> 56#include <linux/audit.h>
53#include <linux/personality.h> 57#include <linux/personality.h>
54#include <linux/time.h> 58#include <linux/time.h>
@@ -102,6 +106,33 @@ struct audit_aux_data {
102 106
103#define AUDIT_AUX_IPCPERM 0 107#define AUDIT_AUX_IPCPERM 0
104 108
109struct audit_aux_data_mq_open {
110 struct audit_aux_data d;
111 int oflag;
112 mode_t mode;
113 struct mq_attr attr;
114};
115
116struct audit_aux_data_mq_sendrecv {
117 struct audit_aux_data d;
118 mqd_t mqdes;
119 size_t msg_len;
120 unsigned int msg_prio;
121 struct timespec abs_timeout;
122};
123
124struct audit_aux_data_mq_notify {
125 struct audit_aux_data d;
126 mqd_t mqdes;
127 struct sigevent notification;
128};
129
130struct audit_aux_data_mq_getsetattr {
131 struct audit_aux_data d;
132 mqd_t mqdes;
133 struct mq_attr mqstat;
134};
135
105struct audit_aux_data_ipcctl { 136struct audit_aux_data_ipcctl {
106 struct audit_aux_data d; 137 struct audit_aux_data d;
107 struct ipc_perm p; 138 struct ipc_perm p;
@@ -644,6 +675,43 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
644 continue; /* audit_panic has been called */ 675 continue; /* audit_panic has been called */
645 676
646 switch (aux->type) { 677 switch (aux->type) {
678 case AUDIT_MQ_OPEN: {
679 struct audit_aux_data_mq_open *axi = (void *)aux;
680 audit_log_format(ab,
681 "oflag=0x%x mode=%#o mq_flags=0x%lx mq_maxmsg=%ld "
682 "mq_msgsize=%ld mq_curmsgs=%ld",
683 axi->oflag, axi->mode, axi->attr.mq_flags,
684 axi->attr.mq_maxmsg, axi->attr.mq_msgsize,
685 axi->attr.mq_curmsgs);
686 break; }
687
688 case AUDIT_MQ_SENDRECV: {
689 struct audit_aux_data_mq_sendrecv *axi = (void *)aux;
690 audit_log_format(ab,
691 "mqdes=%d msg_len=%zd msg_prio=%u "
692 "abs_timeout_sec=%ld abs_timeout_nsec=%ld",
693 axi->mqdes, axi->msg_len, axi->msg_prio,
694 axi->abs_timeout.tv_sec, axi->abs_timeout.tv_nsec);
695 break; }
696
697 case AUDIT_MQ_NOTIFY: {
698 struct audit_aux_data_mq_notify *axi = (void *)aux;
699 audit_log_format(ab,
700 "mqdes=%d sigev_signo=%d",
701 axi->mqdes,
702 axi->notification.sigev_signo);
703 break; }
704
705 case AUDIT_MQ_GETSETATTR: {
706 struct audit_aux_data_mq_getsetattr *axi = (void *)aux;
707 audit_log_format(ab,
708 "mqdes=%d mq_flags=0x%lx mq_maxmsg=%ld mq_msgsize=%ld "
709 "mq_curmsgs=%ld ",
710 axi->mqdes,
711 axi->mqstat.mq_flags, axi->mqstat.mq_maxmsg,
712 axi->mqstat.mq_msgsize, axi->mqstat.mq_curmsgs);
713 break; }
714
647 case AUDIT_IPC: { 715 case AUDIT_IPC: {
648 struct audit_aux_data_ipcctl *axi = (void *)aux; 716 struct audit_aux_data_ipcctl *axi = (void *)aux;
649 audit_log_format(ab, 717 audit_log_format(ab,
@@ -1183,6 +1251,210 @@ uid_t audit_get_loginuid(struct audit_context *ctx)
1183} 1251}
1184 1252
1185/** 1253/**
1254 * __audit_mq_open - record audit data for a POSIX MQ open
1255 * @oflag: open flag
1256 * @mode: mode bits
1257 * @u_attr: queue attributes
1258 *
1259 * Returns 0 for success or NULL context or < 0 on error.
1260 */
1261int __audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr)
1262{
1263 struct audit_aux_data_mq_open *ax;
1264 struct audit_context *context = current->audit_context;
1265
1266 if (!audit_enabled)
1267 return 0;
1268
1269 if (likely(!context))
1270 return 0;
1271
1272 ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
1273 if (!ax)
1274 return -ENOMEM;
1275
1276 if (u_attr != NULL) {
1277 if (copy_from_user(&ax->attr, u_attr, sizeof(ax->attr))) {
1278 kfree(ax);
1279 return -EFAULT;
1280 }
1281 } else
1282 memset(&ax->attr, 0, sizeof(ax->attr));
1283
1284 ax->oflag = oflag;
1285 ax->mode = mode;
1286
1287 ax->d.type = AUDIT_MQ_OPEN;
1288 ax->d.next = context->aux;
1289 context->aux = (void *)ax;
1290 return 0;
1291}
1292
1293/**
1294 * __audit_mq_timedsend - record audit data for a POSIX MQ timed send
1295 * @mqdes: MQ descriptor
1296 * @msg_len: Message length
1297 * @msg_prio: Message priority
1298 * @abs_timeout: Message timeout in absolute time
1299 *
1300 * Returns 0 for success or NULL context or < 0 on error.
1301 */
1302int __audit_mq_timedsend(mqd_t mqdes, size_t msg_len, unsigned int msg_prio,
1303 const struct timespec __user *u_abs_timeout)
1304{
1305 struct audit_aux_data_mq_sendrecv *ax;
1306 struct audit_context *context = current->audit_context;
1307
1308 if (!audit_enabled)
1309 return 0;
1310
1311 if (likely(!context))
1312 return 0;
1313
1314 ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
1315 if (!ax)
1316 return -ENOMEM;
1317
1318 if (u_abs_timeout != NULL) {
1319 if (copy_from_user(&ax->abs_timeout, u_abs_timeout, sizeof(ax->abs_timeout))) {
1320 kfree(ax);
1321 return -EFAULT;
1322 }
1323 } else
1324 memset(&ax->abs_timeout, 0, sizeof(ax->abs_timeout));
1325
1326 ax->mqdes = mqdes;
1327 ax->msg_len = msg_len;
1328 ax->msg_prio = msg_prio;
1329
1330 ax->d.type = AUDIT_MQ_SENDRECV;
1331 ax->d.next = context->aux;
1332 context->aux = (void *)ax;
1333 return 0;
1334}
1335
1336/**
1337 * __audit_mq_timedreceive - record audit data for a POSIX MQ timed receive
1338 * @mqdes: MQ descriptor
1339 * @msg_len: Message length
1340 * @msg_prio: Message priority
1341 * @abs_timeout: Message timeout in absolute time
1342 *
1343 * Returns 0 for success or NULL context or < 0 on error.
1344 */
1345int __audit_mq_timedreceive(mqd_t mqdes, size_t msg_len,
1346 unsigned int __user *u_msg_prio,
1347 const struct timespec __user *u_abs_timeout)
1348{
1349 struct audit_aux_data_mq_sendrecv *ax;
1350 struct audit_context *context = current->audit_context;
1351
1352 if (!audit_enabled)
1353 return 0;
1354
1355 if (likely(!context))
1356 return 0;
1357
1358 ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
1359 if (!ax)
1360 return -ENOMEM;
1361
1362 if (u_msg_prio != NULL) {
1363 if (get_user(ax->msg_prio, u_msg_prio)) {
1364 kfree(ax);
1365 return -EFAULT;
1366 }
1367 } else
1368 ax->msg_prio = 0;
1369
1370 if (u_abs_timeout != NULL) {
1371 if (copy_from_user(&ax->abs_timeout, u_abs_timeout, sizeof(ax->abs_timeout))) {
1372 kfree(ax);
1373 return -EFAULT;
1374 }
1375 } else
1376 memset(&ax->abs_timeout, 0, sizeof(ax->abs_timeout));
1377
1378 ax->mqdes = mqdes;
1379 ax->msg_len = msg_len;
1380
1381 ax->d.type = AUDIT_MQ_SENDRECV;
1382 ax->d.next = context->aux;
1383 context->aux = (void *)ax;
1384 return 0;
1385}
1386
1387/**
1388 * __audit_mq_notify - record audit data for a POSIX MQ notify
1389 * @mqdes: MQ descriptor
1390 * @u_notification: Notification event
1391 *
1392 * Returns 0 for success or NULL context or < 0 on error.
1393 */
1394
1395int __audit_mq_notify(mqd_t mqdes, const struct sigevent __user *u_notification)
1396{
1397 struct audit_aux_data_mq_notify *ax;
1398 struct audit_context *context = current->audit_context;
1399
1400 if (!audit_enabled)
1401 return 0;
1402
1403 if (likely(!context))
1404 return 0;
1405
1406 ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
1407 if (!ax)
1408 return -ENOMEM;
1409
1410 if (u_notification != NULL) {
1411 if (copy_from_user(&ax->notification, u_notification, sizeof(ax->notification))) {
1412 kfree(ax);
1413 return -EFAULT;
1414 }
1415 } else
1416 memset(&ax->notification, 0, sizeof(ax->notification));
1417
1418 ax->mqdes = mqdes;
1419
1420 ax->d.type = AUDIT_MQ_NOTIFY;
1421 ax->d.next = context->aux;
1422 context->aux = (void *)ax;
1423 return 0;
1424}
1425
1426/**
1427 * __audit_mq_getsetattr - record audit data for a POSIX MQ get/set attribute
1428 * @mqdes: MQ descriptor
1429 * @mqstat: MQ flags
1430 *
1431 * Returns 0 for success or NULL context or < 0 on error.
1432 */
1433int __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat)
1434{
1435 struct audit_aux_data_mq_getsetattr *ax;
1436 struct audit_context *context = current->audit_context;
1437
1438 if (!audit_enabled)
1439 return 0;
1440
1441 if (likely(!context))
1442 return 0;
1443
1444 ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
1445 if (!ax)
1446 return -ENOMEM;
1447
1448 ax->mqdes = mqdes;
1449 ax->mqstat = *mqstat;
1450
1451 ax->d.type = AUDIT_MQ_GETSETATTR;
1452 ax->d.next = context->aux;
1453 context->aux = (void *)ax;
1454 return 0;
1455}
1456
1457/**
1186 * audit_ipc_obj - record audit data for ipc object 1458 * audit_ipc_obj - record audit data for ipc object
1187 * @ipcp: ipc permissions 1459 * @ipcp: ipc permissions
1188 * 1460 *