aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/audit.h46
-rw-r--r--ipc/mqueue.c22
-rw-r--r--kernel/auditsc.c274
3 files changed, 341 insertions, 1 deletions
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 4b62743b2e6d..7c8780b150e6 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -85,6 +85,10 @@
85#define AUDIT_CWD 1307 /* Current working directory */ 85#define AUDIT_CWD 1307 /* Current working directory */
86#define AUDIT_EXECVE 1309 /* execve arguments */ 86#define AUDIT_EXECVE 1309 /* execve arguments */
87#define AUDIT_IPC_SET_PERM 1311 /* IPC new permissions record type */ 87#define AUDIT_IPC_SET_PERM 1311 /* IPC new permissions record type */
88#define AUDIT_MQ_OPEN 1312 /* POSIX MQ open record type */
89#define AUDIT_MQ_SENDRECV 1313 /* POSIX MQ send/receive record type */
90#define AUDIT_MQ_NOTIFY 1314 /* POSIX MQ notify record type */
91#define AUDIT_MQ_GETSETATTR 1315 /* POSIX MQ get/set attribute record type */
88 92
89#define AUDIT_AVC 1400 /* SE Linux avc denial or grant */ 93#define AUDIT_AVC 1400 /* SE Linux avc denial or grant */
90#define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */ 94#define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */
@@ -287,6 +291,8 @@ struct audit_context;
287struct inode; 291struct inode;
288struct netlink_skb_parms; 292struct netlink_skb_parms;
289struct linux_binprm; 293struct linux_binprm;
294struct mq_attr;
295struct mqstat;
290 296
291#define AUDITSC_INVALID 0 297#define AUDITSC_INVALID 0
292#define AUDITSC_SUCCESS 1 298#define AUDITSC_SUCCESS 1
@@ -336,6 +342,11 @@ extern int audit_socketcall(int nargs, unsigned long *args);
336extern int audit_sockaddr(int len, void *addr); 342extern int audit_sockaddr(int len, void *addr);
337extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt); 343extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt);
338extern int audit_set_macxattr(const char *name); 344extern int audit_set_macxattr(const char *name);
345extern int __audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr);
346extern int __audit_mq_timedsend(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec __user *u_abs_timeout);
347extern int __audit_mq_timedreceive(mqd_t mqdes, size_t msg_len, unsigned int __user *u_msg_prio, const struct timespec __user *u_abs_timeout);
348extern int __audit_mq_notify(mqd_t mqdes, const struct sigevent __user *u_notification);
349extern int __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat);
339 350
340static inline int audit_ipc_obj(struct kern_ipc_perm *ipcp) 351static inline int audit_ipc_obj(struct kern_ipc_perm *ipcp)
341{ 352{
@@ -349,6 +360,36 @@ static inline int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid,
349 return __audit_ipc_set_perm(qbytes, uid, gid, mode); 360 return __audit_ipc_set_perm(qbytes, uid, gid, mode);
350 return 0; 361 return 0;
351} 362}
363static inline int audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr)
364{
365 if (unlikely(current->audit_context))
366 return __audit_mq_open(oflag, mode, u_attr);
367 return 0;
368}
369static inline int audit_mq_timedsend(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec __user *u_abs_timeout)
370{
371 if (unlikely(current->audit_context))
372 return __audit_mq_timedsend(mqdes, msg_len, msg_prio, u_abs_timeout);
373 return 0;
374}
375static inline int audit_mq_timedreceive(mqd_t mqdes, size_t msg_len, unsigned int __user *u_msg_prio, const struct timespec __user *u_abs_timeout)
376{
377 if (unlikely(current->audit_context))
378 return __audit_mq_timedreceive(mqdes, msg_len, u_msg_prio, u_abs_timeout);
379 return 0;
380}
381static inline int audit_mq_notify(mqd_t mqdes, const struct sigevent __user *u_notification)
382{
383 if (unlikely(current->audit_context))
384 return __audit_mq_notify(mqdes, u_notification);
385 return 0;
386}
387static inline int audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat)
388{
389 if (unlikely(current->audit_context))
390 return __audit_mq_getsetattr(mqdes, mqstat);
391 return 0;
392}
352#else 393#else
353#define audit_alloc(t) ({ 0; }) 394#define audit_alloc(t) ({ 0; })
354#define audit_free(t) do { ; } while (0) 395#define audit_free(t) do { ; } while (0)
@@ -369,6 +410,11 @@ static inline int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid,
369#define audit_sockaddr(len, addr) ({ 0; }) 410#define audit_sockaddr(len, addr) ({ 0; })
370#define audit_avc_path(dentry, mnt) ({ 0; }) 411#define audit_avc_path(dentry, mnt) ({ 0; })
371#define audit_set_macxattr(n) do { ; } while (0) 412#define audit_set_macxattr(n) do { ; } while (0)
413#define audit_mq_open(o,m,a) ({ 0; })
414#define audit_mq_timedsend(d,l,p,t) ({ 0; })
415#define audit_mq_timedreceive(d,l,p,t) ({ 0; })
416#define audit_mq_notify(d,n) ({ 0; })
417#define audit_mq_getsetattr(d,s) ({ 0; })
372#endif 418#endif
373 419
374#ifdef CONFIG_AUDIT 420#ifdef CONFIG_AUDIT
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 41ecbd440fed..1511714a9585 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -8,6 +8,8 @@
8 * Lockless receive & send, fd based notify: 8 * Lockless receive & send, fd based notify:
9 * Manfred Spraul (manfred@colorfullife.com) 9 * Manfred Spraul (manfred@colorfullife.com)
10 * 10 *
11 * Audit: George Wilson (ltcgcw@us.ibm.com)
12 *
11 * This file is released under the GPL. 13 * This file is released under the GPL.
12 */ 14 */
13 15
@@ -24,6 +26,7 @@
24#include <linux/skbuff.h> 26#include <linux/skbuff.h>
25#include <linux/netlink.h> 27#include <linux/netlink.h>
26#include <linux/syscalls.h> 28#include <linux/syscalls.h>
29#include <linux/audit.h>
27#include <linux/signal.h> 30#include <linux/signal.h>
28#include <linux/mutex.h> 31#include <linux/mutex.h>
29 32
@@ -657,6 +660,10 @@ asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode,
657 char *name; 660 char *name;
658 int fd, error; 661 int fd, error;
659 662
663 error = audit_mq_open(oflag, mode, u_attr);
664 if (error != 0)
665 return error;
666
660 if (IS_ERR(name = getname(u_name))) 667 if (IS_ERR(name = getname(u_name)))
661 return PTR_ERR(name); 668 return PTR_ERR(name);
662 669
@@ -814,6 +821,10 @@ asmlinkage long sys_mq_timedsend(mqd_t mqdes, const char __user *u_msg_ptr,
814 long timeout; 821 long timeout;
815 int ret; 822 int ret;
816 823
824 ret = audit_mq_timedsend(mqdes, msg_len, msg_prio, u_abs_timeout);
825 if (ret != 0)
826 return ret;
827
817 if (unlikely(msg_prio >= (unsigned long) MQ_PRIO_MAX)) 828 if (unlikely(msg_prio >= (unsigned long) MQ_PRIO_MAX))
818 return -EINVAL; 829 return -EINVAL;
819 830
@@ -896,6 +907,10 @@ asmlinkage ssize_t sys_mq_timedreceive(mqd_t mqdes, char __user *u_msg_ptr,
896 struct mqueue_inode_info *info; 907 struct mqueue_inode_info *info;
897 struct ext_wait_queue wait; 908 struct ext_wait_queue wait;
898 909
910 ret = audit_mq_timedreceive(mqdes, msg_len, u_msg_prio, u_abs_timeout);
911 if (ret != 0)
912 return ret;
913
899 timeout = prepare_timeout(u_abs_timeout); 914 timeout = prepare_timeout(u_abs_timeout);
900 915
901 ret = -EBADF; 916 ret = -EBADF;
@@ -975,6 +990,10 @@ asmlinkage long sys_mq_notify(mqd_t mqdes,
975 struct mqueue_inode_info *info; 990 struct mqueue_inode_info *info;
976 struct sk_buff *nc; 991 struct sk_buff *nc;
977 992
993 ret = audit_mq_notify(mqdes, u_notification);
994 if (ret != 0)
995 return ret;
996
978 nc = NULL; 997 nc = NULL;
979 sock = NULL; 998 sock = NULL;
980 if (u_notification != NULL) { 999 if (u_notification != NULL) {
@@ -1115,6 +1134,9 @@ asmlinkage long sys_mq_getsetattr(mqd_t mqdes,
1115 omqstat = info->attr; 1134 omqstat = info->attr;
1116 omqstat.mq_flags = filp->f_flags & O_NONBLOCK; 1135 omqstat.mq_flags = filp->f_flags & O_NONBLOCK;
1117 if (u_mqstat) { 1136 if (u_mqstat) {
1137 ret = audit_mq_getsetattr(mqdes, &mqstat);
1138 if (ret != 0)
1139 goto out;
1118 if (mqstat.mq_flags & O_NONBLOCK) 1140 if (mqstat.mq_flags & O_NONBLOCK)
1119 filp->f_flags |= O_NONBLOCK; 1141 filp->f_flags |= O_NONBLOCK;
1120 else 1142 else
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 *