diff options
author | Haavard Skinnemoen <haavard.skinnemoen@atmel.com> | 2008-07-27 07:54:08 -0400 |
---|---|---|
committer | Haavard Skinnemoen <haavard.skinnemoen@atmel.com> | 2008-07-27 07:54:08 -0400 |
commit | eda3d8f5604860aae1bb9996bb5efc4213778369 (patch) | |
tree | 9d3887d2665bcc5f5abf200758794545c7b2c69b /fs/proc/base.c | |
parent | 87a9f704658a40940e740b1d73d861667e9164d3 (diff) | |
parent | 8be1a6d6c77ab4532e4476fdb8177030ef48b52c (diff) |
Merge commit 'upstream/master'
Diffstat (limited to 'fs/proc/base.c')
-rw-r--r-- | fs/proc/base.c | 116 |
1 files changed, 95 insertions, 21 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index 58c3e6a8e15e..e74308bdabd3 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -69,6 +69,7 @@ | |||
69 | #include <linux/mount.h> | 69 | #include <linux/mount.h> |
70 | #include <linux/security.h> | 70 | #include <linux/security.h> |
71 | #include <linux/ptrace.h> | 71 | #include <linux/ptrace.h> |
72 | #include <linux/tracehook.h> | ||
72 | #include <linux/cgroup.h> | 73 | #include <linux/cgroup.h> |
73 | #include <linux/cpuset.h> | 74 | #include <linux/cpuset.h> |
74 | #include <linux/audit.h> | 75 | #include <linux/audit.h> |
@@ -231,10 +232,14 @@ static int check_mem_permission(struct task_struct *task) | |||
231 | * If current is actively ptrace'ing, and would also be | 232 | * If current is actively ptrace'ing, and would also be |
232 | * permitted to freshly attach with ptrace now, permit it. | 233 | * permitted to freshly attach with ptrace now, permit it. |
233 | */ | 234 | */ |
234 | if (task->parent == current && (task->ptrace & PT_PTRACED) && | 235 | if (task_is_stopped_or_traced(task)) { |
235 | task_is_stopped_or_traced(task) && | 236 | int match; |
236 | ptrace_may_access(task, PTRACE_MODE_ATTACH)) | 237 | rcu_read_lock(); |
237 | return 0; | 238 | match = (tracehook_tracer_task(task) == current); |
239 | rcu_read_unlock(); | ||
240 | if (match && ptrace_may_access(task, PTRACE_MODE_ATTACH)) | ||
241 | return 0; | ||
242 | } | ||
238 | 243 | ||
239 | /* | 244 | /* |
240 | * Noone else is allowed. | 245 | * Noone else is allowed. |
@@ -504,6 +509,26 @@ static int proc_pid_limits(struct task_struct *task, char *buffer) | |||
504 | return count; | 509 | return count; |
505 | } | 510 | } |
506 | 511 | ||
512 | #ifdef CONFIG_HAVE_ARCH_TRACEHOOK | ||
513 | static int proc_pid_syscall(struct task_struct *task, char *buffer) | ||
514 | { | ||
515 | long nr; | ||
516 | unsigned long args[6], sp, pc; | ||
517 | |||
518 | if (task_current_syscall(task, &nr, args, 6, &sp, &pc)) | ||
519 | return sprintf(buffer, "running\n"); | ||
520 | |||
521 | if (nr < 0) | ||
522 | return sprintf(buffer, "%ld 0x%lx 0x%lx\n", nr, sp, pc); | ||
523 | |||
524 | return sprintf(buffer, | ||
525 | "%ld 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n", | ||
526 | nr, | ||
527 | args[0], args[1], args[2], args[3], args[4], args[5], | ||
528 | sp, pc); | ||
529 | } | ||
530 | #endif /* CONFIG_HAVE_ARCH_TRACEHOOK */ | ||
531 | |||
507 | /************************************************************************/ | 532 | /************************************************************************/ |
508 | /* Here the fs part begins */ | 533 | /* Here the fs part begins */ |
509 | /************************************************************************/ | 534 | /************************************************************************/ |
@@ -1834,8 +1859,7 @@ static const struct file_operations proc_fd_operations = { | |||
1834 | * /proc/pid/fd needs a special permission handler so that a process can still | 1859 | * /proc/pid/fd needs a special permission handler so that a process can still |
1835 | * access /proc/self/fd after it has executed a setuid(). | 1860 | * access /proc/self/fd after it has executed a setuid(). |
1836 | */ | 1861 | */ |
1837 | static int proc_fd_permission(struct inode *inode, int mask, | 1862 | static int proc_fd_permission(struct inode *inode, int mask) |
1838 | struct nameidata *nd) | ||
1839 | { | 1863 | { |
1840 | int rv; | 1864 | int rv; |
1841 | 1865 | ||
@@ -2376,29 +2400,70 @@ static int proc_base_fill_cache(struct file *filp, void *dirent, | |||
2376 | } | 2400 | } |
2377 | 2401 | ||
2378 | #ifdef CONFIG_TASK_IO_ACCOUNTING | 2402 | #ifdef CONFIG_TASK_IO_ACCOUNTING |
2379 | static int proc_pid_io_accounting(struct task_struct *task, char *buffer) | 2403 | static int do_io_accounting(struct task_struct *task, char *buffer, int whole) |
2380 | { | 2404 | { |
2405 | u64 rchar, wchar, syscr, syscw; | ||
2406 | struct task_io_accounting ioac; | ||
2407 | |||
2408 | rchar = task->rchar; | ||
2409 | wchar = task->wchar; | ||
2410 | syscr = task->syscr; | ||
2411 | syscw = task->syscw; | ||
2412 | memcpy(&ioac, &task->ioac, sizeof(ioac)); | ||
2413 | |||
2414 | if (whole) { | ||
2415 | unsigned long flags; | ||
2416 | |||
2417 | if (lock_task_sighand(task, &flags)) { | ||
2418 | struct signal_struct *sig = task->signal; | ||
2419 | struct task_struct *t = task; | ||
2420 | |||
2421 | rchar += sig->rchar; | ||
2422 | wchar += sig->wchar; | ||
2423 | syscr += sig->syscr; | ||
2424 | syscw += sig->syscw; | ||
2425 | |||
2426 | ioac.read_bytes += sig->ioac.read_bytes; | ||
2427 | ioac.write_bytes += sig->ioac.write_bytes; | ||
2428 | ioac.cancelled_write_bytes += | ||
2429 | sig->ioac.cancelled_write_bytes; | ||
2430 | while_each_thread(task, t) { | ||
2431 | rchar += t->rchar; | ||
2432 | wchar += t->wchar; | ||
2433 | syscr += t->syscr; | ||
2434 | syscw += t->syscw; | ||
2435 | |||
2436 | ioac.read_bytes += t->ioac.read_bytes; | ||
2437 | ioac.write_bytes += t->ioac.write_bytes; | ||
2438 | ioac.cancelled_write_bytes += | ||
2439 | t->ioac.cancelled_write_bytes; | ||
2440 | } | ||
2441 | unlock_task_sighand(task, &flags); | ||
2442 | } | ||
2443 | } | ||
2381 | return sprintf(buffer, | 2444 | return sprintf(buffer, |
2382 | #ifdef CONFIG_TASK_XACCT | ||
2383 | "rchar: %llu\n" | 2445 | "rchar: %llu\n" |
2384 | "wchar: %llu\n" | 2446 | "wchar: %llu\n" |
2385 | "syscr: %llu\n" | 2447 | "syscr: %llu\n" |
2386 | "syscw: %llu\n" | 2448 | "syscw: %llu\n" |
2387 | #endif | ||
2388 | "read_bytes: %llu\n" | 2449 | "read_bytes: %llu\n" |
2389 | "write_bytes: %llu\n" | 2450 | "write_bytes: %llu\n" |
2390 | "cancelled_write_bytes: %llu\n", | 2451 | "cancelled_write_bytes: %llu\n", |
2391 | #ifdef CONFIG_TASK_XACCT | 2452 | rchar, wchar, syscr, syscw, |
2392 | (unsigned long long)task->rchar, | 2453 | ioac.read_bytes, ioac.write_bytes, |
2393 | (unsigned long long)task->wchar, | 2454 | ioac.cancelled_write_bytes); |
2394 | (unsigned long long)task->syscr, | 2455 | } |
2395 | (unsigned long long)task->syscw, | 2456 | |
2396 | #endif | 2457 | static int proc_tid_io_accounting(struct task_struct *task, char *buffer) |
2397 | (unsigned long long)task->ioac.read_bytes, | 2458 | { |
2398 | (unsigned long long)task->ioac.write_bytes, | 2459 | return do_io_accounting(task, buffer, 0); |
2399 | (unsigned long long)task->ioac.cancelled_write_bytes); | ||
2400 | } | 2460 | } |
2401 | #endif | 2461 | |
2462 | static int proc_tgid_io_accounting(struct task_struct *task, char *buffer) | ||
2463 | { | ||
2464 | return do_io_accounting(task, buffer, 1); | ||
2465 | } | ||
2466 | #endif /* CONFIG_TASK_IO_ACCOUNTING */ | ||
2402 | 2467 | ||
2403 | /* | 2468 | /* |
2404 | * Thread groups | 2469 | * Thread groups |
@@ -2420,6 +2485,9 @@ static const struct pid_entry tgid_base_stuff[] = { | |||
2420 | #ifdef CONFIG_SCHED_DEBUG | 2485 | #ifdef CONFIG_SCHED_DEBUG |
2421 | REG("sched", S_IRUGO|S_IWUSR, pid_sched), | 2486 | REG("sched", S_IRUGO|S_IWUSR, pid_sched), |
2422 | #endif | 2487 | #endif |
2488 | #ifdef CONFIG_HAVE_ARCH_TRACEHOOK | ||
2489 | INF("syscall", S_IRUSR, pid_syscall), | ||
2490 | #endif | ||
2423 | INF("cmdline", S_IRUGO, pid_cmdline), | 2491 | INF("cmdline", S_IRUGO, pid_cmdline), |
2424 | ONE("stat", S_IRUGO, tgid_stat), | 2492 | ONE("stat", S_IRUGO, tgid_stat), |
2425 | ONE("statm", S_IRUGO, pid_statm), | 2493 | ONE("statm", S_IRUGO, pid_statm), |
@@ -2470,7 +2538,7 @@ static const struct pid_entry tgid_base_stuff[] = { | |||
2470 | REG("coredump_filter", S_IRUGO|S_IWUSR, coredump_filter), | 2538 | REG("coredump_filter", S_IRUGO|S_IWUSR, coredump_filter), |
2471 | #endif | 2539 | #endif |
2472 | #ifdef CONFIG_TASK_IO_ACCOUNTING | 2540 | #ifdef CONFIG_TASK_IO_ACCOUNTING |
2473 | INF("io", S_IRUGO, pid_io_accounting), | 2541 | INF("io", S_IRUGO, tgid_io_accounting), |
2474 | #endif | 2542 | #endif |
2475 | }; | 2543 | }; |
2476 | 2544 | ||
@@ -2752,6 +2820,9 @@ static const struct pid_entry tid_base_stuff[] = { | |||
2752 | #ifdef CONFIG_SCHED_DEBUG | 2820 | #ifdef CONFIG_SCHED_DEBUG |
2753 | REG("sched", S_IRUGO|S_IWUSR, pid_sched), | 2821 | REG("sched", S_IRUGO|S_IWUSR, pid_sched), |
2754 | #endif | 2822 | #endif |
2823 | #ifdef CONFIG_HAVE_ARCH_TRACEHOOK | ||
2824 | INF("syscall", S_IRUSR, pid_syscall), | ||
2825 | #endif | ||
2755 | INF("cmdline", S_IRUGO, pid_cmdline), | 2826 | INF("cmdline", S_IRUGO, pid_cmdline), |
2756 | ONE("stat", S_IRUGO, tid_stat), | 2827 | ONE("stat", S_IRUGO, tid_stat), |
2757 | ONE("statm", S_IRUGO, pid_statm), | 2828 | ONE("statm", S_IRUGO, pid_statm), |
@@ -2797,6 +2868,9 @@ static const struct pid_entry tid_base_stuff[] = { | |||
2797 | #ifdef CONFIG_FAULT_INJECTION | 2868 | #ifdef CONFIG_FAULT_INJECTION |
2798 | REG("make-it-fail", S_IRUGO|S_IWUSR, fault_inject), | 2869 | REG("make-it-fail", S_IRUGO|S_IWUSR, fault_inject), |
2799 | #endif | 2870 | #endif |
2871 | #ifdef CONFIG_TASK_IO_ACCOUNTING | ||
2872 | INF("io", S_IRUGO, tid_io_accounting), | ||
2873 | #endif | ||
2800 | }; | 2874 | }; |
2801 | 2875 | ||
2802 | static int proc_tid_base_readdir(struct file * filp, | 2876 | static int proc_tid_base_readdir(struct file * filp, |