aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/proc/base.c35
-rw-r--r--include/linux/ptrace.h1
-rw-r--r--kernel/ptrace.c41
3 files changed, 33 insertions, 44 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 24eed139e54e..84751f3f52d5 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -346,33 +346,6 @@ static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vf
346 (task->state == TASK_STOPPED || task->state == TASK_TRACED) && \ 346 (task->state == TASK_STOPPED || task->state == TASK_TRACED) && \
347 security_ptrace(current,task) == 0)) 347 security_ptrace(current,task) == 0))
348 348
349static int may_ptrace_attach(struct task_struct *task)
350{
351 int retval = 0;
352
353 task_lock(task);
354
355 if (!task->mm)
356 goto out;
357 if (((current->uid != task->euid) ||
358 (current->uid != task->suid) ||
359 (current->uid != task->uid) ||
360 (current->gid != task->egid) ||
361 (current->gid != task->sgid) ||
362 (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
363 goto out;
364 rmb();
365 if (task->mm->dumpable != 1 && !capable(CAP_SYS_PTRACE))
366 goto out;
367 if (security_ptrace(current, task))
368 goto out;
369
370 retval = 1;
371out:
372 task_unlock(task);
373 return retval;
374}
375
376static int proc_pid_environ(struct task_struct *task, char * buffer) 349static int proc_pid_environ(struct task_struct *task, char * buffer)
377{ 350{
378 int res = 0; 351 int res = 0;
@@ -382,7 +355,7 @@ static int proc_pid_environ(struct task_struct *task, char * buffer)
382 if (len > PAGE_SIZE) 355 if (len > PAGE_SIZE)
383 len = PAGE_SIZE; 356 len = PAGE_SIZE;
384 res = access_process_vm(task, mm->env_start, buffer, len, 0); 357 res = access_process_vm(task, mm->env_start, buffer, len, 0);
385 if (!may_ptrace_attach(task)) 358 if (!ptrace_may_attach(task))
386 res = -ESRCH; 359 res = -ESRCH;
387 mmput(mm); 360 mmput(mm);
388 } 361 }
@@ -685,7 +658,7 @@ static ssize_t mem_read(struct file * file, char __user * buf,
685 int ret = -ESRCH; 658 int ret = -ESRCH;
686 struct mm_struct *mm; 659 struct mm_struct *mm;
687 660
688 if (!MAY_PTRACE(task) || !may_ptrace_attach(task)) 661 if (!MAY_PTRACE(task) || !ptrace_may_attach(task))
689 goto out; 662 goto out;
690 663
691 ret = -ENOMEM; 664 ret = -ENOMEM;
@@ -711,7 +684,7 @@ static ssize_t mem_read(struct file * file, char __user * buf,
711 684
712 this_len = (count > PAGE_SIZE) ? PAGE_SIZE : count; 685 this_len = (count > PAGE_SIZE) ? PAGE_SIZE : count;
713 retval = access_process_vm(task, src, page, this_len, 0); 686 retval = access_process_vm(task, src, page, this_len, 0);
714 if (!retval || !MAY_PTRACE(task) || !may_ptrace_attach(task)) { 687 if (!retval || !MAY_PTRACE(task) || !ptrace_may_attach(task)) {
715 if (!ret) 688 if (!ret)
716 ret = -EIO; 689 ret = -EIO;
717 break; 690 break;
@@ -749,7 +722,7 @@ static ssize_t mem_write(struct file * file, const char * buf,
749 struct task_struct *task = proc_task(file->f_dentry->d_inode); 722 struct task_struct *task = proc_task(file->f_dentry->d_inode);
750 unsigned long dst = *ppos; 723 unsigned long dst = *ppos;
751 724
752 if (!MAY_PTRACE(task) || !may_ptrace_attach(task)) 725 if (!MAY_PTRACE(task) || !ptrace_may_attach(task))
753 return -ESRCH; 726 return -ESRCH;
754 727
755 page = (char *)__get_free_page(GFP_USER); 728 page = (char *)__get_free_page(GFP_USER);
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
index 2afdafb62123..dc6f3647bfbc 100644
--- a/include/linux/ptrace.h
+++ b/include/linux/ptrace.h
@@ -90,6 +90,7 @@ extern void __ptrace_link(struct task_struct *child,
90 struct task_struct *new_parent); 90 struct task_struct *new_parent);
91extern void __ptrace_unlink(struct task_struct *child); 91extern void __ptrace_unlink(struct task_struct *child);
92extern void ptrace_untrace(struct task_struct *child); 92extern void ptrace_untrace(struct task_struct *child);
93extern int ptrace_may_attach(struct task_struct *task);
93 94
94static inline void ptrace_link(struct task_struct *child, 95static inline void ptrace_link(struct task_struct *child,
95 struct task_struct *new_parent) 96 struct task_struct *new_parent)
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 8dcb8f6288bc..019e04ec065a 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -118,6 +118,33 @@ int ptrace_check_attach(struct task_struct *child, int kill)
118 return ret; 118 return ret;
119} 119}
120 120
121static int may_attach(struct task_struct *task)
122{
123 if (!task->mm)
124 return -EPERM;
125 if (((current->uid != task->euid) ||
126 (current->uid != task->suid) ||
127 (current->uid != task->uid) ||
128 (current->gid != task->egid) ||
129 (current->gid != task->sgid) ||
130 (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
131 return -EPERM;
132 smp_rmb();
133 if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE))
134 return -EPERM;
135
136 return security_ptrace(current, task);
137}
138
139int ptrace_may_attach(struct task_struct *task)
140{
141 int err;
142 task_lock(task);
143 err = may_attach(task);
144 task_unlock(task);
145 return !err;
146}
147
121int ptrace_attach(struct task_struct *task) 148int ptrace_attach(struct task_struct *task)
122{ 149{
123 int retval; 150 int retval;
@@ -127,22 +154,10 @@ int ptrace_attach(struct task_struct *task)
127 goto bad; 154 goto bad;
128 if (task == current) 155 if (task == current)
129 goto bad; 156 goto bad;
130 if (!task->mm)
131 goto bad;
132 if(((current->uid != task->euid) ||
133 (current->uid != task->suid) ||
134 (current->uid != task->uid) ||
135 (current->gid != task->egid) ||
136 (current->gid != task->sgid) ||
137 (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
138 goto bad;
139 smp_rmb();
140 if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE))
141 goto bad;
142 /* the same process cannot be attached many times */ 157 /* the same process cannot be attached many times */
143 if (task->ptrace & PT_PTRACED) 158 if (task->ptrace & PT_PTRACED)
144 goto bad; 159 goto bad;
145 retval = security_ptrace(current, task); 160 retval = may_attach(task);
146 if (retval) 161 if (retval)
147 goto bad; 162 goto bad;
148 163