diff options
-rw-r--r-- | include/linux/audit.h | 17 | ||||
-rw-r--r-- | ipc/mqueue.c | 54 | ||||
-rw-r--r-- | kernel/auditsc.c | 127 |
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); | |||
451 | extern int __audit_fd_pair(int fd1, int fd2); | 451 | extern int __audit_fd_pair(int fd1, int fd2); |
452 | extern int audit_set_macxattr(const char *name); | 452 | extern int audit_set_macxattr(const char *name); |
453 | extern int __audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr); | 453 | extern int __audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr); |
454 | extern int __audit_mq_timedsend(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec __user *u_abs_timeout); | 454 | extern void __audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec *abs_timeout); |
455 | 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); | ||
456 | extern void __audit_mq_notify(mqd_t mqdes, const struct sigevent *notification); | 455 | extern void __audit_mq_notify(mqd_t mqdes, const struct sigevent *notification); |
457 | extern void __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat); | 456 | extern void __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat); |
458 | extern int __audit_log_bprm_fcaps(struct linux_binprm *bprm, | 457 | extern 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 | } |
485 | static inline int audit_mq_timedsend(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec __user *u_abs_timeout) | 484 | static 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 | } | ||
491 | 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) | ||
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 | } |
497 | static inline void audit_mq_notify(mqd_t mqdes, const struct sigevent *notification) | 489 | static 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 | ||
527 | static long prepare_timeout(const struct timespec __user *u_arg) | 527 | static 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 | ||
134 | struct 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 | |||
142 | struct audit_aux_data_execve { | 134 | struct 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 | */ | ||
2182 | int __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 | */ |
2225 | int __audit_mq_timedreceive(mqd_t mqdes, size_t msg_len, | 2180 | void __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 | /** |