mqueue: apply mathematics distributivity on mq_bytes calculation
[safe/jmp/linux-2.6] / ipc / mqueue.c
index ee9d697..15eabf9 100644 (file)
@@ -32,7 +32,6 @@
 #include <linux/nsproxy.h>
 #include <linux/pid.h>
 #include <linux/ipc_namespace.h>
-#include <linux/ima.h>
 
 #include <net/sock.h>
 #include "util.h"
@@ -135,7 +134,6 @@ static struct inode *mqueue_get_inode(struct super_block *sb,
                        init_waitqueue_head(&info->wait_q);
                        INIT_LIST_HEAD(&info->e_wait_q[0].list);
                        INIT_LIST_HEAD(&info->e_wait_q[1].list);
-                       info->messages = NULL;
                        info->notify_owner = NULL;
                        info->qsize = 0;
                        info->user = NULL;      /* set when all is ok */
@@ -147,6 +145,10 @@ static struct inode *mqueue_get_inode(struct super_block *sb,
                                info->attr.mq_msgsize = attr->mq_msgsize;
                        }
                        mq_msg_tblsz = info->attr.mq_maxmsg * sizeof(struct msg_msg *);
+                       info->messages = kmalloc(mq_msg_tblsz, GFP_KERNEL);
+                       if (!info->messages)
+                               goto out_inode;
+
                        mq_bytes = (mq_msg_tblsz +
                                (info->attr.mq_maxmsg * info->attr.mq_msgsize));
 
@@ -155,18 +157,12 @@ static struct inode *mqueue_get_inode(struct super_block *sb,
                            u->mq_bytes + mq_bytes >
                            p->signal->rlim[RLIMIT_MSGQUEUE].rlim_cur) {
                                spin_unlock(&mq_lock);
+                               kfree(info->messages);
                                goto out_inode;
                        }
                        u->mq_bytes += mq_bytes;
                        spin_unlock(&mq_lock);
 
-                       info->messages = kmalloc(mq_msg_tblsz, GFP_KERNEL);
-                       if (!info->messages) {
-                               spin_lock(&mq_lock);
-                               u->mq_bytes -= mq_bytes;
-                               spin_unlock(&mq_lock);
-                               goto out_inode;
-                       }
                        /* all is ok */
                        info->user = get_uid(u);
                } else if (S_ISDIR(mode)) {
@@ -265,8 +261,9 @@ static void mqueue_delete_inode(struct inode *inode)
 
        clear_inode(inode);
 
-       mq_bytes = (info->attr.mq_maxmsg * sizeof(struct msg_msg *) +
-                  (info->attr.mq_maxmsg * info->attr.mq_msgsize));
+       /* Total amount of bytes accounted for the mqueue */
+       mq_bytes = info->attr.mq_maxmsg * (sizeof(struct msg_msg *)
+           + info->attr.mq_msgsize);
        user = info->user;
        if (user) {
                spin_lock(&mq_lock);
@@ -605,8 +602,8 @@ static int mq_attr_ok(struct ipc_namespace *ipc_ns, struct mq_attr *attr)
        /* check for overflow */
        if (attr->mq_msgsize > ULONG_MAX/attr->mq_maxmsg)
                return 0;
-       if ((unsigned long)(attr->mq_maxmsg * attr->mq_msgsize) +
-           (attr->mq_maxmsg * sizeof (struct msg_msg *)) <
+       if ((unsigned long)(attr->mq_maxmsg * (attr->mq_msgsize
+           + sizeof (struct msg_msg *))) <
            (unsigned long)(attr->mq_maxmsg * attr->mq_msgsize))
                return 0;
        return 1;
@@ -706,7 +703,7 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode,
        dentry = lookup_one_len(name, ipc_ns->mq_mnt->mnt_root, strlen(name));
        if (IS_ERR(dentry)) {
                error = PTR_ERR(dentry);
-               goto out_err;
+               goto out_putfd;
        }
        mntget(ipc_ns->mq_mnt);
 
@@ -734,7 +731,6 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode,
                error = PTR_ERR(filp);
                goto out_putfd;
        }
-       ima_counts_get(filp);
 
        fd_install(fd, filp);
        goto out_upsem;
@@ -744,7 +740,6 @@ out:
        mntput(ipc_ns->mq_mnt);
 out_putfd:
        put_unused_fd(fd);
-out_err:
        fd = error;
 out_upsem:
        mutex_unlock(&ipc_ns->mq_mnt->mnt_root->d_inode->i_mutex);