diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/auditsc.c | 274 |
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 | ||
109 | struct 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 | |||
116 | struct 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 | |||
124 | struct audit_aux_data_mq_notify { | ||
125 | struct audit_aux_data d; | ||
126 | mqd_t mqdes; | ||
127 | struct sigevent notification; | ||
128 | }; | ||
129 | |||
130 | struct audit_aux_data_mq_getsetattr { | ||
131 | struct audit_aux_data d; | ||
132 | mqd_t mqdes; | ||
133 | struct mq_attr mqstat; | ||
134 | }; | ||
135 | |||
105 | struct audit_aux_data_ipcctl { | 136 | struct 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 | */ | ||
1261 | int __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 | */ | ||
1302 | int __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 | */ | ||
1345 | int __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 | |||
1395 | int __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 | */ | ||
1433 | int __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 | * |