diff options
Diffstat (limited to 'fs/proc/base.c')
| -rw-r--r-- | fs/proc/base.c | 40 | 
1 files changed, 26 insertions, 14 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index e42bbd843ed1..a7310841c831 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -647,17 +647,11 @@ static int mounts_release(struct inode *inode, struct file *file)  static unsigned mounts_poll(struct file *file, poll_table *wait)  {  	struct proc_mounts *p = file->private_data; -	struct mnt_namespace *ns = p->ns;  	unsigned res = POLLIN | POLLRDNORM; -	poll_wait(file, &ns->poll, wait); - -	spin_lock(&vfsmount_lock); -	if (p->event != ns->event) { -		p->event = ns->event; +	poll_wait(file, &p->ns->poll, wait); +	if (mnt_had_events(p))  		res |= POLLERR | POLLPRI; -	} -	spin_unlock(&vfsmount_lock);  	return res;  } @@ -1095,8 +1089,12 @@ static ssize_t proc_loginuid_write(struct file * file, const char __user * buf,  	if (!capable(CAP_AUDIT_CONTROL))  		return -EPERM; -	if (current != pid_task(proc_pid(inode), PIDTYPE_PID)) +	rcu_read_lock(); +	if (current != pid_task(proc_pid(inode), PIDTYPE_PID)) { +		rcu_read_unlock();  		return -EPERM; +	} +	rcu_read_unlock();  	if (count >= PAGE_SIZE)  		count = PAGE_SIZE - 1; @@ -2369,16 +2367,30 @@ static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)  {  	struct pid_namespace *ns = dentry->d_sb->s_fs_info;  	pid_t tgid = task_tgid_nr_ns(current, ns); -	char tmp[PROC_NUMBUF]; -	if (!tgid) -		return ERR_PTR(-ENOENT); -	sprintf(tmp, "%d", task_tgid_nr_ns(current, ns)); -	return ERR_PTR(vfs_follow_link(nd,tmp)); +	char *name = ERR_PTR(-ENOENT); +	if (tgid) { +		name = __getname(); +		if (!name) +			name = ERR_PTR(-ENOMEM); +		else +			sprintf(name, "%d", tgid); +	} +	nd_set_link(nd, name); +	return NULL; +} + +static void proc_self_put_link(struct dentry *dentry, struct nameidata *nd, +				void *cookie) +{ +	char *s = nd_get_link(nd); +	if (!IS_ERR(s)) +		__putname(s);  }  static const struct inode_operations proc_self_inode_operations = {  	.readlink	= proc_self_readlink,  	.follow_link	= proc_self_follow_link, +	.put_link	= proc_self_put_link,  };  /*  |