[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: Miklos Szeredi <miklos@szeredi.hu> Cc: <viro@parcelfarce.linux.theplanet.co.uk> Cc: Christoph Hellwig <hch@lst.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
Родитель
5e21ccb136
Коммит
ab8d11beb4
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -118,6 +118,33 @@ int ptrace_check_attach(struct task_struct *child, int kill)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int may_attach(struct task_struct *task)
|
||||
{
|
||||
if (!task->mm)
|
||||
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))
|
||||
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;
|
||||
|
@ -127,22 +154,10 @@ int ptrace_attach(struct task_struct *task)
|
|||
goto bad;
|
||||
if (task == current)
|
||||
goto bad;
|
||||
if (!task->mm)
|
||||
goto bad;
|
||||
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;
|
||||
smp_rmb();
|
||||
if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE))
|
||||
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;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче