diff options
Diffstat (limited to 'fs/proc/base.c')
| -rw-r--r-- | fs/proc/base.c | 42 | 
1 files changed, 23 insertions, 19 deletions
| diff --git a/fs/proc/base.c b/fs/proc/base.c index bd3e9e68125b..2cf5d7e37375 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -1564,12 +1564,16 @@ static int proc_exe_link(struct dentry *dentry, struct path *exe_path)  		return -ENOENT;  } -static const char *proc_pid_follow_link(struct dentry *dentry, void **cookie) +static const char *proc_pid_get_link(struct dentry *dentry, +				     struct inode *inode, +				     struct delayed_call *done)  { -	struct inode *inode = d_inode(dentry);  	struct path path;  	int error = -EACCES; +	if (!dentry) +		return ERR_PTR(-ECHILD); +  	/* Are we allowed to snoop on the tasks file descriptors? */  	if (!proc_fd_access_allowed(inode))  		goto out; @@ -1630,7 +1634,7 @@ out:  const struct inode_operations proc_pid_link_inode_operations = {  	.readlink	= proc_pid_readlink, -	.follow_link	= proc_pid_follow_link, +	.get_link	= proc_pid_get_link,  	.setattr	= proc_setattr,  }; @@ -1895,7 +1899,7 @@ static const struct dentry_operations tid_map_files_dentry_operations = {  	.d_delete	= pid_delete_dentry,  }; -static int proc_map_files_get_link(struct dentry *dentry, struct path *path) +static int map_files_get_link(struct dentry *dentry, struct path *path)  {  	unsigned long vm_start, vm_end;  	struct vm_area_struct *vma; @@ -1945,20 +1949,22 @@ struct map_files_info {   * path to the file in question.   */  static const char * -proc_map_files_follow_link(struct dentry *dentry, void **cookie) +proc_map_files_get_link(struct dentry *dentry, +			struct inode *inode, +		        struct delayed_call *done)  {  	if (!capable(CAP_SYS_ADMIN))  		return ERR_PTR(-EPERM); -	return proc_pid_follow_link(dentry, NULL); +	return proc_pid_get_link(dentry, inode, done);  }  /* - * Identical to proc_pid_link_inode_operations except for follow_link() + * Identical to proc_pid_link_inode_operations except for get_link()   */  static const struct inode_operations proc_map_files_link_inode_operations = {  	.readlink	= proc_pid_readlink, -	.follow_link	= proc_map_files_follow_link, +	.get_link	= proc_map_files_get_link,  	.setattr	= proc_setattr,  }; @@ -1975,7 +1981,7 @@ proc_map_files_instantiate(struct inode *dir, struct dentry *dentry,  		return -ENOENT;  	ei = PROC_I(inode); -	ei->op.proc_get_link = proc_map_files_get_link; +	ei->op.proc_get_link = map_files_get_link;  	inode->i_op = &proc_map_files_link_inode_operations;  	inode->i_size = 64; @@ -2359,7 +2365,7 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,  				   size_t count, loff_t *ppos)  {  	struct inode * inode = file_inode(file); -	char *page; +	void *page;  	ssize_t length;  	struct task_struct *task = get_proc_task(inode); @@ -2374,14 +2380,11 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,  	if (*ppos != 0)  		goto out; -	length = -ENOMEM; -	page = (char*)__get_free_page(GFP_TEMPORARY); -	if (!page) +	page = memdup_user(buf, count); +	if (IS_ERR(page)) { +		length = PTR_ERR(page);  		goto out; - -	length = -EFAULT; -	if (copy_from_user(page, buf, count)) -		goto out_free; +	}  	/* Guard against adverse ptrace interaction */  	length = mutex_lock_interruptible(&task->signal->cred_guard_mutex); @@ -2390,10 +2393,10 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,  	length = security_setprocattr(task,  				      (char*)file->f_path.dentry->d_name.name, -				      (void*)page, count); +				      page, count);  	mutex_unlock(&task->signal->cred_guard_mutex);  out_free: -	free_page((unsigned long) page); +	kfree(page);  out:  	put_task_struct(task);  out_no_task: @@ -2494,6 +2497,7 @@ static ssize_t proc_coredump_filter_write(struct file *file,  	mm = get_task_mm(task);  	if (!mm)  		goto out_no_mm; +	ret = 0;  	for (i = 0, mask = 1; i < MMF_DUMP_FILTER_BITS; i++, mask <<= 1) {  		if (val & mask) | 
