]> nv-tegra.nvidia Code Review - linux-2.6.git/blobdiff - ipc/mqueue.c
sanitize audit_mq_getsetattr()
[linux-2.6.git] / ipc / mqueue.c
index 96fb36cd9874cb26b242933178426244d1ed7e13..7563611c6615435e8a05ecb0758335c4d3fc0d54 100644 (file)
 #define HARD_MSGMAX    (131072/sizeof(void*))
 #define DFLT_MSGSIZEMAX 8192   /* max message size */
 
+/*
+ * Define the ranges various user-specified maximum values can
+ * be set to.
+ */
+#define MIN_MSGMAX     1               /* min value for msg_max */
+#define MAX_MSGMAX     HARD_MSGMAX     /* max value for msg_max */
+#define MIN_MSGSIZEMAX 128             /* min value for msgsize_max */
+#define MAX_MSGSIZEMAX (8192*128)      /* max value for msgsize_max */
 
 struct ext_wait_queue {                /* queue of sleeping tasks */
        struct task_struct *task;
@@ -104,13 +112,14 @@ static inline struct mqueue_inode_info *MQUEUE_I(struct inode *inode)
 static struct inode *mqueue_get_inode(struct super_block *sb, int mode,
                                                        struct mq_attr *attr)
 {
+       struct user_struct *u = current_user();
        struct inode *inode;
 
        inode = new_inode(sb);
        if (inode) {
                inode->i_mode = mode;
-               inode->i_uid = current->fsuid;
-               inode->i_gid = current->fsgid;
+               inode->i_uid = current_fsuid();
+               inode->i_gid = current_fsgid();
                inode->i_blocks = 0;
                inode->i_mtime = inode->i_ctime = inode->i_atime =
                                CURRENT_TIME;
@@ -118,7 +127,6 @@ static struct inode *mqueue_get_inode(struct super_block *sb, int mode,
                if (S_ISREG(mode)) {
                        struct mqueue_inode_info *info;
                        struct task_struct *p = current;
-                       struct user_struct *u = p->user;
                        unsigned long mq_bytes, mq_msg_tblsz;
 
                        inode->i_fop = &mqueue_file_operations;
@@ -134,8 +142,8 @@ static struct inode *mqueue_get_inode(struct super_block *sb, int mode,
                        info->qsize = 0;
                        info->user = NULL;      /* set when all is ok */
                        memset(&info->attr, 0, sizeof(info->attr));
-                       info->attr.mq_maxmsg = DFLT_MSGMAX;
-                       info->attr.mq_msgsize = DFLT_MSGSIZEMAX;
+                       info->attr.mq_maxmsg = msg_max;
+                       info->attr.mq_msgsize = msgsize_max;
                        if (attr) {
                                info->attr.mq_maxmsg = attr->mq_maxmsg;
                                info->attr.mq_msgsize = attr->mq_msgsize;
@@ -499,7 +507,7 @@ static void __do_notify(struct mqueue_inode_info *info)
                        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_uid = current->uid;
+                       sig_i.si_uid = current_uid();
 
                        kill_pid_info(info->notify.sigev_signo,
                                      &sig_i, info->notify_owner);
@@ -586,6 +594,7 @@ static int mq_attr_ok(struct mq_attr *attr)
 static struct file *do_create(struct dentry *dir, struct dentry *dentry,
                        int oflag, mode_t mode, struct mq_attr __user *u_attr)
 {
+       const struct cred *cred = current_cred();
        struct mq_attr attr;
        struct file *result;
        int ret;
@@ -610,7 +619,7 @@ static struct file *do_create(struct dentry *dir, struct dentry *dentry,
        if (ret)
                goto out_drop_write;
 
-       result = dentry_open(dentry, mqueue_mnt, oflag);
+       result = dentry_open(dentry, mqueue_mnt, oflag, cred);
        /*
         * dentry_open() took a persistent mnt_want_write(),
         * so we can now drop this one.
@@ -629,8 +638,10 @@ out:
 /* Opens existing queue */
 static struct file *do_open(struct dentry *dentry, int oflag)
 {
-static int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE,
-                                       MAY_READ | MAY_WRITE };
+       const struct cred *cred = current_cred();
+
+       static const int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE,
+                                                 MAY_READ | MAY_WRITE };
 
        if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY)) {
                dput(dentry);
@@ -644,7 +655,7 @@ static int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE,
                return ERR_PTR(-EACCES);
        }
 
-       return dentry_open(dentry, mqueue_mnt, oflag);
+       return dentry_open(dentry, mqueue_mnt, oflag, cred);
 }
 
 asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode,
@@ -1139,11 +1150,7 @@ asmlinkage long sys_mq_getsetattr(mqd_t mqdes,
        omqstat = info->attr;
        omqstat.mq_flags = filp->f_flags & O_NONBLOCK;
        if (u_mqstat) {
-               ret = audit_mq_getsetattr(mqdes, &mqstat);
-               if (ret != 0) {
-                       spin_unlock(&info->lock);
-                       goto out_fput;
-               }
+               audit_mq_getsetattr(mqdes, &mqstat);
                if (mqstat.mq_flags & O_NONBLOCK)
                        filp->f_flags |= O_NONBLOCK;
                else
@@ -1191,11 +1198,11 @@ static struct file_system_type mqueue_fs_type = {
        .kill_sb = kill_litter_super,
 };
 
-static int msg_max_limit_min = DFLT_MSGMAX;
-static int msg_max_limit_max = HARD_MSGMAX;
+static int msg_max_limit_min = MIN_MSGMAX;
+static int msg_max_limit_max = MAX_MSGMAX;
 
-static int msg_maxsize_limit_min = DFLT_MSGSIZEMAX;
-static int msg_maxsize_limit_max = INT_MAX;
+static int msg_maxsize_limit_min = MIN_MSGSIZEMAX;
+static int msg_maxsize_limit_max = MAX_MSGSIZEMAX;
 
 static ctl_table mq_sysctls[] = {
        {