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 | /** |
