diff options
Diffstat (limited to 'fs/proc/base.c')
-rw-r--r-- | fs/proc/base.c | 105 |
1 files changed, 49 insertions, 56 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index a891fe4cb43b..01ed610f9b87 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -53,6 +53,7 @@ | |||
53 | #include <linux/time.h> | 53 | #include <linux/time.h> |
54 | #include <linux/proc_fs.h> | 54 | #include <linux/proc_fs.h> |
55 | #include <linux/stat.h> | 55 | #include <linux/stat.h> |
56 | #include <linux/task_io_accounting_ops.h> | ||
56 | #include <linux/init.h> | 57 | #include <linux/init.h> |
57 | #include <linux/capability.h> | 58 | #include <linux/capability.h> |
58 | #include <linux/file.h> | 59 | #include <linux/file.h> |
@@ -69,6 +70,7 @@ | |||
69 | #include <linux/mount.h> | 70 | #include <linux/mount.h> |
70 | #include <linux/security.h> | 71 | #include <linux/security.h> |
71 | #include <linux/ptrace.h> | 72 | #include <linux/ptrace.h> |
73 | #include <linux/tracehook.h> | ||
72 | #include <linux/cgroup.h> | 74 | #include <linux/cgroup.h> |
73 | #include <linux/cpuset.h> | 75 | #include <linux/cpuset.h> |
74 | #include <linux/audit.h> | 76 | #include <linux/audit.h> |
@@ -231,10 +233,14 @@ static int check_mem_permission(struct task_struct *task) | |||
231 | * If current is actively ptrace'ing, and would also be | 233 | * If current is actively ptrace'ing, and would also be |
232 | * permitted to freshly attach with ptrace now, permit it. | 234 | * permitted to freshly attach with ptrace now, permit it. |
233 | */ | 235 | */ |
234 | if (task->parent == current && (task->ptrace & PT_PTRACED) && | 236 | if (task_is_stopped_or_traced(task)) { |
235 | task_is_stopped_or_traced(task) && | 237 | int match; |
236 | ptrace_may_access(task, PTRACE_MODE_ATTACH)) | 238 | rcu_read_lock(); |
237 | return 0; | 239 | match = (tracehook_tracer_task(task) == current); |
240 | rcu_read_unlock(); | ||
241 | if (match && ptrace_may_access(task, PTRACE_MODE_ATTACH)) | ||
242 | return 0; | ||
243 | } | ||
238 | 244 | ||
239 | /* | 245 | /* |
240 | * Noone else is allowed. | 246 | * Noone else is allowed. |
@@ -504,6 +510,26 @@ static int proc_pid_limits(struct task_struct *task, char *buffer) | |||
504 | return count; | 510 | return count; |
505 | } | 511 | } |
506 | 512 | ||
513 | #ifdef CONFIG_HAVE_ARCH_TRACEHOOK | ||
514 | static int proc_pid_syscall(struct task_struct *task, char *buffer) | ||
515 | { | ||
516 | long nr; | ||
517 | unsigned long args[6], sp, pc; | ||
518 | |||
519 | if (task_current_syscall(task, &nr, args, 6, &sp, &pc)) | ||
520 | return sprintf(buffer, "running\n"); | ||
521 | |||
522 | if (nr < 0) | ||
523 | return sprintf(buffer, "%ld 0x%lx 0x%lx\n", nr, sp, pc); | ||
524 | |||
525 | return sprintf(buffer, | ||
526 | "%ld 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n", | ||
527 | nr, | ||
528 | args[0], args[1], args[2], args[3], args[4], args[5], | ||
529 | sp, pc); | ||
530 | } | ||
531 | #endif /* CONFIG_HAVE_ARCH_TRACEHOOK */ | ||
532 | |||
507 | /************************************************************************/ | 533 | /************************************************************************/ |
508 | /* Here the fs part begins */ | 534 | /* Here the fs part begins */ |
509 | /************************************************************************/ | 535 | /************************************************************************/ |
@@ -1834,8 +1860,7 @@ static const struct file_operations proc_fd_operations = { | |||
1834 | * /proc/pid/fd needs a special permission handler so that a process can still | 1860 | * /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(). | 1861 | * access /proc/self/fd after it has executed a setuid(). |
1836 | */ | 1862 | */ |
1837 | static int proc_fd_permission(struct inode *inode, int mask, | 1863 | static int proc_fd_permission(struct inode *inode, int mask) |
1838 | struct nameidata *nd) | ||
1839 | { | 1864 | { |
1840 | int rv; | 1865 | int rv; |
1841 | 1866 | ||
@@ -2378,53 +2403,18 @@ static int proc_base_fill_cache(struct file *filp, void *dirent, | |||
2378 | #ifdef CONFIG_TASK_IO_ACCOUNTING | 2403 | #ifdef CONFIG_TASK_IO_ACCOUNTING |
2379 | static int do_io_accounting(struct task_struct *task, char *buffer, int whole) | 2404 | static int do_io_accounting(struct task_struct *task, char *buffer, int whole) |
2380 | { | 2405 | { |
2381 | u64 rchar, wchar, syscr, syscw; | 2406 | struct task_io_accounting acct = task->ioac; |
2382 | struct task_io_accounting ioac; | 2407 | unsigned long flags; |
2383 | |||
2384 | if (!whole) { | ||
2385 | rchar = task->rchar; | ||
2386 | wchar = task->wchar; | ||
2387 | syscr = task->syscr; | ||
2388 | syscw = task->syscw; | ||
2389 | memcpy(&ioac, &task->ioac, sizeof(ioac)); | ||
2390 | } else { | ||
2391 | unsigned long flags; | ||
2392 | struct task_struct *t = task; | ||
2393 | rchar = wchar = syscr = syscw = 0; | ||
2394 | memset(&ioac, 0, sizeof(ioac)); | ||
2395 | |||
2396 | rcu_read_lock(); | ||
2397 | do { | ||
2398 | rchar += t->rchar; | ||
2399 | wchar += t->wchar; | ||
2400 | syscr += t->syscr; | ||
2401 | syscw += t->syscw; | ||
2402 | |||
2403 | ioac.read_bytes += t->ioac.read_bytes; | ||
2404 | ioac.write_bytes += t->ioac.write_bytes; | ||
2405 | ioac.cancelled_write_bytes += | ||
2406 | t->ioac.cancelled_write_bytes; | ||
2407 | t = next_thread(t); | ||
2408 | } while (t != task); | ||
2409 | rcu_read_unlock(); | ||
2410 | |||
2411 | if (lock_task_sighand(task, &flags)) { | ||
2412 | struct signal_struct *sig = task->signal; | ||
2413 | 2408 | ||
2414 | rchar += sig->rchar; | 2409 | if (whole && lock_task_sighand(task, &flags)) { |
2415 | wchar += sig->wchar; | 2410 | struct task_struct *t = task; |
2416 | syscr += sig->syscr; | ||
2417 | syscw += sig->syscw; | ||
2418 | 2411 | ||
2419 | ioac.read_bytes += sig->ioac.read_bytes; | 2412 | task_io_accounting_add(&acct, &task->signal->ioac); |
2420 | ioac.write_bytes += sig->ioac.write_bytes; | 2413 | while_each_thread(task, t) |
2421 | ioac.cancelled_write_bytes += | 2414 | task_io_accounting_add(&acct, &t->ioac); |
2422 | sig->ioac.cancelled_write_bytes; | ||
2423 | 2415 | ||
2424 | unlock_task_sighand(task, &flags); | 2416 | unlock_task_sighand(task, &flags); |
2425 | } | ||
2426 | } | 2417 | } |
2427 | |||
2428 | return sprintf(buffer, | 2418 | return sprintf(buffer, |
2429 | "rchar: %llu\n" | 2419 | "rchar: %llu\n" |
2430 | "wchar: %llu\n" | 2420 | "wchar: %llu\n" |
@@ -2433,13 +2423,10 @@ static int do_io_accounting(struct task_struct *task, char *buffer, int whole) | |||
2433 | "read_bytes: %llu\n" | 2423 | "read_bytes: %llu\n" |
2434 | "write_bytes: %llu\n" | 2424 | "write_bytes: %llu\n" |
2435 | "cancelled_write_bytes: %llu\n", | 2425 | "cancelled_write_bytes: %llu\n", |
2436 | (unsigned long long)rchar, | 2426 | acct.rchar, acct.wchar, |
2437 | (unsigned long long)wchar, | 2427 | acct.syscr, acct.syscw, |
2438 | (unsigned long long)syscr, | 2428 | acct.read_bytes, acct.write_bytes, |
2439 | (unsigned long long)syscw, | 2429 | acct.cancelled_write_bytes); |
2440 | (unsigned long long)ioac.read_bytes, | ||
2441 | (unsigned long long)ioac.write_bytes, | ||
2442 | (unsigned long long)ioac.cancelled_write_bytes); | ||
2443 | } | 2430 | } |
2444 | 2431 | ||
2445 | static int proc_tid_io_accounting(struct task_struct *task, char *buffer) | 2432 | static int proc_tid_io_accounting(struct task_struct *task, char *buffer) |
@@ -2473,6 +2460,9 @@ static const struct pid_entry tgid_base_stuff[] = { | |||
2473 | #ifdef CONFIG_SCHED_DEBUG | 2460 | #ifdef CONFIG_SCHED_DEBUG |
2474 | REG("sched", S_IRUGO|S_IWUSR, pid_sched), | 2461 | REG("sched", S_IRUGO|S_IWUSR, pid_sched), |
2475 | #endif | 2462 | #endif |
2463 | #ifdef CONFIG_HAVE_ARCH_TRACEHOOK | ||
2464 | INF("syscall", S_IRUSR, pid_syscall), | ||
2465 | #endif | ||
2476 | INF("cmdline", S_IRUGO, pid_cmdline), | 2466 | INF("cmdline", S_IRUGO, pid_cmdline), |
2477 | ONE("stat", S_IRUGO, tgid_stat), | 2467 | ONE("stat", S_IRUGO, tgid_stat), |
2478 | ONE("statm", S_IRUGO, pid_statm), | 2468 | ONE("statm", S_IRUGO, pid_statm), |
@@ -2805,6 +2795,9 @@ static const struct pid_entry tid_base_stuff[] = { | |||
2805 | #ifdef CONFIG_SCHED_DEBUG | 2795 | #ifdef CONFIG_SCHED_DEBUG |
2806 | REG("sched", S_IRUGO|S_IWUSR, pid_sched), | 2796 | REG("sched", S_IRUGO|S_IWUSR, pid_sched), |
2807 | #endif | 2797 | #endif |
2798 | #ifdef CONFIG_HAVE_ARCH_TRACEHOOK | ||
2799 | INF("syscall", S_IRUSR, pid_syscall), | ||
2800 | #endif | ||
2808 | INF("cmdline", S_IRUGO, pid_cmdline), | 2801 | INF("cmdline", S_IRUGO, pid_cmdline), |
2809 | ONE("stat", S_IRUGO, tid_stat), | 2802 | ONE("stat", S_IRUGO, tid_stat), |
2810 | ONE("statm", S_IRUGO, pid_statm), | 2803 | ONE("statm", S_IRUGO, pid_statm), |