aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc/base.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/proc/base.c')
-rw-r--r--fs/proc/base.c71
1 files changed, 48 insertions, 23 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index a17c26859074..7411bfb0b7cc 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -202,6 +202,26 @@ static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vf
202 (task->state == TASK_STOPPED || task->state == TASK_TRACED) && \ 202 (task->state == TASK_STOPPED || task->state == TASK_TRACED) && \
203 security_ptrace(current,task) == 0)) 203 security_ptrace(current,task) == 0))
204 204
205struct mm_struct *mm_for_maps(struct task_struct *task)
206{
207 struct mm_struct *mm = get_task_mm(task);
208 if (!mm)
209 return NULL;
210 down_read(&mm->mmap_sem);
211 task_lock(task);
212 if (task->mm != mm)
213 goto out;
214 if (task->mm != current->mm && __ptrace_may_attach(task) < 0)
215 goto out;
216 task_unlock(task);
217 return mm;
218out:
219 task_unlock(task);
220 up_read(&mm->mmap_sem);
221 mmput(mm);
222 return NULL;
223}
224
205static int proc_pid_cmdline(struct task_struct *task, char * buffer) 225static int proc_pid_cmdline(struct task_struct *task, char * buffer)
206{ 226{
207 int res = 0; 227 int res = 0;
@@ -2411,19 +2431,23 @@ out:
2411 * Find the first task with tgid >= tgid 2431 * Find the first task with tgid >= tgid
2412 * 2432 *
2413 */ 2433 */
2414static struct task_struct *next_tgid(unsigned int tgid, 2434struct tgid_iter {
2415 struct pid_namespace *ns) 2435 unsigned int tgid;
2416{
2417 struct task_struct *task; 2436 struct task_struct *task;
2437};
2438static struct tgid_iter next_tgid(struct pid_namespace *ns, struct tgid_iter iter)
2439{
2418 struct pid *pid; 2440 struct pid *pid;
2419 2441
2442 if (iter.task)
2443 put_task_struct(iter.task);
2420 rcu_read_lock(); 2444 rcu_read_lock();
2421retry: 2445retry:
2422 task = NULL; 2446 iter.task = NULL;
2423 pid = find_ge_pid(tgid, ns); 2447 pid = find_ge_pid(iter.tgid, ns);
2424 if (pid) { 2448 if (pid) {
2425 tgid = pid_nr_ns(pid, ns) + 1; 2449 iter.tgid = pid_nr_ns(pid, ns);
2426 task = pid_task(pid, PIDTYPE_PID); 2450 iter.task = pid_task(pid, PIDTYPE_PID);
2427 /* What we to know is if the pid we have find is the 2451 /* What we to know is if the pid we have find is the
2428 * pid of a thread_group_leader. Testing for task 2452 * pid of a thread_group_leader. Testing for task
2429 * being a thread_group_leader is the obvious thing 2453 * being a thread_group_leader is the obvious thing
@@ -2436,23 +2460,25 @@ retry:
2436 * found doesn't happen to be a thread group leader. 2460 * found doesn't happen to be a thread group leader.
2437 * As we don't care in the case of readdir. 2461 * As we don't care in the case of readdir.
2438 */ 2462 */
2439 if (!task || !has_group_leader_pid(task)) 2463 if (!iter.task || !has_group_leader_pid(iter.task)) {
2464 iter.tgid += 1;
2440 goto retry; 2465 goto retry;
2441 get_task_struct(task); 2466 }
2467 get_task_struct(iter.task);
2442 } 2468 }
2443 rcu_read_unlock(); 2469 rcu_read_unlock();
2444 return task; 2470 return iter;
2445} 2471}
2446 2472
2447#define TGID_OFFSET (FIRST_PROCESS_ENTRY + ARRAY_SIZE(proc_base_stuff)) 2473#define TGID_OFFSET (FIRST_PROCESS_ENTRY + ARRAY_SIZE(proc_base_stuff))
2448 2474
2449static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldir, 2475static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
2450 struct task_struct *task, int tgid) 2476 struct tgid_iter iter)
2451{ 2477{
2452 char name[PROC_NUMBUF]; 2478 char name[PROC_NUMBUF];
2453 int len = snprintf(name, sizeof(name), "%d", tgid); 2479 int len = snprintf(name, sizeof(name), "%d", iter.tgid);
2454 return proc_fill_cache(filp, dirent, filldir, name, len, 2480 return proc_fill_cache(filp, dirent, filldir, name, len,
2455 proc_pid_instantiate, task, NULL); 2481 proc_pid_instantiate, iter.task, NULL);
2456} 2482}
2457 2483
2458/* for the /proc/ directory itself, after non-process stuff has been done */ 2484/* for the /proc/ directory itself, after non-process stuff has been done */
@@ -2460,8 +2486,7 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
2460{ 2486{
2461 unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY; 2487 unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
2462 struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode); 2488 struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode);
2463 struct task_struct *task; 2489 struct tgid_iter iter;
2464 int tgid;
2465 struct pid_namespace *ns; 2490 struct pid_namespace *ns;
2466 2491
2467 if (!reaper) 2492 if (!reaper)
@@ -2474,14 +2499,14 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
2474 } 2499 }
2475 2500
2476 ns = filp->f_dentry->d_sb->s_fs_info; 2501 ns = filp->f_dentry->d_sb->s_fs_info;
2477 tgid = filp->f_pos - TGID_OFFSET; 2502 iter.task = NULL;
2478 for (task = next_tgid(tgid, ns); 2503 iter.tgid = filp->f_pos - TGID_OFFSET;
2479 task; 2504 for (iter = next_tgid(ns, iter);
2480 put_task_struct(task), task = next_tgid(tgid + 1, ns)) { 2505 iter.task;
2481 tgid = task_pid_nr_ns(task, ns); 2506 iter.tgid += 1, iter = next_tgid(ns, iter)) {
2482 filp->f_pos = tgid + TGID_OFFSET; 2507 filp->f_pos = iter.tgid + TGID_OFFSET;
2483 if (proc_pid_fill_cache(filp, dirent, filldir, task, tgid) < 0) { 2508 if (proc_pid_fill_cache(filp, dirent, filldir, iter) < 0) {
2484 put_task_struct(task); 2509 put_task_struct(iter.task);
2485 goto out; 2510 goto out;
2486 } 2511 }
2487 } 2512 }