]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/proc/base.c
Merge branch 'for-linus' of git://git.linaro.org/people/rmk/linux-arm
[karo-tx-linux.git] / fs / proc / base.c
index b55c3bb298e365e296f18eb76f898f793c037cb2..d295af993677dda290242adb5e0187deef1bcb7c 100644 (file)
@@ -1088,7 +1088,8 @@ static ssize_t proc_loginuid_read(struct file * file, char __user * buf,
        if (!task)
                return -ESRCH;
        length = scnprintf(tmpbuf, TMPBUFLEN, "%u",
-                               audit_get_loginuid(task));
+                          from_kuid(file->f_cred->user_ns,
+                                    audit_get_loginuid(task)));
        put_task_struct(task);
        return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
 }
@@ -1100,6 +1101,7 @@ static ssize_t proc_loginuid_write(struct file * file, const char __user * buf,
        char *page, *tmp;
        ssize_t length;
        uid_t loginuid;
+       kuid_t kloginuid;
 
        rcu_read_lock();
        if (current != pid_task(proc_pid(inode), PIDTYPE_PID)) {
@@ -1129,7 +1131,13 @@ static ssize_t proc_loginuid_write(struct file * file, const char __user * buf,
                goto out_free_page;
 
        }
-       length = audit_set_loginuid(loginuid);
+       kloginuid = make_kuid(file->f_cred->user_ns, loginuid);
+       if (!uid_valid(kloginuid)) {
+               length = -EINVAL;
+               goto out_free_page;
+       }
+
+       length = audit_set_loginuid(kloginuid);
        if (likely(length == 0))
                length = count;
 
@@ -1805,7 +1813,7 @@ out:
 }
 
 struct map_files_info {
-       struct file     *file;
+       fmode_t         mode;
        unsigned long   len;
        unsigned char   name[4*sizeof(long)+2]; /* max: %lx-%lx\0 */
 };
@@ -1814,13 +1822,10 @@ static struct dentry *
 proc_map_files_instantiate(struct inode *dir, struct dentry *dentry,
                           struct task_struct *task, const void *ptr)
 {
-       const struct file *file = ptr;
+       fmode_t mode = (fmode_t)(unsigned long)ptr;
        struct proc_inode *ei;
        struct inode *inode;
 
-       if (!file)
-               return ERR_PTR(-ENOENT);
-
        inode = proc_pid_make_inode(dir->i_sb, task);
        if (!inode)
                return ERR_PTR(-ENOENT);
@@ -1832,9 +1837,9 @@ proc_map_files_instantiate(struct inode *dir, struct dentry *dentry,
        inode->i_size = 64;
        inode->i_mode = S_IFLNK;
 
-       if (file->f_mode & FMODE_READ)
+       if (mode & FMODE_READ)
                inode->i_mode |= S_IRUSR;
-       if (file->f_mode & FMODE_WRITE)
+       if (mode & FMODE_WRITE)
                inode->i_mode |= S_IWUSR;
 
        d_set_d_op(dentry, &tid_map_files_dentry_operations);
@@ -1878,7 +1883,8 @@ static struct dentry *proc_map_files_lookup(struct inode *dir,
        if (!vma)
                goto out_no_vma;
 
-       result = proc_map_files_instantiate(dir, dentry, task, vma->vm_file);
+       result = proc_map_files_instantiate(dir, dentry, task,
+                       (void *)(unsigned long)vma->vm_file->f_mode);
 
 out_no_vma:
        up_read(&mm->mmap_sem);
@@ -1979,8 +1985,7 @@ proc_map_files_readdir(struct file *filp, void *dirent, filldir_t filldir)
                                if (++pos <= filp->f_pos)
                                        continue;
 
-                               get_file(vma->vm_file);
-                               info.file = vma->vm_file;
+                               info.mode = vma->vm_file->f_mode;
                                info.len = snprintf(info.name,
                                                sizeof(info.name), "%lx-%lx",
                                                vma->vm_start, vma->vm_end);
@@ -1995,19 +2000,11 @@ proc_map_files_readdir(struct file *filp, void *dirent, filldir_t filldir)
                        ret = proc_fill_cache(filp, dirent, filldir,
                                              p->name, p->len,
                                              proc_map_files_instantiate,
-                                             task, p->file);
+                                             task,
+                                             (void *)(unsigned long)p->mode);
                        if (ret)
                                break;
                        filp->f_pos++;
-                       fput(p->file);
-               }
-               for (; i < nr_files; i++) {
-                       /*
-                        * In case of error don't forget
-                        * to put rest of file refs.
-                        */
-                       p = flex_array_get(fa, i);
-                       fput(p->file);
                }
                if (fa)
                        flex_array_free(fa);
@@ -2599,6 +2596,11 @@ static int proc_gid_map_open(struct inode *inode, struct file *file)
        return proc_id_map_open(inode, file, &proc_gid_seq_operations);
 }
 
+static int proc_projid_map_open(struct inode *inode, struct file *file)
+{
+       return proc_id_map_open(inode, file, &proc_projid_seq_operations);
+}
+
 static const struct file_operations proc_uid_map_operations = {
        .open           = proc_uid_map_open,
        .write          = proc_uid_map_write,
@@ -2614,6 +2616,14 @@ static const struct file_operations proc_gid_map_operations = {
        .llseek         = seq_lseek,
        .release        = proc_id_map_release,
 };
+
+static const struct file_operations proc_projid_map_operations = {
+       .open           = proc_projid_map_open,
+       .write          = proc_projid_map_write,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = proc_id_map_release,
+};
 #endif /* CONFIG_USER_NS */
 
 static int proc_pid_personality(struct seq_file *m, struct pid_namespace *ns,
@@ -2721,6 +2731,7 @@ static const struct pid_entry tgid_base_stuff[] = {
 #ifdef CONFIG_USER_NS
        REG("uid_map",    S_IRUGO|S_IWUSR, proc_uid_map_operations),
        REG("gid_map",    S_IRUGO|S_IWUSR, proc_gid_map_operations),
+       REG("projid_map", S_IRUGO|S_IWUSR, proc_projid_map_operations),
 #endif
 };
 
@@ -3084,6 +3095,7 @@ static const struct pid_entry tid_base_stuff[] = {
 #ifdef CONFIG_USER_NS
        REG("uid_map",    S_IRUGO|S_IWUSR, proc_uid_map_operations),
        REG("gid_map",    S_IRUGO|S_IWUSR, proc_gid_map_operations),
+       REG("projid_map", S_IRUGO|S_IWUSR, proc_projid_map_operations),
 #endif
 };