aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/proc/base.c43
1 files changed, 14 insertions, 29 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 1c8b280146d7..7d6ad98631f2 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1799,10 +1799,15 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
1799 if (task) { 1799 if (task) {
1800 files = get_files_struct(task); 1800 files = get_files_struct(task);
1801 if (files) { 1801 if (files) {
1802 struct file *file;
1802 rcu_read_lock(); 1803 rcu_read_lock();
1803 if (fcheck_files(files, fd)) { 1804 file = fcheck_files(files, fd);
1805 if (file) {
1806 unsigned i_mode, f_mode = file->f_mode;
1807
1804 rcu_read_unlock(); 1808 rcu_read_unlock();
1805 put_files_struct(files); 1809 put_files_struct(files);
1810
1806 if (task_dumpable(task)) { 1811 if (task_dumpable(task)) {
1807 rcu_read_lock(); 1812 rcu_read_lock();
1808 cred = __task_cred(task); 1813 cred = __task_cred(task);
@@ -1813,7 +1818,14 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
1813 inode->i_uid = 0; 1818 inode->i_uid = 0;
1814 inode->i_gid = 0; 1819 inode->i_gid = 0;
1815 } 1820 }
1816 inode->i_mode &= ~(S_ISUID | S_ISGID); 1821
1822 i_mode = S_IFLNK;
1823 if (f_mode & FMODE_READ)
1824 i_mode |= S_IRUSR | S_IXUSR;
1825 if (f_mode & FMODE_WRITE)
1826 i_mode |= S_IWUSR | S_IXUSR;
1827 inode->i_mode = i_mode;
1828
1817 security_task_to_inode(task, inode); 1829 security_task_to_inode(task, inode);
1818 put_task_struct(task); 1830 put_task_struct(task);
1819 return 1; 1831 return 1;
@@ -1837,8 +1849,6 @@ static struct dentry *proc_fd_instantiate(struct inode *dir,
1837 struct dentry *dentry, struct task_struct *task, const void *ptr) 1849 struct dentry *dentry, struct task_struct *task, const void *ptr)
1838{ 1850{
1839 unsigned fd = *(const unsigned *)ptr; 1851 unsigned fd = *(const unsigned *)ptr;
1840 struct file *file;
1841 struct files_struct *files;
1842 struct inode *inode; 1852 struct inode *inode;
1843 struct proc_inode *ei; 1853 struct proc_inode *ei;
1844 struct dentry *error = ERR_PTR(-ENOENT); 1854 struct dentry *error = ERR_PTR(-ENOENT);
@@ -1848,25 +1858,6 @@ static struct dentry *proc_fd_instantiate(struct inode *dir,
1848 goto out; 1858 goto out;
1849 ei = PROC_I(inode); 1859 ei = PROC_I(inode);
1850 ei->fd = fd; 1860 ei->fd = fd;
1851 files = get_files_struct(task);
1852 if (!files)
1853 goto out_iput;
1854 inode->i_mode = S_IFLNK;
1855
1856 /*
1857 * We are not taking a ref to the file structure, so we must
1858 * hold ->file_lock.
1859 */
1860 spin_lock(&files->file_lock);
1861 file = fcheck_files(files, fd);
1862 if (!file)
1863 goto out_unlock;
1864 if (file->f_mode & FMODE_READ)
1865 inode->i_mode |= S_IRUSR | S_IXUSR;
1866 if (file->f_mode & FMODE_WRITE)
1867 inode->i_mode |= S_IWUSR | S_IXUSR;
1868 spin_unlock(&files->file_lock);
1869 put_files_struct(files);
1870 1861
1871 inode->i_op = &proc_pid_link_inode_operations; 1862 inode->i_op = &proc_pid_link_inode_operations;
1872 inode->i_size = 64; 1863 inode->i_size = 64;
@@ -1879,12 +1870,6 @@ static struct dentry *proc_fd_instantiate(struct inode *dir,
1879 1870
1880 out: 1871 out:
1881 return error; 1872 return error;
1882out_unlock:
1883 spin_unlock(&files->file_lock);
1884 put_files_struct(files);
1885out_iput:
1886 iput(inode);
1887 goto out;
1888} 1873}
1889 1874
1890static struct dentry *proc_lookupfd_common(struct inode *dir, 1875static struct dentry *proc_lookupfd_common(struct inode *dir,