CRED: Use RCU to access another task's creds and to release a task's own creds
[deliverable/linux.git] / fs / proc / base.c
index b5918ae8ca79a7823bd6a4d3eb0ecfc0b08d30f6..cf42c42cbfbbf5db12491dc769585f4a0c7f4229 100644 (file)
@@ -1406,6 +1406,7 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st
 {
        struct inode * inode;
        struct proc_inode *ei;
+       const struct cred *cred;
 
        /* We need a new inode */
 
@@ -1428,8 +1429,11 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st
        inode->i_uid = 0;
        inode->i_gid = 0;
        if (task_dumpable(task)) {
-               inode->i_uid = task->euid;
-               inode->i_gid = task->egid;
+               rcu_read_lock();
+               cred = __task_cred(task);
+               inode->i_uid = cred->euid;
+               inode->i_gid = cred->egid;
+               rcu_read_unlock();
        }
        security_task_to_inode(task, inode);
 
@@ -1445,6 +1449,8 @@ static int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat
 {
        struct inode *inode = dentry->d_inode;
        struct task_struct *task;
+       const struct cred *cred;
+
        generic_fillattr(inode, stat);
 
        rcu_read_lock();
@@ -1454,8 +1460,9 @@ static int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat
        if (task) {
                if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
                    task_dumpable(task)) {
-                       stat->uid = task->euid;
-                       stat->gid = task->egid;
+                       cred = __task_cred(task);
+                       stat->uid = cred->euid;
+                       stat->gid = cred->egid;
                }
        }
        rcu_read_unlock();
@@ -1483,11 +1490,16 @@ static int pid_revalidate(struct dentry *dentry, struct nameidata *nd)
 {
        struct inode *inode = dentry->d_inode;
        struct task_struct *task = get_proc_task(inode);
+       const struct cred *cred;
+
        if (task) {
                if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
                    task_dumpable(task)) {
-                       inode->i_uid = task->euid;
-                       inode->i_gid = task->egid;
+                       rcu_read_lock();
+                       cred = __task_cred(task);
+                       inode->i_uid = cred->euid;
+                       inode->i_gid = cred->egid;
+                       rcu_read_unlock();
                } else {
                        inode->i_uid = 0;
                        inode->i_gid = 0;
@@ -1649,6 +1661,7 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
        struct task_struct *task = get_proc_task(inode);
        int fd = proc_fd(inode);
        struct files_struct *files;
+       const struct cred *cred;
 
        if (task) {
                files = get_files_struct(task);
@@ -1658,8 +1671,11 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
                                rcu_read_unlock();
                                put_files_struct(files);
                                if (task_dumpable(task)) {
-                                       inode->i_uid = task->euid;
-                                       inode->i_gid = task->egid;
+                                       rcu_read_lock();
+                                       cred = __task_cred(task);
+                                       inode->i_uid = cred->euid;
+                                       inode->i_gid = cred->egid;
+                                       rcu_read_unlock();
                                } else {
                                        inode->i_uid = 0;
                                        inode->i_gid = 0;
@@ -1712,9 +1728,9 @@ static struct dentry *proc_fd_instantiate(struct inode *dir,
        file = fcheck_files(files, fd);
        if (!file)
                goto out_unlock;
-       if (file->f_mode & 1)
+       if (file->f_mode & FMODE_READ)
                inode->i_mode |= S_IRUSR | S_IXUSR;
-       if (file->f_mode & 2)
+       if (file->f_mode & FMODE_WRITE)
                inode->i_mode |= S_IWUSR | S_IXUSR;
        spin_unlock(&files->file_lock);
        put_files_struct(files);
This page took 0.034744 seconds and 5 git commands to generate.