Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ab8d11be authored by Miklos Szeredi's avatar Miklos Szeredi Committed by Linus Torvalds
Browse files

[PATCH] remove duplicated code from proc and ptrace



Extract common code used by ptrace_attach() and may_ptrace_attach()
into a separate function.

Signed-off-by: default avatarMiklos Szeredi <miklos@szeredi.hu>
Cc: <viro@parcelfarce.linux.theplanet.co.uk>
Cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 5e21ccb1
Loading
Loading
Loading
Loading
+4 −31
Original line number Diff line number Diff line
@@ -346,33 +346,6 @@ static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vf
	 (task->state == TASK_STOPPED || task->state == TASK_TRACED) && \
	 security_ptrace(current,task) == 0))

static int may_ptrace_attach(struct task_struct *task)
{
	int retval = 0;

	task_lock(task);

	if (!task->mm)
		goto out;
	if (((current->uid != task->euid) ||
	     (current->uid != task->suid) ||
	     (current->uid != task->uid) ||
	     (current->gid != task->egid) ||
	     (current->gid != task->sgid) ||
	     (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
		goto out;
	rmb();
	if (task->mm->dumpable != 1 && !capable(CAP_SYS_PTRACE))
		goto out;
	if (security_ptrace(current, task))
		goto out;

	retval = 1;
out:
	task_unlock(task);
	return retval;
}

static int proc_pid_environ(struct task_struct *task, char * buffer)
{
	int res = 0;
@@ -382,7 +355,7 @@ static int proc_pid_environ(struct task_struct *task, char * buffer)
		if (len > PAGE_SIZE)
			len = PAGE_SIZE;
		res = access_process_vm(task, mm->env_start, buffer, len, 0);
		if (!may_ptrace_attach(task))
		if (!ptrace_may_attach(task))
			res = -ESRCH;
		mmput(mm);
	}
@@ -685,7 +658,7 @@ static ssize_t mem_read(struct file * file, char __user * buf,
	int ret = -ESRCH;
	struct mm_struct *mm;

	if (!MAY_PTRACE(task) || !may_ptrace_attach(task))
	if (!MAY_PTRACE(task) || !ptrace_may_attach(task))
		goto out;

	ret = -ENOMEM;
@@ -711,7 +684,7 @@ static ssize_t mem_read(struct file * file, char __user * buf,

		this_len = (count > PAGE_SIZE) ? PAGE_SIZE : count;
		retval = access_process_vm(task, src, page, this_len, 0);
		if (!retval || !MAY_PTRACE(task) || !may_ptrace_attach(task)) {
		if (!retval || !MAY_PTRACE(task) || !ptrace_may_attach(task)) {
			if (!ret)
				ret = -EIO;
			break;
@@ -749,7 +722,7 @@ static ssize_t mem_write(struct file * file, const char * buf,
	struct task_struct *task = proc_task(file->f_dentry->d_inode);
	unsigned long dst = *ppos;

	if (!MAY_PTRACE(task) || !may_ptrace_attach(task))
	if (!MAY_PTRACE(task) || !ptrace_may_attach(task))
		return -ESRCH;

	page = (char *)__get_free_page(GFP_USER);
+1 −0
Original line number Diff line number Diff line
@@ -90,6 +90,7 @@ extern void __ptrace_link(struct task_struct *child,
			  struct task_struct *new_parent);
extern void __ptrace_unlink(struct task_struct *child);
extern void ptrace_untrace(struct task_struct *child);
extern int ptrace_may_attach(struct task_struct *task);

static inline void ptrace_link(struct task_struct *child,
			       struct task_struct *new_parent)
+28 −13
Original line number Diff line number Diff line
@@ -118,31 +118,46 @@ int ptrace_check_attach(struct task_struct *child, int kill)
	return ret;
}

int ptrace_attach(struct task_struct *task)
static int may_attach(struct task_struct *task)
{
	int retval;
	task_lock(task);
	retval = -EPERM;
	if (task->pid <= 1)
		goto bad;
	if (task == current)
		goto bad;
	if (!task->mm)
		goto bad;
		return -EPERM;
	if (((current->uid != task->euid) ||
	     (current->uid != task->suid) ||
	     (current->uid != task->uid) ||
	     (current->gid != task->egid) ||
	     (current->gid != task->sgid) ||
	     (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
		goto bad;
		return -EPERM;
	smp_rmb();
	if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE))
		return -EPERM;

	return security_ptrace(current, task);
}

int ptrace_may_attach(struct task_struct *task)
{
	int err;
	task_lock(task);
	err = may_attach(task);
	task_unlock(task);
	return !err;
}

int ptrace_attach(struct task_struct *task)
{
	int retval;
	task_lock(task);
	retval = -EPERM;
	if (task->pid <= 1)
		goto bad;
	if (task == current)
		goto bad;
	/* the same process cannot be attached many times */
	if (task->ptrace & PT_PTRACED)
		goto bad;
	retval = security_ptrace(current, task);
	retval = may_attach(task);
	if (retval)
		goto bad;