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.c92
1 files changed, 72 insertions, 20 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 58c3e6a8e15e..a28840b11b89 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
514static 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 */
1837static int proc_fd_permission(struct inode *inode, int mask, 1863static int proc_fd_permission(struct inode *inode, int mask)
1838 struct nameidata *nd)
1839{ 1864{
1840 int rv; 1865 int rv;
1841 1866
@@ -2376,29 +2401,47 @@ static int proc_base_fill_cache(struct file *filp, void *dirent,
2376} 2401}
2377 2402
2378#ifdef CONFIG_TASK_IO_ACCOUNTING 2403#ifdef CONFIG_TASK_IO_ACCOUNTING
2379static int proc_pid_io_accounting(struct task_struct *task, char *buffer) 2404static int do_io_accounting(struct task_struct *task, char *buffer, int whole)
2380{ 2405{
2406 struct task_io_accounting acct = task->ioac;
2407 unsigned long flags;
2408
2409 if (whole && lock_task_sighand(task, &flags)) {
2410 struct task_struct *t = task;
2411
2412 task_io_accounting_add(&acct, &task->signal->ioac);
2413 while_each_thread(task, t)
2414 task_io_accounting_add(&acct, &t->ioac);
2415
2416 unlock_task_sighand(task, &flags);
2417 }
2381 return sprintf(buffer, 2418 return sprintf(buffer,
2382#ifdef CONFIG_TASK_XACCT
2383 "rchar: %llu\n" 2419 "rchar: %llu\n"
2384 "wchar: %llu\n" 2420 "wchar: %llu\n"
2385 "syscr: %llu\n" 2421 "syscr: %llu\n"
2386 "syscw: %llu\n" 2422 "syscw: %llu\n"
2387#endif
2388 "read_bytes: %llu\n" 2423 "read_bytes: %llu\n"
2389 "write_bytes: %llu\n" 2424 "write_bytes: %llu\n"
2390 "cancelled_write_bytes: %llu\n", 2425 "cancelled_write_bytes: %llu\n",
2391#ifdef CONFIG_TASK_XACCT 2426 (unsigned long long)acct.rchar,
2392 (unsigned long long)task->rchar, 2427 (unsigned long long)acct.wchar,
2393 (unsigned long long)task->wchar, 2428 (unsigned long long)acct.syscr,
2394 (unsigned long long)task->syscr, 2429 (unsigned long long)acct.syscw,
2395 (unsigned long long)task->syscw, 2430 (unsigned long long)acct.read_bytes,
2396#endif 2431 (unsigned long long)acct.write_bytes,
2397 (unsigned long long)task->ioac.read_bytes, 2432 (unsigned long long)acct.cancelled_write_bytes);
2398 (unsigned long long)task->ioac.write_bytes, 2433}
2399 (unsigned long long)task->ioac.cancelled_write_bytes); 2434
2435static int proc_tid_io_accounting(struct task_struct *task, char *buffer)
2436{
2437 return do_io_accounting(task, buffer, 0);
2400} 2438}
2401#endif 2439
2440static int proc_tgid_io_accounting(struct task_struct *task, char *buffer)
2441{
2442 return do_io_accounting(task, buffer, 1);
2443}
2444#endif /* CONFIG_TASK_IO_ACCOUNTING */
2402 2445
2403/* 2446/*
2404 * Thread groups 2447 * Thread groups
@@ -2420,6 +2463,9 @@ static const struct pid_entry tgid_base_stuff[] = {
2420#ifdef CONFIG_SCHED_DEBUG 2463#ifdef CONFIG_SCHED_DEBUG
2421 REG("sched", S_IRUGO|S_IWUSR, pid_sched), 2464 REG("sched", S_IRUGO|S_IWUSR, pid_sched),
2422#endif 2465#endif
2466#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
2467 INF("syscall", S_IRUSR, pid_syscall),
2468#endif
2423 INF("cmdline", S_IRUGO, pid_cmdline), 2469 INF("cmdline", S_IRUGO, pid_cmdline),
2424 ONE("stat", S_IRUGO, tgid_stat), 2470 ONE("stat", S_IRUGO, tgid_stat),
2425 ONE("statm", S_IRUGO, pid_statm), 2471 ONE("statm", S_IRUGO, pid_statm),
@@ -2470,7 +2516,7 @@ static const struct pid_entry tgid_base_stuff[] = {
2470 REG("coredump_filter", S_IRUGO|S_IWUSR, coredump_filter), 2516 REG("coredump_filter", S_IRUGO|S_IWUSR, coredump_filter),
2471#endif 2517#endif
2472#ifdef CONFIG_TASK_IO_ACCOUNTING 2518#ifdef CONFIG_TASK_IO_ACCOUNTING
2473 INF("io", S_IRUGO, pid_io_accounting), 2519 INF("io", S_IRUGO, tgid_io_accounting),
2474#endif 2520#endif
2475}; 2521};
2476 2522
@@ -2752,6 +2798,9 @@ static const struct pid_entry tid_base_stuff[] = {
2752#ifdef CONFIG_SCHED_DEBUG 2798#ifdef CONFIG_SCHED_DEBUG
2753 REG("sched", S_IRUGO|S_IWUSR, pid_sched), 2799 REG("sched", S_IRUGO|S_IWUSR, pid_sched),
2754#endif 2800#endif
2801#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
2802 INF("syscall", S_IRUSR, pid_syscall),
2803#endif
2755 INF("cmdline", S_IRUGO, pid_cmdline), 2804 INF("cmdline", S_IRUGO, pid_cmdline),
2756 ONE("stat", S_IRUGO, tid_stat), 2805 ONE("stat", S_IRUGO, tid_stat),
2757 ONE("statm", S_IRUGO, pid_statm), 2806 ONE("statm", S_IRUGO, pid_statm),
@@ -2797,6 +2846,9 @@ static const struct pid_entry tid_base_stuff[] = {
2797#ifdef CONFIG_FAULT_INJECTION 2846#ifdef CONFIG_FAULT_INJECTION
2798 REG("make-it-fail", S_IRUGO|S_IWUSR, fault_inject), 2847 REG("make-it-fail", S_IRUGO|S_IWUSR, fault_inject),
2799#endif 2848#endif
2849#ifdef CONFIG_TASK_IO_ACCOUNTING
2850 INF("io", S_IRUGO, tid_io_accounting),
2851#endif
2800}; 2852};
2801 2853
2802static int proc_tid_base_readdir(struct file * filp, 2854static int proc_tid_base_readdir(struct file * filp,