View | Details | Raw Unified
Collapse All | Expand All

(-) file_not_specified_in_diff (-95 / +29 lines)
 Lines 532-573   static int proc_oom_score(struct task_st Link Here 
/************************************************************************/
/************************************************************************/
/* permission checks */
/* permission checks */
static int proc_fd_access_allowed(struct inode *inode)
/* If the process being read is separated by chroot from the reading process,
 * don't let the reader access the threads.
 */
static int proc_check_chroot(struct dentry *de, struct vfsmount *mnt)
{
{
	struct dentry *base;
	struct task_struct *task;
	struct vfsmount *our_vfsmnt;
	int allowed = 0;
	int res = 0;
	/* Allow access to a task's file descriptors if either we may
	 * use ptrace attach to the process and find out that
	read_lock(&current->fs->lock);
	 * information, or if the task cannot possibly be ptraced
	our_vfsmnt = mntget(current->fs->rootmnt);
	 * allow access if we have the proper capability.
	base = dget(current->fs->root);
	 */
	read_unlock(&current->fs->lock);
	task = get_proc_task(inode);
	if (task == current)
	spin_lock(&vfsmount_lock);
		allowed = 1;
	if (task && !allowed) {
		int alive;
	while (mnt != our_vfsmnt) {
		task_lock(task);
		if (mnt == mnt->mnt_parent)
		alive = !!task->mm;
			goto out;
		task_unlock(task);
		de = mnt->mnt_mountpoint;
		if (alive)
		mnt = mnt->mnt_parent;
			/* For a living task obey ptrace_may_attach */
			allowed = ptrace_may_attach(task);
		else
			/* For a special task simply check the capability */
			allowed = capable(CAP_SYS_PTRACE);
	}
	}
	if (task)
	if (!is_subdir(de, base))
		put_task_struct(task);
		goto out;
	return allowed;
	spin_unlock(&vfsmount_lock);
exit:
	dput(base);
	mntput(our_vfsmnt);
	return res;
out:
	spin_unlock(&vfsmount_lock);
	res = -EACCES;
	goto exit;
}
}
extern struct seq_operations mounts_op;
extern struct seq_operations mounts_op;
 Lines 1062-1113   static struct file_operations proc_secco Link Here 
};
};
#endif /* CONFIG_SECCOMP */
#endif /* CONFIG_SECCOMP */
static int proc_check_dentry_visible(struct inode *inode,
	struct dentry *dentry, struct vfsmount *mnt)
{
	/* Verify that the current process can already see the
	 * file pointed at by the file descriptor.
	 * This prevents /proc from being an accidental information leak.
	 *
	 * This prevents access to files that are not visible do to
	 * being on the otherside of a chroot, in a different
	 * namespace, or are simply process local (like pipes).
	 */
	struct task_struct *task;
	int error = -EACCES;
	/* See if the the two tasks share a commone set of
	 * file descriptors.  If so everything is visible.
	 */
	rcu_read_lock();
	task = tref_task(proc_tref(inode));
	if (task) {
		struct files_struct *task_files, *files;
		/* This test answeres the question:
		 * Is there a point in time since we looked up the
		 * file descriptor where the two tasks share the
		 * same files struct?
		 */
		rmb();
		files = current->files;
		task_files = task->files;
		if (files && (files == task_files))
			error = 0;
	}
	rcu_read_unlock();
	if (!error)
		goto out;
	/* If the two tasks don't share a common set of file
	 * descriptors see if the destination dentry is already
	 * visible in the current tasks filesystem namespace.
	 */
	error = proc_check_chroot(dentry, mnt);
out:
	return error;
}
static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
{
{
	struct inode *inode = dentry->d_inode;
	struct inode *inode = dentry->d_inode;
 Lines 1116-1133   static void *proc_pid_follow_link(struct Link Here 
	/* We don't need a base pointer in the /proc filesystem */
	/* We don't need a base pointer in the /proc filesystem */
	path_release(nd);
	path_release(nd);
	if (current->fsuid != inode->i_uid && !capable(CAP_DAC_OVERRIDE))
	/* Are we allowed to snoop on the tasks file descriptors? */
	if (!proc_fd_access_allowed(inode))
		goto out;
		goto out;
	error = PROC_I(inode)->op.proc_get_link(inode, &nd->dentry, &nd->mnt);
	error = PROC_I(inode)->op.proc_get_link(inode, &nd->dentry, &nd->mnt);
	nd->last_type = LAST_BIND;
	nd->last_type = LAST_BIND;
	if (error)
		goto out;
	/* Only return files this task can already see */
	error = proc_check_dentry_visible(inode, nd->dentry, nd->mnt);
	if (error)
		path_release(nd);
out:
out:
	return ERR_PTR(error);
	return ERR_PTR(error);
}
}
 Lines 1165-1185   static int proc_pid_readlink(struct dent Link Here 
	struct dentry *de;
	struct dentry *de;
	struct vfsmount *mnt = NULL;
	struct vfsmount *mnt = NULL;
	/* Are we allowed to snoop on the tasks file descriptors? */
	if (current->fsuid != inode->i_uid && !capable(CAP_DAC_OVERRIDE))
	if (!proc_fd_access_allowed(inode))
		goto out;
		goto out;
	error = PROC_I(inode)->op.proc_get_link(inode, &de, &mnt);
	error = PROC_I(inode)->op.proc_get_link(inode, &de, &mnt);
	if (error)
	if (error)
		goto out;
		goto out;
	/* Only return files this task can already see */
	error = proc_check_dentry_visible(inode, de, mnt);
	if (error)
		goto out_put;
	error = do_proc_readlink(de, mnt, buffer, buflen);
	error = do_proc_readlink(de, mnt, buffer, buflen);
out_put:
	dput(de);
	dput(de);
	mntput(mnt);
	mntput(mnt);
out:
out: