ipc: shm: fix information leak to userland
[pandora-kernel.git] / ipc / mqueue.c
index b3b69fd..ca502aa 100644 (file)
@@ -207,7 +207,7 @@ static int mqueue_get_sb(struct file_system_type *fs_type,
        return get_sb_single(fs_type, flags, data, mqueue_fill_super, mnt);
 }
 
-static void init_once(struct kmem_cache *cachep, void *foo)
+static void init_once(void *foo)
 {
        struct mqueue_inode_info *p = (struct mqueue_inode_info *) foo;
 
@@ -314,15 +314,11 @@ static int mqueue_unlink(struct inode *dir, struct dentry *dentry)
 *      through std routines)
 */
 static ssize_t mqueue_read_file(struct file *filp, char __user *u_data,
-                               size_t count, loff_t * off)
+                               size_t count, loff_t *off)
 {
        struct mqueue_inode_info *info = MQUEUE_I(filp->f_path.dentry->d_inode);
        char buffer[FILENT_SIZE];
-       size_t slen;
-       loff_t o;
-
-       if (!count)
-               return 0;
+       ssize_t ret;
 
        spin_lock(&info->lock);
        snprintf(buffer, sizeof(buffer),
@@ -335,21 +331,14 @@ static ssize_t mqueue_read_file(struct file *filp, char __user *u_data,
                        pid_vnr(info->notify_owner));
        spin_unlock(&info->lock);
        buffer[sizeof(buffer)-1] = '\0';
-       slen = strlen(buffer)+1;
-
-       o = *off;
-       if (o > slen)
-               return 0;
-
-       if (o + count > slen)
-               count = slen - o;
 
-       if (copy_to_user(u_data, buffer + o, count))
-               return -EFAULT;
+       ret = simple_read_from_buffer(u_data, count, off, buffer,
+                               strlen(buffer));
+       if (ret <= 0)
+               return ret;
 
-       *off = o + count;
        filp->f_path.dentry->d_inode->i_atime = filp->f_path.dentry->d_inode->i_ctime = CURRENT_TIME;
-       return count;
+       return ret;
 }
 
 static int mqueue_flush_file(struct file *filp, fl_owner_t id)
@@ -509,7 +498,8 @@ static void __do_notify(struct mqueue_inode_info *info)
                        sig_i.si_errno = 0;
                        sig_i.si_code = SI_MESGQ;
                        sig_i.si_value = info->notify.sigev_value;
-                       sig_i.si_pid = task_tgid_vnr(current);
+                       sig_i.si_pid = task_tgid_nr_ns(current,
+                                               ns_of_pid(info->notify_owner));
                        sig_i.si_uid = current->uid;
 
                        kill_pid_info(info->notify.sigev_signo,
@@ -649,7 +639,7 @@ static int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE,
                return ERR_PTR(-EINVAL);
        }
 
-       if (permission(dentry->d_inode, oflag2acc[oflag & O_ACCMODE], NULL)) {
+       if (inode_permission(dentry->d_inode, oflag2acc[oflag & O_ACCMODE])) {
                dput(dentry);
                mntput(mqueue_mnt);
                return ERR_PTR(-EACCES);
@@ -658,8 +648,8 @@ static int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE,
        return dentry_open(dentry, mqueue_mnt, oflag);
 }
 
-asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode,
-                               struct mq_attr __user *u_attr)
+SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode,
+               struct mq_attr __user *, u_attr)
 {
        struct dentry *dentry;
        struct file *filp;
@@ -726,7 +716,7 @@ out_putname:
        return fd;
 }
 
-asmlinkage long sys_mq_unlink(const char __user *u_name)
+SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name)
 {
        int err;
        char *name;
@@ -819,9 +809,9 @@ static inline void pipelined_receive(struct mqueue_inode_info *info)
        sender->state = STATE_READY;
 }
 
-asmlinkage long sys_mq_timedsend(mqd_t mqdes, const char __user *u_msg_ptr,
-       size_t msg_len, unsigned int msg_prio,
-       const struct timespec __user *u_abs_timeout)
+SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqdes, const char __user *, u_msg_ptr,
+               size_t, msg_len, unsigned int, msg_prio,
+               const struct timespec __user *, u_abs_timeout)
 {
        struct file *filp;
        struct inode *inode;
@@ -907,9 +897,9 @@ out:
        return ret;
 }
 
-asmlinkage ssize_t sys_mq_timedreceive(mqd_t mqdes, char __user *u_msg_ptr,
-       size_t msg_len, unsigned int __user *u_msg_prio,
-       const struct timespec __user *u_abs_timeout)
+SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes, char __user *, u_msg_ptr,
+               size_t, msg_len, unsigned int __user *, u_msg_prio,
+               const struct timespec __user *, u_abs_timeout)
 {
        long timeout;
        ssize_t ret;
@@ -992,8 +982,8 @@ out:
  * and he isn't currently owner of notification, will be silently discarded.
  * It isn't explicitly defined in the POSIX.
  */
-asmlinkage long sys_mq_notify(mqd_t mqdes,
-                               const struct sigevent __user *u_notification)
+SYSCALL_DEFINE2(mq_notify, mqd_t, mqdes,
+               const struct sigevent __user *, u_notification)
 {
        int ret;
        struct file *filp;
@@ -1054,7 +1044,7 @@ retry:
                        }
 
                        timeo = MAX_SCHEDULE_TIMEOUT;
-                       ret = netlink_attachskb(sock, nc, 0, &timeo, NULL);
+                       ret = netlink_attachskb(sock, nc, &timeo, NULL);
                        if (ret == 1)
                                goto retry;
                        if (ret) {
@@ -1118,9 +1108,9 @@ out:
        return ret;
 }
 
-asmlinkage long sys_mq_getsetattr(mqd_t mqdes,
-                       const struct mq_attr __user *u_mqstat,
-                       struct mq_attr __user *u_omqstat)
+SYSCALL_DEFINE3(mq_getsetattr, mqd_t, mqdes,
+               const struct mq_attr __user *, u_mqstat,
+               struct mq_attr __user *, u_omqstat)
 {
        int ret;
        struct mq_attr mqstat, omqstat;