diff options
Diffstat (limited to 'fs/proc')
-rw-r--r-- | fs/proc/array.c | 27 | ||||
-rw-r--r-- | fs/proc/base.c | 37 |
2 files changed, 42 insertions, 22 deletions
diff --git a/fs/proc/array.c b/fs/proc/array.c index 24f7f9f6684d..04b689f3288f 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c | |||
@@ -77,6 +77,7 @@ | |||
77 | #include <linux/cpuset.h> | 77 | #include <linux/cpuset.h> |
78 | #include <linux/rcupdate.h> | 78 | #include <linux/rcupdate.h> |
79 | #include <linux/delayacct.h> | 79 | #include <linux/delayacct.h> |
80 | #include <linux/pid_namespace.h> | ||
80 | 81 | ||
81 | #include <asm/pgtable.h> | 82 | #include <asm/pgtable.h> |
82 | #include <asm/processor.h> | 83 | #include <asm/processor.h> |
@@ -161,8 +162,15 @@ static inline char *task_state(struct task_struct *p, char *buffer) | |||
161 | struct group_info *group_info; | 162 | struct group_info *group_info; |
162 | int g; | 163 | int g; |
163 | struct fdtable *fdt = NULL; | 164 | struct fdtable *fdt = NULL; |
165 | struct pid_namespace *ns; | ||
166 | pid_t ppid, tpid; | ||
164 | 167 | ||
168 | ns = current->nsproxy->pid_ns; | ||
165 | rcu_read_lock(); | 169 | rcu_read_lock(); |
170 | ppid = pid_alive(p) ? | ||
171 | task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0; | ||
172 | tpid = pid_alive(p) && p->ptrace ? | ||
173 | task_ppid_nr_ns(rcu_dereference(p->parent), ns) : 0; | ||
166 | buffer += sprintf(buffer, | 174 | buffer += sprintf(buffer, |
167 | "State:\t%s\n" | 175 | "State:\t%s\n" |
168 | "Tgid:\t%d\n" | 176 | "Tgid:\t%d\n" |
@@ -172,9 +180,9 @@ static inline char *task_state(struct task_struct *p, char *buffer) | |||
172 | "Uid:\t%d\t%d\t%d\t%d\n" | 180 | "Uid:\t%d\t%d\t%d\t%d\n" |
173 | "Gid:\t%d\t%d\t%d\t%d\n", | 181 | "Gid:\t%d\t%d\t%d\t%d\n", |
174 | get_task_state(p), | 182 | get_task_state(p), |
175 | p->tgid, p->pid, | 183 | task_tgid_nr_ns(p, ns), |
176 | pid_alive(p) ? rcu_dereference(p->real_parent)->tgid : 0, | 184 | task_pid_nr_ns(p, ns), |
177 | pid_alive(p) && p->ptrace ? rcu_dereference(p->parent)->pid : 0, | 185 | ppid, tpid, |
178 | p->uid, p->euid, p->suid, p->fsuid, | 186 | p->uid, p->euid, p->suid, p->fsuid, |
179 | p->gid, p->egid, p->sgid, p->fsgid); | 187 | p->gid, p->egid, p->sgid, p->fsgid); |
180 | 188 | ||
@@ -394,6 +402,9 @@ static int do_task_stat(struct task_struct *task, char *buffer, int whole) | |||
394 | unsigned long rsslim = 0; | 402 | unsigned long rsslim = 0; |
395 | char tcomm[sizeof(task->comm)]; | 403 | char tcomm[sizeof(task->comm)]; |
396 | unsigned long flags; | 404 | unsigned long flags; |
405 | struct pid_namespace *ns; | ||
406 | |||
407 | ns = current->nsproxy->pid_ns; | ||
397 | 408 | ||
398 | state = *get_task_state(task); | 409 | state = *get_task_state(task); |
399 | vsize = eip = esp = 0; | 410 | vsize = eip = esp = 0; |
@@ -416,7 +427,7 @@ static int do_task_stat(struct task_struct *task, char *buffer, int whole) | |||
416 | struct signal_struct *sig = task->signal; | 427 | struct signal_struct *sig = task->signal; |
417 | 428 | ||
418 | if (sig->tty) { | 429 | if (sig->tty) { |
419 | tty_pgrp = pid_nr(sig->tty->pgrp); | 430 | tty_pgrp = pid_nr_ns(sig->tty->pgrp, ns); |
420 | tty_nr = new_encode_dev(tty_devnum(sig->tty)); | 431 | tty_nr = new_encode_dev(tty_devnum(sig->tty)); |
421 | } | 432 | } |
422 | 433 | ||
@@ -449,9 +460,9 @@ static int do_task_stat(struct task_struct *task, char *buffer, int whole) | |||
449 | gtime += cputime_add(gtime, sig->gtime); | 460 | gtime += cputime_add(gtime, sig->gtime); |
450 | } | 461 | } |
451 | 462 | ||
452 | sid = task_session_nr(task); | 463 | sid = task_session_nr_ns(task, ns); |
453 | pgid = task_pgrp_nr(task); | 464 | pgid = task_pgrp_nr_ns(task, ns); |
454 | ppid = rcu_dereference(task->real_parent)->tgid; | 465 | ppid = task_ppid_nr_ns(task, ns); |
455 | 466 | ||
456 | unlock_task_sighand(task, &flags); | 467 | unlock_task_sighand(task, &flags); |
457 | } | 468 | } |
@@ -483,7 +494,7 @@ static int do_task_stat(struct task_struct *task, char *buffer, int whole) | |||
483 | res = sprintf(buffer, "%d (%s) %c %d %d %d %d %d %u %lu \ | 494 | res = sprintf(buffer, "%d (%s) %c %d %d %d %d %d %u %lu \ |
484 | %lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \ | 495 | %lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \ |
485 | %lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu %lu %ld\n", | 496 | %lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu %lu %ld\n", |
486 | task->pid, | 497 | task_pid_nr_ns(task, ns), |
487 | tcomm, | 498 | tcomm, |
488 | state, | 499 | state, |
489 | ppid, | 500 | ppid, |
diff --git a/fs/proc/base.c b/fs/proc/base.c index 21510c9aa89c..db7636041c10 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -1937,14 +1937,14 @@ static int proc_self_readlink(struct dentry *dentry, char __user *buffer, | |||
1937 | int buflen) | 1937 | int buflen) |
1938 | { | 1938 | { |
1939 | char tmp[PROC_NUMBUF]; | 1939 | char tmp[PROC_NUMBUF]; |
1940 | sprintf(tmp, "%d", current->tgid); | 1940 | sprintf(tmp, "%d", task_tgid_vnr(current)); |
1941 | return vfs_readlink(dentry,buffer,buflen,tmp); | 1941 | return vfs_readlink(dentry,buffer,buflen,tmp); |
1942 | } | 1942 | } |
1943 | 1943 | ||
1944 | static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd) | 1944 | static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd) |
1945 | { | 1945 | { |
1946 | char tmp[PROC_NUMBUF]; | 1946 | char tmp[PROC_NUMBUF]; |
1947 | sprintf(tmp, "%d", current->tgid); | 1947 | sprintf(tmp, "%d", task_tgid_vnr(current)); |
1948 | return ERR_PTR(vfs_follow_link(nd,tmp)); | 1948 | return ERR_PTR(vfs_follow_link(nd,tmp)); |
1949 | } | 1949 | } |
1950 | 1950 | ||
@@ -2316,6 +2316,7 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct | |||
2316 | struct dentry *result = ERR_PTR(-ENOENT); | 2316 | struct dentry *result = ERR_PTR(-ENOENT); |
2317 | struct task_struct *task; | 2317 | struct task_struct *task; |
2318 | unsigned tgid; | 2318 | unsigned tgid; |
2319 | struct pid_namespace *ns; | ||
2319 | 2320 | ||
2320 | result = proc_base_lookup(dir, dentry); | 2321 | result = proc_base_lookup(dir, dentry); |
2321 | if (!IS_ERR(result) || PTR_ERR(result) != -ENOENT) | 2322 | if (!IS_ERR(result) || PTR_ERR(result) != -ENOENT) |
@@ -2325,8 +2326,9 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct | |||
2325 | if (tgid == ~0U) | 2326 | if (tgid == ~0U) |
2326 | goto out; | 2327 | goto out; |
2327 | 2328 | ||
2329 | ns = dentry->d_sb->s_fs_info; | ||
2328 | rcu_read_lock(); | 2330 | rcu_read_lock(); |
2329 | task = find_task_by_pid(tgid); | 2331 | task = find_task_by_pid_ns(tgid, ns); |
2330 | if (task) | 2332 | if (task) |
2331 | get_task_struct(task); | 2333 | get_task_struct(task); |
2332 | rcu_read_unlock(); | 2334 | rcu_read_unlock(); |
@@ -2343,7 +2345,8 @@ out: | |||
2343 | * Find the first task with tgid >= tgid | 2345 | * Find the first task with tgid >= tgid |
2344 | * | 2346 | * |
2345 | */ | 2347 | */ |
2346 | static struct task_struct *next_tgid(unsigned int tgid) | 2348 | static struct task_struct *next_tgid(unsigned int tgid, |
2349 | struct pid_namespace *ns) | ||
2347 | { | 2350 | { |
2348 | struct task_struct *task; | 2351 | struct task_struct *task; |
2349 | struct pid *pid; | 2352 | struct pid *pid; |
@@ -2351,9 +2354,9 @@ static struct task_struct *next_tgid(unsigned int tgid) | |||
2351 | rcu_read_lock(); | 2354 | rcu_read_lock(); |
2352 | retry: | 2355 | retry: |
2353 | task = NULL; | 2356 | task = NULL; |
2354 | pid = find_ge_pid(tgid, &init_pid_ns); | 2357 | pid = find_ge_pid(tgid, ns); |
2355 | if (pid) { | 2358 | if (pid) { |
2356 | tgid = pid->nr + 1; | 2359 | tgid = pid_nr_ns(pid, ns) + 1; |
2357 | task = pid_task(pid, PIDTYPE_PID); | 2360 | task = pid_task(pid, PIDTYPE_PID); |
2358 | /* What we to know is if the pid we have find is the | 2361 | /* What we to know is if the pid we have find is the |
2359 | * pid of a thread_group_leader. Testing for task | 2362 | * pid of a thread_group_leader. Testing for task |
@@ -2393,6 +2396,7 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
2393 | struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode); | 2396 | struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode); |
2394 | struct task_struct *task; | 2397 | struct task_struct *task; |
2395 | int tgid; | 2398 | int tgid; |
2399 | struct pid_namespace *ns; | ||
2396 | 2400 | ||
2397 | if (!reaper) | 2401 | if (!reaper) |
2398 | goto out_no_task; | 2402 | goto out_no_task; |
@@ -2403,11 +2407,12 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
2403 | goto out; | 2407 | goto out; |
2404 | } | 2408 | } |
2405 | 2409 | ||
2410 | ns = filp->f_dentry->d_sb->s_fs_info; | ||
2406 | tgid = filp->f_pos - TGID_OFFSET; | 2411 | tgid = filp->f_pos - TGID_OFFSET; |
2407 | for (task = next_tgid(tgid); | 2412 | for (task = next_tgid(tgid, ns); |
2408 | task; | 2413 | task; |
2409 | put_task_struct(task), task = next_tgid(tgid + 1)) { | 2414 | put_task_struct(task), task = next_tgid(tgid + 1, ns)) { |
2410 | tgid = task->pid; | 2415 | tgid = task_pid_nr_ns(task, ns); |
2411 | filp->f_pos = tgid + TGID_OFFSET; | 2416 | filp->f_pos = tgid + TGID_OFFSET; |
2412 | if (proc_pid_fill_cache(filp, dirent, filldir, task, tgid) < 0) { | 2417 | if (proc_pid_fill_cache(filp, dirent, filldir, task, tgid) < 0) { |
2413 | put_task_struct(task); | 2418 | put_task_struct(task); |
@@ -2531,6 +2536,7 @@ static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry | |||
2531 | struct task_struct *task; | 2536 | struct task_struct *task; |
2532 | struct task_struct *leader = get_proc_task(dir); | 2537 | struct task_struct *leader = get_proc_task(dir); |
2533 | unsigned tid; | 2538 | unsigned tid; |
2539 | struct pid_namespace *ns; | ||
2534 | 2540 | ||
2535 | if (!leader) | 2541 | if (!leader) |
2536 | goto out_no_task; | 2542 | goto out_no_task; |
@@ -2539,8 +2545,9 @@ static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry | |||
2539 | if (tid == ~0U) | 2545 | if (tid == ~0U) |
2540 | goto out; | 2546 | goto out; |
2541 | 2547 | ||
2548 | ns = dentry->d_sb->s_fs_info; | ||
2542 | rcu_read_lock(); | 2549 | rcu_read_lock(); |
2543 | task = find_task_by_pid(tid); | 2550 | task = find_task_by_pid_ns(tid, ns); |
2544 | if (task) | 2551 | if (task) |
2545 | get_task_struct(task); | 2552 | get_task_struct(task); |
2546 | rcu_read_unlock(); | 2553 | rcu_read_unlock(); |
@@ -2571,14 +2578,14 @@ out_no_task: | |||
2571 | * threads past it. | 2578 | * threads past it. |
2572 | */ | 2579 | */ |
2573 | static struct task_struct *first_tid(struct task_struct *leader, | 2580 | static struct task_struct *first_tid(struct task_struct *leader, |
2574 | int tid, int nr) | 2581 | int tid, int nr, struct pid_namespace *ns) |
2575 | { | 2582 | { |
2576 | struct task_struct *pos; | 2583 | struct task_struct *pos; |
2577 | 2584 | ||
2578 | rcu_read_lock(); | 2585 | rcu_read_lock(); |
2579 | /* Attempt to start with the pid of a thread */ | 2586 | /* Attempt to start with the pid of a thread */ |
2580 | if (tid && (nr > 0)) { | 2587 | if (tid && (nr > 0)) { |
2581 | pos = find_task_by_pid(tid); | 2588 | pos = find_task_by_pid_ns(tid, ns); |
2582 | if (pos && (pos->group_leader == leader)) | 2589 | if (pos && (pos->group_leader == leader)) |
2583 | goto found; | 2590 | goto found; |
2584 | } | 2591 | } |
@@ -2647,6 +2654,7 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi | |||
2647 | ino_t ino; | 2654 | ino_t ino; |
2648 | int tid; | 2655 | int tid; |
2649 | unsigned long pos = filp->f_pos; /* avoiding "long long" filp->f_pos */ | 2656 | unsigned long pos = filp->f_pos; /* avoiding "long long" filp->f_pos */ |
2657 | struct pid_namespace *ns; | ||
2650 | 2658 | ||
2651 | task = get_proc_task(inode); | 2659 | task = get_proc_task(inode); |
2652 | if (!task) | 2660 | if (!task) |
@@ -2680,12 +2688,13 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi | |||
2680 | /* f_version caches the tgid value that the last readdir call couldn't | 2688 | /* f_version caches the tgid value that the last readdir call couldn't |
2681 | * return. lseek aka telldir automagically resets f_version to 0. | 2689 | * return. lseek aka telldir automagically resets f_version to 0. |
2682 | */ | 2690 | */ |
2691 | ns = filp->f_dentry->d_sb->s_fs_info; | ||
2683 | tid = (int)filp->f_version; | 2692 | tid = (int)filp->f_version; |
2684 | filp->f_version = 0; | 2693 | filp->f_version = 0; |
2685 | for (task = first_tid(leader, tid, pos - 2); | 2694 | for (task = first_tid(leader, tid, pos - 2, ns); |
2686 | task; | 2695 | task; |
2687 | task = next_tid(task), pos++) { | 2696 | task = next_tid(task), pos++) { |
2688 | tid = task->pid; | 2697 | tid = task_pid_nr_ns(task, ns); |
2689 | if (proc_task_fill_cache(filp, dirent, filldir, task, tid) < 0) { | 2698 | if (proc_task_fill_cache(filp, dirent, filldir, task, tid) < 0) { |
2690 | /* returning this tgid failed, save it as the first | 2699 | /* returning this tgid failed, save it as the first |
2691 | * pid for the next readir call */ | 2700 | * pid for the next readir call */ |