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.c105
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
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
@@ -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
2379static int do_io_accounting(struct task_struct *task, char *buffer, int whole) 2404static 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
2445static int proc_tid_io_accounting(struct task_struct *task, char *buffer) 2432static 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),