patch-2.4.22 linux-2.4.22/fs/proc/base.c
Next file: linux-2.4.22/fs/proc/proc_misc.c
Previous file: linux-2.4.22/fs/pipe.c
Back to the patch index
Back to the overall index
- Lines: 104
- Date:
2003-08-25 04:44:43.000000000 -0700
- Orig file:
linux-2.4.21/fs/proc/base.c
- Orig date:
2003-06-13 07:51:37.000000000 -0700
diff -urN linux-2.4.21/fs/proc/base.c linux-2.4.22/fs/proc/base.c
@@ -124,20 +124,56 @@
return result;
}
+#define MAY_PTRACE(task) \
+ (task == current || \
+ (task->p_pptr == current && \
+ (task->ptrace & PT_PTRACED) && task->state == TASK_STOPPED))
+
+static int may_ptrace_attach(struct task_struct *task)
+{
+ int retval = 0;
+
+ task_lock(task);
+
+ if (((current->uid != task->euid) ||
+ (current->uid != task->suid) ||
+ (current->uid != task->uid) ||
+ (current->gid != task->egid) ||
+ (current->gid != task->sgid) ||
+ (!cap_issubset(task->cap_permitted, current->cap_permitted)) ||
+ (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
+ goto out;
+ rmb();
+ if (!is_dumpable(task) && !capable(CAP_SYS_PTRACE))
+ goto out;
+
+ retval = 1;
+
+out:
+ task_unlock(task);
+ return retval;
+}
+
static int proc_pid_environ(struct task_struct *task, char * buffer)
{
struct mm_struct *mm;
int res = 0;
+
+ if (!may_ptrace_attach(task))
+ return -ESRCH;
+
task_lock(task);
mm = task->mm;
if (mm)
atomic_inc(&mm->mm_users);
task_unlock(task);
if (mm) {
- int len = mm->env_end - mm->env_start;
+ unsigned int len = mm->env_end - mm->env_start;
if (len > PAGE_SIZE)
len = PAGE_SIZE;
res = access_process_vm(task, mm->env_start, buffer, len, 0);
+ if (!may_ptrace_attach(task))
+ res = -ESRCH;
mmput(mm);
}
return res;
@@ -328,10 +364,6 @@
read: proc_info_read,
};
-#define MAY_PTRACE(p) \
-(p==current||(p->p_pptr==current&&(p->ptrace & PT_PTRACED)&&p->state==TASK_STOPPED))
-
-
static int mem_open(struct inode* inode, struct file* file)
{
file->private_data = (void*)((long)current->self_exec_id);
@@ -347,8 +379,7 @@
int copied = 0;
struct mm_struct *mm;
-
- if (!MAY_PTRACE(task))
+ if (!MAY_PTRACE(task) || !may_ptrace_attach(task))
return -ESRCH;
page = (char *)__get_free_page(GFP_USER);
@@ -370,14 +401,13 @@
copied = -EIO;
goto out_free;
}
-
while (count > 0) {
int this_len, retval;
this_len = (count > PAGE_SIZE) ? PAGE_SIZE : count;
retval = access_process_vm(task, src, page, this_len, 0);
- if (!retval) {
+ if (!retval || !MAY_PTRACE(task) || !may_ptrace_attach(task)) {
if (!copied)
copied = -EIO;
break;
@@ -411,7 +441,7 @@
struct task_struct *task = file->f_dentry->d_inode->u.proc_i.task;
unsigned long dst = *ppos;
- if (!MAY_PTRACE(task))
+ if (!MAY_PTRACE(task) || !may_ptrace_attach(task))
return -ESRCH;
page = (char *)__get_free_page(GFP_USER);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)