|
@@ -1799,10 +1799,15 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
|
|
|
if (task) {
|
|
|
files = get_files_struct(task);
|
|
|
if (files) {
|
|
|
+ struct file *file;
|
|
|
rcu_read_lock();
|
|
|
- if (fcheck_files(files, fd)) {
|
|
|
+ file = fcheck_files(files, fd);
|
|
|
+ if (file) {
|
|
|
+ unsigned i_mode, f_mode = file->f_mode;
|
|
|
+
|
|
|
rcu_read_unlock();
|
|
|
put_files_struct(files);
|
|
|
+
|
|
|
if (task_dumpable(task)) {
|
|
|
rcu_read_lock();
|
|
|
cred = __task_cred(task);
|
|
@@ -1813,7 +1818,14 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
|
|
|
inode->i_uid = 0;
|
|
|
inode->i_gid = 0;
|
|
|
}
|
|
|
- inode->i_mode &= ~(S_ISUID | S_ISGID);
|
|
|
+
|
|
|
+ i_mode = S_IFLNK;
|
|
|
+ if (f_mode & FMODE_READ)
|
|
|
+ i_mode |= S_IRUSR | S_IXUSR;
|
|
|
+ if (f_mode & FMODE_WRITE)
|
|
|
+ i_mode |= S_IWUSR | S_IXUSR;
|
|
|
+ inode->i_mode = i_mode;
|
|
|
+
|
|
|
security_task_to_inode(task, inode);
|
|
|
put_task_struct(task);
|
|
|
return 1;
|
|
@@ -1837,8 +1849,6 @@ static struct dentry *proc_fd_instantiate(struct inode *dir,
|
|
|
struct dentry *dentry, struct task_struct *task, const void *ptr)
|
|
|
{
|
|
|
unsigned fd = *(const unsigned *)ptr;
|
|
|
- struct file *file;
|
|
|
- struct files_struct *files;
|
|
|
struct inode *inode;
|
|
|
struct proc_inode *ei;
|
|
|
struct dentry *error = ERR_PTR(-ENOENT);
|
|
@@ -1848,25 +1858,6 @@ static struct dentry *proc_fd_instantiate(struct inode *dir,
|
|
|
goto out;
|
|
|
ei = PROC_I(inode);
|
|
|
ei->fd = fd;
|
|
|
- files = get_files_struct(task);
|
|
|
- if (!files)
|
|
|
- goto out_iput;
|
|
|
- inode->i_mode = S_IFLNK;
|
|
|
-
|
|
|
- /*
|
|
|
- * We are not taking a ref to the file structure, so we must
|
|
|
- * hold ->file_lock.
|
|
|
- */
|
|
|
- spin_lock(&files->file_lock);
|
|
|
- file = fcheck_files(files, fd);
|
|
|
- if (!file)
|
|
|
- goto out_unlock;
|
|
|
- if (file->f_mode & FMODE_READ)
|
|
|
- inode->i_mode |= S_IRUSR | S_IXUSR;
|
|
|
- if (file->f_mode & FMODE_WRITE)
|
|
|
- inode->i_mode |= S_IWUSR | S_IXUSR;
|
|
|
- spin_unlock(&files->file_lock);
|
|
|
- put_files_struct(files);
|
|
|
|
|
|
inode->i_op = &proc_pid_link_inode_operations;
|
|
|
inode->i_size = 64;
|
|
@@ -1879,12 +1870,6 @@ static struct dentry *proc_fd_instantiate(struct inode *dir,
|
|
|
|
|
|
out:
|
|
|
return error;
|
|
|
-out_unlock:
|
|
|
- spin_unlock(&files->file_lock);
|
|
|
- put_files_struct(files);
|
|
|
-out_iput:
|
|
|
- iput(inode);
|
|
|
- goto out;
|
|
|
}
|
|
|
|
|
|
static struct dentry *proc_lookupfd_common(struct inode *dir,
|