diff options
| -rw-r--r-- | include/linux/audit.h | 46 | ||||
| -rw-r--r-- | ipc/mqueue.c | 22 | ||||
| -rw-r--r-- | kernel/auditsc.c | 274 |
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; | |||
| 287 | struct inode; | 291 | struct inode; |
| 288 | struct netlink_skb_parms; | 292 | struct netlink_skb_parms; |
| 289 | struct linux_binprm; | 293 | struct linux_binprm; |
| 294 | struct mq_attr; | ||
| 295 | struct 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); | |||
| 336 | extern int audit_sockaddr(int len, void *addr); | 342 | extern int audit_sockaddr(int len, void *addr); |
| 337 | extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt); | 343 | extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt); |
| 338 | extern int audit_set_macxattr(const char *name); | 344 | extern int audit_set_macxattr(const char *name); |
| 345 | extern int __audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr); | ||
| 346 | extern int __audit_mq_timedsend(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec __user *u_abs_timeout); | ||
| 347 | extern int __audit_mq_timedreceive(mqd_t mqdes, size_t msg_len, unsigned int __user *u_msg_prio, const struct timespec __user *u_abs_timeout); | ||
| 348 | extern int __audit_mq_notify(mqd_t mqdes, const struct sigevent __user *u_notification); | ||
| 349 | extern int __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat); | ||
| 339 | 350 | ||
| 340 | static inline int audit_ipc_obj(struct kern_ipc_perm *ipcp) | 351 | static 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 | } |
| 363 | static 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 | } | ||
| 369 | static 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 | } | ||
| 375 | static 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 | } | ||
| 381 | static 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 | } | ||
| 387 | static 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 | ||
| 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 | * |
