aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2008-12-14 04:02:26 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2009-01-04 15:14:41 -0500
commit564f6993ffef656aebaf46cf2f1f6cb4f5c97207 (patch)
tree0bf1ee553ab1241338fe522ffbaed8cd48e10c99
parentc32c8af43b9adde8d6f938d8e6328c13b8de79ac (diff)
sanitize audit_mq_open()
* don't bother with allocations * don't do double copy_from_user() * don't duplicate parts of check for audit_dummy_context() Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--include/linux/audit.h9
-rw-r--r--ipc/mqueue.c23
-rw-r--r--kernel/auditsc.c65
3 files changed, 38 insertions, 59 deletions
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 67f0cdd991ba..54978bdd2bd4 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -450,7 +450,7 @@ extern void audit_socketcall(int nargs, unsigned long *args);
450extern int audit_sockaddr(int len, void *addr); 450extern 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 void __audit_mq_open(int oflag, mode_t mode, struct mq_attr *attr);
454extern void __audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec *abs_timeout); 454extern void __audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec *abs_timeout);
455extern void __audit_mq_notify(mqd_t mqdes, const struct sigevent *notification); 455extern void __audit_mq_notify(mqd_t mqdes, const struct sigevent *notification);
456extern void __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat); 456extern void __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat);
@@ -475,11 +475,10 @@ static inline void audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid
475 if (unlikely(!audit_dummy_context())) 475 if (unlikely(!audit_dummy_context()))
476 __audit_ipc_set_perm(qbytes, uid, gid, mode); 476 __audit_ipc_set_perm(qbytes, uid, gid, mode);
477} 477}
478static inline int audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr) 478static inline void audit_mq_open(int oflag, mode_t mode, struct mq_attr *attr)
479{ 479{
480 if (unlikely(!audit_dummy_context())) 480 if (unlikely(!audit_dummy_context()))
481 return __audit_mq_open(oflag, mode, u_attr); 481 __audit_mq_open(oflag, mode, attr);
482 return 0;
483} 482}
484static inline void audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec *abs_timeout) 483static inline void audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec *abs_timeout)
485{ 484{
@@ -541,7 +540,7 @@ extern int audit_signals;
541#define audit_fd_pair(n,a) ({ 0; }) 540#define audit_fd_pair(n,a) ({ 0; })
542#define audit_sockaddr(len, addr) ({ 0; }) 541#define audit_sockaddr(len, addr) ({ 0; })
543#define audit_set_macxattr(n) do { ; } while (0) 542#define audit_set_macxattr(n) do { ; } while (0)
544#define audit_mq_open(o,m,a) ({ 0; }) 543#define audit_mq_open(o,m,a) ((void)0)
545#define audit_mq_sendrecv(d,l,p,t) ((void)0) 544#define audit_mq_sendrecv(d,l,p,t) ((void)0)
546#define audit_mq_notify(d,n) ((void)0) 545#define audit_mq_notify(d,n) ((void)0)
547#define audit_mq_getsetattr(d,s) ((void)0) 546#define audit_mq_getsetattr(d,s) ((void)0)
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 192da806c283..d448b69672b5 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -588,22 +588,18 @@ static int mq_attr_ok(struct mq_attr *attr)
588 * Invoked when creating a new queue via sys_mq_open 588 * Invoked when creating a new queue via sys_mq_open
589 */ 589 */
590static struct file *do_create(struct dentry *dir, struct dentry *dentry, 590static struct file *do_create(struct dentry *dir, struct dentry *dentry,
591 int oflag, mode_t mode, struct mq_attr __user *u_attr) 591 int oflag, mode_t mode, struct mq_attr *attr)
592{ 592{
593 const struct cred *cred = current_cred(); 593 const struct cred *cred = current_cred();
594 struct mq_attr attr;
595 struct file *result; 594 struct file *result;
596 int ret; 595 int ret;
597 596
598 if (u_attr) { 597 if (attr) {
599 ret = -EFAULT;
600 if (copy_from_user(&attr, u_attr, sizeof(attr)))
601 goto out;
602 ret = -EINVAL; 598 ret = -EINVAL;
603 if (!mq_attr_ok(&attr)) 599 if (!mq_attr_ok(attr))
604 goto out; 600 goto out;
605 /* store for use during create */ 601 /* store for use during create */
606 dentry->d_fsdata = &attr; 602 dentry->d_fsdata = attr;
607 } 603 }
608 604
609 mode &= ~current->fs->umask; 605 mode &= ~current->fs->umask;
@@ -660,11 +656,13 @@ asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode,
660 struct dentry *dentry; 656 struct dentry *dentry;
661 struct file *filp; 657 struct file *filp;
662 char *name; 658 char *name;
659 struct mq_attr attr;
663 int fd, error; 660 int fd, error;
664 661
665 error = audit_mq_open(oflag, mode, u_attr); 662 if (u_attr && copy_from_user(&attr, u_attr, sizeof(struct mq_attr)))
666 if (error != 0) 663 return -EFAULT;
667 return error; 664
665 audit_mq_open(oflag, mode, u_attr ? &attr : NULL);
668 666
669 if (IS_ERR(name = getname(u_name))) 667 if (IS_ERR(name = getname(u_name)))
670 return PTR_ERR(name); 668 return PTR_ERR(name);
@@ -690,7 +688,8 @@ asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode,
690 filp = do_open(dentry, oflag); 688 filp = do_open(dentry, oflag);
691 } else { 689 } else {
692 filp = do_create(mqueue_mnt->mnt_root, dentry, 690 filp = do_create(mqueue_mnt->mnt_root, dentry,
693 oflag, mode, u_attr); 691 oflag, mode,
692 u_attr ? &attr : NULL);
694 } 693 }
695 } else { 694 } else {
696 error = -ENOENT; 695 error = -ENOENT;
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 140c47453470..83e946f1cdde 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -124,13 +124,6 @@ struct audit_aux_data {
124/* Number of target pids per aux struct. */ 124/* Number of target pids per aux struct. */
125#define AUDIT_AUX_PIDS 16 125#define AUDIT_AUX_PIDS 16
126 126
127struct audit_aux_data_mq_open {
128 struct audit_aux_data d;
129 int oflag;
130 mode_t mode;
131 struct mq_attr attr;
132};
133
134struct audit_aux_data_execve { 127struct audit_aux_data_execve {
135 struct audit_aux_data d; 128 struct audit_aux_data d;
136 int argc; 129 int argc;
@@ -242,6 +235,11 @@ struct audit_context {
242 unsigned int msg_prio; 235 unsigned int msg_prio;
243 struct timespec abs_timeout; 236 struct timespec abs_timeout;
244 } mq_sendrecv; 237 } mq_sendrecv;
238 struct {
239 int oflag;
240 mode_t mode;
241 struct mq_attr attr;
242 } mq_open;
245 }; 243 };
246 244
247#if AUDIT_DEBUG 245#if AUDIT_DEBUG
@@ -1263,6 +1261,16 @@ static void show_special(struct audit_context *context, int *call_panic)
1263 return; 1261 return;
1264 } 1262 }
1265 break; } 1263 break; }
1264 case AUDIT_MQ_OPEN: {
1265 audit_log_format(ab,
1266 "oflag=0x%x mode=%#o mq_flags=0x%lx mq_maxmsg=%ld "
1267 "mq_msgsize=%ld mq_curmsgs=%ld",
1268 context->mq_open.oflag, context->mq_open.mode,
1269 context->mq_open.attr.mq_flags,
1270 context->mq_open.attr.mq_maxmsg,
1271 context->mq_open.attr.mq_msgsize,
1272 context->mq_open.attr.mq_curmsgs);
1273 break; }
1266 case AUDIT_MQ_SENDRECV: { 1274 case AUDIT_MQ_SENDRECV: {
1267 audit_log_format(ab, 1275 audit_log_format(ab,
1268 "mqdes=%d msg_len=%zd msg_prio=%u " 1276 "mqdes=%d msg_len=%zd msg_prio=%u "
@@ -1368,15 +1376,6 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
1368 continue; /* audit_panic has been called */ 1376 continue; /* audit_panic has been called */
1369 1377
1370 switch (aux->type) { 1378 switch (aux->type) {
1371 case AUDIT_MQ_OPEN: {
1372 struct audit_aux_data_mq_open *axi = (void *)aux;
1373 audit_log_format(ab,
1374 "oflag=0x%x mode=%#o mq_flags=0x%lx mq_maxmsg=%ld "
1375 "mq_msgsize=%ld mq_curmsgs=%ld",
1376 axi->oflag, axi->mode, axi->attr.mq_flags,
1377 axi->attr.mq_maxmsg, axi->attr.mq_msgsize,
1378 axi->attr.mq_curmsgs);
1379 break; }
1380 1379
1381 case AUDIT_EXECVE: { 1380 case AUDIT_EXECVE: {
1382 struct audit_aux_data_execve *axi = (void *)aux; 1381 struct audit_aux_data_execve *axi = (void *)aux;
@@ -2135,38 +2134,20 @@ int audit_set_loginuid(struct task_struct *task, uid_t loginuid)
2135 * @mode: mode bits 2134 * @mode: mode bits
2136 * @u_attr: queue attributes 2135 * @u_attr: queue attributes
2137 * 2136 *
2138 * Returns 0 for success or NULL context or < 0 on error.
2139 */ 2137 */
2140int __audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr) 2138void __audit_mq_open(int oflag, mode_t mode, struct mq_attr *attr)
2141{ 2139{
2142 struct audit_aux_data_mq_open *ax;
2143 struct audit_context *context = current->audit_context; 2140 struct audit_context *context = current->audit_context;
2144 2141
2145 if (!audit_enabled) 2142 if (attr)
2146 return 0; 2143 memcpy(&context->mq_open.attr, attr, sizeof(struct mq_attr));
2147 2144 else
2148 if (likely(!context)) 2145 memset(&context->mq_open.attr, 0, sizeof(struct mq_attr));
2149 return 0;
2150
2151 ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
2152 if (!ax)
2153 return -ENOMEM;
2154
2155 if (u_attr != NULL) {
2156 if (copy_from_user(&ax->attr, u_attr, sizeof(ax->attr))) {
2157 kfree(ax);
2158 return -EFAULT;
2159 }
2160 } else
2161 memset(&ax->attr, 0, sizeof(ax->attr));
2162 2146
2163 ax->oflag = oflag; 2147 context->mq_open.oflag = oflag;
2164 ax->mode = mode; 2148 context->mq_open.mode = mode;
2165 2149
2166 ax->d.type = AUDIT_MQ_OPEN; 2150 context->type = AUDIT_MQ_OPEN;
2167 ax->d.next = context->aux;
2168 context->aux = (void *)ax;
2169 return 0;
2170} 2151}
2171 2152
2172/** 2153/**