aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/audit.h17
-rw-r--r--ipc/mqueue.c54
-rw-r--r--kernel/auditsc.c127
3 files changed, 63 insertions, 135 deletions
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 8101d2c4a995..67f0cdd991ba 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -451,8 +451,7 @@ extern int audit_sockaddr(int len, void *addr);
451extern int __audit_fd_pair(int fd1, int fd2); 451extern int __audit_fd_pair(int fd1, int fd2);
452extern int audit_set_macxattr(const char *name); 452extern int audit_set_macxattr(const char *name);
453extern int __audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr); 453extern int __audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr);
454extern int __audit_mq_timedsend(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec __user *u_abs_timeout); 454extern void __audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec *abs_timeout);
455extern int __audit_mq_timedreceive(mqd_t mqdes, size_t msg_len, unsigned int __user *u_msg_prio, const struct timespec __user *u_abs_timeout);
456extern void __audit_mq_notify(mqd_t mqdes, const struct sigevent *notification); 455extern void __audit_mq_notify(mqd_t mqdes, const struct sigevent *notification);
457extern void __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat); 456extern void __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat);
458extern int __audit_log_bprm_fcaps(struct linux_binprm *bprm, 457extern int __audit_log_bprm_fcaps(struct linux_binprm *bprm,
@@ -482,17 +481,10 @@ static inline int audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u
482 return __audit_mq_open(oflag, mode, u_attr); 481 return __audit_mq_open(oflag, mode, u_attr);
483 return 0; 482 return 0;
484} 483}
485static inline int audit_mq_timedsend(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec __user *u_abs_timeout) 484static inline void audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec *abs_timeout)
486{ 485{
487 if (unlikely(!audit_dummy_context())) 486 if (unlikely(!audit_dummy_context()))
488 return __audit_mq_timedsend(mqdes, msg_len, msg_prio, u_abs_timeout); 487 __audit_mq_sendrecv(mqdes, msg_len, msg_prio, abs_timeout);
489 return 0;
490}
491static 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)
492{
493 if (unlikely(!audit_dummy_context()))
494 return __audit_mq_timedreceive(mqdes, msg_len, u_msg_prio, u_abs_timeout);
495 return 0;
496} 488}
497static inline void audit_mq_notify(mqd_t mqdes, const struct sigevent *notification) 489static inline void audit_mq_notify(mqd_t mqdes, const struct sigevent *notification)
498{ 490{
@@ -550,8 +542,7 @@ extern int audit_signals;
550#define audit_sockaddr(len, addr) ({ 0; }) 542#define audit_sockaddr(len, addr) ({ 0; })
551#define audit_set_macxattr(n) do { ; } while (0) 543#define audit_set_macxattr(n) do { ; } while (0)
552#define audit_mq_open(o,m,a) ({ 0; }) 544#define audit_mq_open(o,m,a) ({ 0; })
553#define audit_mq_timedsend(d,l,p,t) ({ 0; }) 545#define audit_mq_sendrecv(d,l,p,t) ((void)0)
554#define audit_mq_timedreceive(d,l,p,t) ({ 0; })
555#define audit_mq_notify(d,n) ((void)0) 546#define audit_mq_notify(d,n) ((void)0)
556#define audit_mq_getsetattr(d,s) ((void)0) 547#define audit_mq_getsetattr(d,s) ((void)0)
557#define audit_log_bprm_fcaps(b, ncr, ocr) ({ 0; }) 548#define audit_log_bprm_fcaps(b, ncr, ocr) ({ 0; })
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index e7b2f68f8d77..192da806c283 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -524,31 +524,27 @@ static void __do_notify(struct mqueue_inode_info *info)
524 wake_up(&info->wait_q); 524 wake_up(&info->wait_q);
525} 525}
526 526
527static long prepare_timeout(const struct timespec __user *u_arg) 527static long prepare_timeout(struct timespec *p)
528{ 528{
529 struct timespec ts, nowts; 529 struct timespec nowts;
530 long timeout; 530 long timeout;
531 531
532 if (u_arg) { 532 if (p) {
533 if (unlikely(copy_from_user(&ts, u_arg, 533 if (unlikely(p->tv_nsec < 0 || p->tv_sec < 0
534 sizeof(struct timespec)))) 534 || p->tv_nsec >= NSEC_PER_SEC))
535 return -EFAULT;
536
537 if (unlikely(ts.tv_nsec < 0 || ts.tv_sec < 0
538 || ts.tv_nsec >= NSEC_PER_SEC))
539 return -EINVAL; 535 return -EINVAL;
540 nowts = CURRENT_TIME; 536 nowts = CURRENT_TIME;
541 /* first subtract as jiffies can't be too big */ 537 /* first subtract as jiffies can't be too big */
542 ts.tv_sec -= nowts.tv_sec; 538 p->tv_sec -= nowts.tv_sec;
543 if (ts.tv_nsec < nowts.tv_nsec) { 539 if (p->tv_nsec < nowts.tv_nsec) {
544 ts.tv_nsec += NSEC_PER_SEC; 540 p->tv_nsec += NSEC_PER_SEC;
545 ts.tv_sec--; 541 p->tv_sec--;
546 } 542 }
547 ts.tv_nsec -= nowts.tv_nsec; 543 p->tv_nsec -= nowts.tv_nsec;
548 if (ts.tv_sec < 0) 544 if (p->tv_sec < 0)
549 return 0; 545 return 0;
550 546
551 timeout = timespec_to_jiffies(&ts) + 1; 547 timeout = timespec_to_jiffies(p) + 1;
552 } else 548 } else
553 return MAX_SCHEDULE_TIMEOUT; 549 return MAX_SCHEDULE_TIMEOUT;
554 550
@@ -829,17 +825,22 @@ asmlinkage long sys_mq_timedsend(mqd_t mqdes, const char __user *u_msg_ptr,
829 struct ext_wait_queue *receiver; 825 struct ext_wait_queue *receiver;
830 struct msg_msg *msg_ptr; 826 struct msg_msg *msg_ptr;
831 struct mqueue_inode_info *info; 827 struct mqueue_inode_info *info;
828 struct timespec ts, *p = NULL;
832 long timeout; 829 long timeout;
833 int ret; 830 int ret;
834 831
835 ret = audit_mq_timedsend(mqdes, msg_len, msg_prio, u_abs_timeout); 832 if (u_abs_timeout) {
836 if (ret != 0) 833 if (copy_from_user(&ts, u_abs_timeout,
837 return ret; 834 sizeof(struct timespec)))
835 return -EFAULT;
836 p = &ts;
837 }
838 838
839 if (unlikely(msg_prio >= (unsigned long) MQ_PRIO_MAX)) 839 if (unlikely(msg_prio >= (unsigned long) MQ_PRIO_MAX))
840 return -EINVAL; 840 return -EINVAL;
841 841
842 timeout = prepare_timeout(u_abs_timeout); 842 audit_mq_sendrecv(mqdes, msg_len, msg_prio, p);
843 timeout = prepare_timeout(p);
843 844
844 ret = -EBADF; 845 ret = -EBADF;
845 filp = fget(mqdes); 846 filp = fget(mqdes);
@@ -918,12 +919,17 @@ asmlinkage ssize_t sys_mq_timedreceive(mqd_t mqdes, char __user *u_msg_ptr,
918 struct inode *inode; 919 struct inode *inode;
919 struct mqueue_inode_info *info; 920 struct mqueue_inode_info *info;
920 struct ext_wait_queue wait; 921 struct ext_wait_queue wait;
922 struct timespec ts, *p = NULL;
921 923
922 ret = audit_mq_timedreceive(mqdes, msg_len, u_msg_prio, u_abs_timeout); 924 if (u_abs_timeout) {
923 if (ret != 0) 925 if (copy_from_user(&ts, u_abs_timeout,
924 return ret; 926 sizeof(struct timespec)))
927 return -EFAULT;
928 p = &ts;
929 }
925 930
926 timeout = prepare_timeout(u_abs_timeout); 931 audit_mq_sendrecv(mqdes, msg_len, 0, p);
932 timeout = prepare_timeout(p);
927 933
928 ret = -EBADF; 934 ret = -EBADF;
929 filp = fget(mqdes); 935 filp = fget(mqdes);
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 3ece960de894..140c47453470 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -131,14 +131,6 @@ struct audit_aux_data_mq_open {
131 struct mq_attr attr; 131 struct mq_attr attr;
132}; 132};
133 133
134struct audit_aux_data_mq_sendrecv {
135 struct audit_aux_data d;
136 mqd_t mqdes;
137 size_t msg_len;
138 unsigned int msg_prio;
139 struct timespec abs_timeout;
140};
141
142struct audit_aux_data_execve { 134struct audit_aux_data_execve {
143 struct audit_aux_data d; 135 struct audit_aux_data d;
144 int argc; 136 int argc;
@@ -244,6 +236,12 @@ struct audit_context {
244 mqd_t mqdes; 236 mqd_t mqdes;
245 int sigev_signo; 237 int sigev_signo;
246 } mq_notify; 238 } mq_notify;
239 struct {
240 mqd_t mqdes;
241 size_t msg_len;
242 unsigned int msg_prio;
243 struct timespec abs_timeout;
244 } mq_sendrecv;
247 }; 245 };
248 246
249#if AUDIT_DEBUG 247#if AUDIT_DEBUG
@@ -1265,6 +1263,16 @@ static void show_special(struct audit_context *context, int *call_panic)
1265 return; 1263 return;
1266 } 1264 }
1267 break; } 1265 break; }
1266 case AUDIT_MQ_SENDRECV: {
1267 audit_log_format(ab,
1268 "mqdes=%d msg_len=%zd msg_prio=%u "
1269 "abs_timeout_sec=%ld abs_timeout_nsec=%ld",
1270 context->mq_sendrecv.mqdes,
1271 context->mq_sendrecv.msg_len,
1272 context->mq_sendrecv.msg_prio,
1273 context->mq_sendrecv.abs_timeout.tv_sec,
1274 context->mq_sendrecv.abs_timeout.tv_nsec);
1275 break; }
1268 case AUDIT_MQ_NOTIFY: { 1276 case AUDIT_MQ_NOTIFY: {
1269 audit_log_format(ab, "mqdes=%d sigev_signo=%d", 1277 audit_log_format(ab, "mqdes=%d sigev_signo=%d",
1270 context->mq_notify.mqdes, 1278 context->mq_notify.mqdes,
@@ -1370,15 +1378,6 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
1370 axi->attr.mq_curmsgs); 1378 axi->attr.mq_curmsgs);
1371 break; } 1379 break; }
1372 1380
1373 case AUDIT_MQ_SENDRECV: {
1374 struct audit_aux_data_mq_sendrecv *axi = (void *)aux;
1375 audit_log_format(ab,
1376 "mqdes=%d msg_len=%zd msg_prio=%u "
1377 "abs_timeout_sec=%ld abs_timeout_nsec=%ld",
1378 axi->mqdes, axi->msg_len, axi->msg_prio,
1379 axi->abs_timeout.tv_sec, axi->abs_timeout.tv_nsec);
1380 break; }
1381
1382 case AUDIT_EXECVE: { 1381 case AUDIT_EXECVE: {
1383 struct audit_aux_data_execve *axi = (void *)aux; 1382 struct audit_aux_data_execve *axi = (void *)aux;
1384 audit_log_execve_info(context, &ab, axi); 1383 audit_log_execve_info(context, &ab, axi);
@@ -2171,97 +2170,29 @@ int __audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr)
2171} 2170}
2172 2171
2173/** 2172/**
2174 * __audit_mq_timedsend - record audit data for a POSIX MQ timed send 2173 * __audit_mq_sendrecv - record audit data for a POSIX MQ timed send/receive
2175 * @mqdes: MQ descriptor 2174 * @mqdes: MQ descriptor
2176 * @msg_len: Message length 2175 * @msg_len: Message length
2177 * @msg_prio: Message priority 2176 * @msg_prio: Message priority
2178 * @u_abs_timeout: Message timeout in absolute time 2177 * @abs_timeout: Message timeout in absolute time
2179 *
2180 * Returns 0 for success or NULL context or < 0 on error.
2181 */
2182int __audit_mq_timedsend(mqd_t mqdes, size_t msg_len, unsigned int msg_prio,
2183 const struct timespec __user *u_abs_timeout)
2184{
2185 struct audit_aux_data_mq_sendrecv *ax;
2186 struct audit_context *context = current->audit_context;
2187
2188 if (!audit_enabled)
2189 return 0;
2190
2191 if (likely(!context))
2192 return 0;
2193
2194 ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
2195 if (!ax)
2196 return -ENOMEM;
2197
2198 if (u_abs_timeout != NULL) {
2199 if (copy_from_user(&ax->abs_timeout, u_abs_timeout, sizeof(ax->abs_timeout))) {
2200 kfree(ax);
2201 return -EFAULT;
2202 }
2203 } else
2204 memset(&ax->abs_timeout, 0, sizeof(ax->abs_timeout));
2205
2206 ax->mqdes = mqdes;
2207 ax->msg_len = msg_len;
2208 ax->msg_prio = msg_prio;
2209
2210 ax->d.type = AUDIT_MQ_SENDRECV;
2211 ax->d.next = context->aux;
2212 context->aux = (void *)ax;
2213 return 0;
2214}
2215
2216/**
2217 * __audit_mq_timedreceive - record audit data for a POSIX MQ timed receive
2218 * @mqdes: MQ descriptor
2219 * @msg_len: Message length
2220 * @u_msg_prio: Message priority
2221 * @u_abs_timeout: Message timeout in absolute time
2222 * 2178 *
2223 * Returns 0 for success or NULL context or < 0 on error.
2224 */ 2179 */
2225int __audit_mq_timedreceive(mqd_t mqdes, size_t msg_len, 2180void __audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio,
2226 unsigned int __user *u_msg_prio, 2181 const struct timespec *abs_timeout)
2227 const struct timespec __user *u_abs_timeout)
2228{ 2182{
2229 struct audit_aux_data_mq_sendrecv *ax;
2230 struct audit_context *context = current->audit_context; 2183 struct audit_context *context = current->audit_context;
2184 struct timespec *p = &context->mq_sendrecv.abs_timeout;
2231 2185
2232 if (!audit_enabled) 2186 if (abs_timeout)
2233 return 0; 2187 memcpy(p, abs_timeout, sizeof(struct timespec));
2234 2188 else
2235 if (likely(!context)) 2189 memset(p, 0, sizeof(struct timespec));
2236 return 0;
2237
2238 ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
2239 if (!ax)
2240 return -ENOMEM;
2241
2242 if (u_msg_prio != NULL) {
2243 if (get_user(ax->msg_prio, u_msg_prio)) {
2244 kfree(ax);
2245 return -EFAULT;
2246 }
2247 } else
2248 ax->msg_prio = 0;
2249
2250 if (u_abs_timeout != NULL) {
2251 if (copy_from_user(&ax->abs_timeout, u_abs_timeout, sizeof(ax->abs_timeout))) {
2252 kfree(ax);
2253 return -EFAULT;
2254 }
2255 } else
2256 memset(&ax->abs_timeout, 0, sizeof(ax->abs_timeout));
2257 2190
2258 ax->mqdes = mqdes; 2191 context->mq_sendrecv.mqdes = mqdes;
2259 ax->msg_len = msg_len; 2192 context->mq_sendrecv.msg_len = msg_len;
2193 context->mq_sendrecv.msg_prio = msg_prio;
2260 2194
2261 ax->d.type = AUDIT_MQ_SENDRECV; 2195 context->type = AUDIT_MQ_SENDRECV;
2262 ax->d.next = context->aux;
2263 context->aux = (void *)ax;
2264 return 0;
2265} 2196}
2266 2197
2267/** 2198/**