diff options
Diffstat (limited to 'fs/proc/base.c')
| -rw-r--r-- | fs/proc/base.c | 17 | 
1 files changed, 10 insertions, 7 deletions
| diff --git a/fs/proc/base.c b/fs/proc/base.c index 616f41a7cde6..437195f204e1 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -1803,7 +1803,7 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)  			rcu_read_lock();  			file = fcheck_files(files, fd);  			if (file) { -				unsigned i_mode, f_mode = file->f_mode; +				unsigned f_mode = file->f_mode;  				rcu_read_unlock();  				put_files_struct(files); @@ -1819,12 +1819,14 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)  					inode->i_gid = GLOBAL_ROOT_GID;  				} -				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; +				if (S_ISLNK(inode->i_mode)) { +					unsigned 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); @@ -1859,6 +1861,7 @@ static struct dentry *proc_fd_instantiate(struct inode *dir,  	ei = PROC_I(inode);  	ei->fd = fd; +	inode->i_mode = S_IFLNK;  	inode->i_op = &proc_pid_link_inode_operations;  	inode->i_size = 64;  	ei->op.proc_get_link = proc_fd_link; | 
