LCOV - code coverage report
Current view: top level - fs/proc - array.c (source / functions) Hit Total Coverage
Test: landlock.info Lines: 324 402 80.6 %
Date: 2021-04-22 12:43:58 Functions: 15 17 88.2 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : /*
       3             :  *  linux/fs/proc/array.c
       4             :  *
       5             :  *  Copyright (C) 1992  by Linus Torvalds
       6             :  *  based on ideas by Darren Senn
       7             :  *
       8             :  * Fixes:
       9             :  * Michael. K. Johnson: stat,statm extensions.
      10             :  *                      <johnsonm@stolaf.edu>
      11             :  *
      12             :  * Pauline Middelink :  Made cmdline,envline only break at '\0's, to
      13             :  *                      make sure SET_PROCTITLE works. Also removed
      14             :  *                      bad '!' which forced address recalculation for
      15             :  *                      EVERY character on the current page.
      16             :  *                      <middelin@polyware.iaf.nl>
      17             :  *
      18             :  * Danny ter Haar    :  added cpuinfo
      19             :  *                      <dth@cistron.nl>
      20             :  *
      21             :  * Alessandro Rubini :  profile extension.
      22             :  *                      <rubini@ipvvis.unipv.it>
      23             :  *
      24             :  * Jeff Tranter      :  added BogoMips field to cpuinfo
      25             :  *                      <Jeff_Tranter@Mitel.COM>
      26             :  *
      27             :  * Bruno Haible      :  remove 4K limit for the maps file
      28             :  *                      <haible@ma2s2.mathematik.uni-karlsruhe.de>
      29             :  *
      30             :  * Yves Arrouye      :  remove removal of trailing spaces in get_array.
      31             :  *                      <Yves.Arrouye@marin.fdn.fr>
      32             :  *
      33             :  * Jerome Forissier  :  added per-CPU time information to /proc/stat
      34             :  *                      and /proc/<pid>/cpu extension
      35             :  *                      <forissier@isia.cma.fr>
      36             :  *                      - Incorporation and non-SMP safe operation
      37             :  *                      of forissier patch in 2.1.78 by
      38             :  *                      Hans Marcus <crowbar@concepts.nl>
      39             :  *
      40             :  * aeb@cwi.nl        :  /proc/partitions
      41             :  *
      42             :  *
      43             :  * Alan Cox          :  security fixes.
      44             :  *                      <alan@lxorguk.ukuu.org.uk>
      45             :  *
      46             :  * Al Viro           :  safe handling of mm_struct
      47             :  *
      48             :  * Gerhard Wichert   :  added BIGMEM support
      49             :  * Siemens AG           <Gerhard.Wichert@pdb.siemens.de>
      50             :  *
      51             :  * Al Viro & Jeff Garzik :  moved most of the thing into base.c and
      52             :  *                       :  proc_misc.c. The rest may eventually go into
      53             :  *                       :  base.c too.
      54             :  */
      55             : 
      56             : #include <linux/types.h>
      57             : #include <linux/errno.h>
      58             : #include <linux/time.h>
      59             : #include <linux/time_namespace.h>
      60             : #include <linux/kernel.h>
      61             : #include <linux/kernel_stat.h>
      62             : #include <linux/tty.h>
      63             : #include <linux/string.h>
      64             : #include <linux/mman.h>
      65             : #include <linux/sched/mm.h>
      66             : #include <linux/sched/numa_balancing.h>
      67             : #include <linux/sched/task_stack.h>
      68             : #include <linux/sched/task.h>
      69             : #include <linux/sched/cputime.h>
      70             : #include <linux/proc_fs.h>
      71             : #include <linux/ioport.h>
      72             : #include <linux/uaccess.h>
      73             : #include <linux/io.h>
      74             : #include <linux/mm.h>
      75             : #include <linux/hugetlb.h>
      76             : #include <linux/pagemap.h>
      77             : #include <linux/swap.h>
      78             : #include <linux/smp.h>
      79             : #include <linux/signal.h>
      80             : #include <linux/highmem.h>
      81             : #include <linux/file.h>
      82             : #include <linux/fdtable.h>
      83             : #include <linux/times.h>
      84             : #include <linux/cpuset.h>
      85             : #include <linux/rcupdate.h>
      86             : #include <linux/delayacct.h>
      87             : #include <linux/seq_file.h>
      88             : #include <linux/pid_namespace.h>
      89             : #include <linux/prctl.h>
      90             : #include <linux/ptrace.h>
      91             : #include <linux/tracehook.h>
      92             : #include <linux/string_helpers.h>
      93             : #include <linux/user_namespace.h>
      94             : #include <linux/fs_struct.h>
      95             : 
      96             : #include <asm/processor.h>
      97             : #include "internal.h"
      98             : 
      99         305 : void proc_task_name(struct seq_file *m, struct task_struct *p, bool escape)
     100             : {
     101         305 :         char *buf;
     102         305 :         size_t size;
     103         305 :         char tcomm[64];
     104         305 :         int ret;
     105             : 
     106         305 :         if (p->flags & PF_WQ_WORKER)
     107          24 :                 wq_worker_comm(tcomm, sizeof(tcomm), p);
     108             :         else
     109         281 :                 __get_task_comm(tcomm, sizeof(tcomm), p);
     110             : 
     111         305 :         size = seq_get_buf(m, &buf);
     112         305 :         if (escape) {
     113          56 :                 ret = string_escape_str(tcomm, buf, size,
     114             :                                         ESCAPE_SPACE | ESCAPE_SPECIAL, "\n\\");
     115          56 :                 if (ret >= size)
     116           0 :                         ret = -1;
     117             :         } else {
     118         249 :                 ret = strscpy(buf, tcomm, size);
     119             :         }
     120             : 
     121         305 :         seq_commit(m, ret);
     122         305 : }
     123             : 
     124             : /*
     125             :  * The task state array is a strange "bitmap" of
     126             :  * reasons to sleep. Thus "running" is zero, and
     127             :  * you can test for combinations of others with
     128             :  * simple bit tests.
     129             :  */
     130             : static const char * const task_state_array[] = {
     131             : 
     132             :         /* states in TASK_REPORT: */
     133             :         "R (running)",                /* 0x00 */
     134             :         "S (sleeping)",               /* 0x01 */
     135             :         "D (disk sleep)",     /* 0x02 */
     136             :         "T (stopped)",                /* 0x04 */
     137             :         "t (tracing stop)",   /* 0x08 */
     138             :         "X (dead)",           /* 0x10 */
     139             :         "Z (zombie)",         /* 0x20 */
     140             :         "P (parked)",         /* 0x40 */
     141             : 
     142             :         /* states beyond TASK_REPORT: */
     143             :         "I (idle)",           /* 0x80 */
     144             : };
     145             : 
     146         197 : static inline const char *get_task_state(struct task_struct *tsk)
     147             : {
     148         197 :         BUILD_BUG_ON(1 + ilog2(TASK_REPORT_MAX) != ARRAY_SIZE(task_state_array));
     149         394 :         return task_state_array[task_state_index(tsk)];
     150             : }
     151             : 
     152          56 : static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
     153             :                                 struct pid *pid, struct task_struct *p)
     154             : {
     155          56 :         struct user_namespace *user_ns = seq_user_ns(m);
     156          56 :         struct group_info *group_info;
     157          56 :         int g, umask = -1;
     158          56 :         struct task_struct *tracer;
     159          56 :         const struct cred *cred;
     160          56 :         pid_t ppid, tpid = 0, tgid, ngid;
     161          56 :         unsigned int max_fds = 0;
     162             : 
     163          56 :         rcu_read_lock();
     164          56 :         ppid = pid_alive(p) ?
     165          56 :                 task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0;
     166             : 
     167          56 :         tracer = ptrace_parent(p);
     168          56 :         if (tracer)
     169           0 :                 tpid = task_pid_nr_ns(tracer, ns);
     170             : 
     171          56 :         tgid = task_tgid_nr_ns(p, ns);
     172          56 :         ngid = task_numa_group_id(p);
     173          56 :         cred = get_task_cred(p);
     174             : 
     175          56 :         task_lock(p);
     176          56 :         if (p->fs)
     177          55 :                 umask = p->fs->umask;
     178          56 :         if (p->files)
     179          55 :                 max_fds = files_fdtable(p->files)->max_fds;
     180          56 :         task_unlock(p);
     181          56 :         rcu_read_unlock();
     182             : 
     183          56 :         if (umask >= 0)
     184          55 :                 seq_printf(m, "Umask:\t%#04o\n", umask);
     185          56 :         seq_puts(m, "State:\t");
     186          56 :         seq_puts(m, get_task_state(p));
     187             : 
     188          56 :         seq_put_decimal_ull(m, "\nTgid:\t", tgid);
     189          56 :         seq_put_decimal_ull(m, "\nNgid:\t", ngid);
     190          56 :         seq_put_decimal_ull(m, "\nPid:\t", pid_nr_ns(pid, ns));
     191          56 :         seq_put_decimal_ull(m, "\nPPid:\t", ppid);
     192          56 :         seq_put_decimal_ull(m, "\nTracerPid:\t", tpid);
     193          56 :         seq_put_decimal_ull(m, "\nUid:\t", from_kuid_munged(user_ns, cred->uid));
     194          56 :         seq_put_decimal_ull(m, "\t", from_kuid_munged(user_ns, cred->euid));
     195          56 :         seq_put_decimal_ull(m, "\t", from_kuid_munged(user_ns, cred->suid));
     196          56 :         seq_put_decimal_ull(m, "\t", from_kuid_munged(user_ns, cred->fsuid));
     197          56 :         seq_put_decimal_ull(m, "\nGid:\t", from_kgid_munged(user_ns, cred->gid));
     198          56 :         seq_put_decimal_ull(m, "\t", from_kgid_munged(user_ns, cred->egid));
     199          56 :         seq_put_decimal_ull(m, "\t", from_kgid_munged(user_ns, cred->sgid));
     200          56 :         seq_put_decimal_ull(m, "\t", from_kgid_munged(user_ns, cred->fsgid));
     201          56 :         seq_put_decimal_ull(m, "\nFDSize:\t", max_fds);
     202             : 
     203          56 :         seq_puts(m, "\nGroups:\t");
     204          56 :         group_info = cred->group_info;
     205          56 :         for (g = 0; g < group_info->ngroups; g++)
     206           0 :                 seq_put_decimal_ull(m, g ? " " : "",
     207           0 :                                 from_kgid_munged(user_ns, group_info->gid[g]));
     208          56 :         put_cred(cred);
     209             :         /* Trailing space shouldn't have been added in the first place. */
     210          56 :         seq_putc(m, ' ');
     211             : 
     212             : #ifdef CONFIG_PID_NS
     213             :         seq_puts(m, "\nNStgid:");
     214             :         for (g = ns->level; g <= pid->level; g++)
     215             :                 seq_put_decimal_ull(m, "\t", task_tgid_nr_ns(p, pid->numbers[g].ns));
     216             :         seq_puts(m, "\nNSpid:");
     217             :         for (g = ns->level; g <= pid->level; g++)
     218             :                 seq_put_decimal_ull(m, "\t", task_pid_nr_ns(p, pid->numbers[g].ns));
     219             :         seq_puts(m, "\nNSpgid:");
     220             :         for (g = ns->level; g <= pid->level; g++)
     221             :                 seq_put_decimal_ull(m, "\t", task_pgrp_nr_ns(p, pid->numbers[g].ns));
     222             :         seq_puts(m, "\nNSsid:");
     223             :         for (g = ns->level; g <= pid->level; g++)
     224             :                 seq_put_decimal_ull(m, "\t", task_session_nr_ns(p, pid->numbers[g].ns));
     225             : #endif
     226          56 :         seq_putc(m, '\n');
     227          56 : }
     228             : 
     229         280 : void render_sigset_t(struct seq_file *m, const char *header,
     230             :                                 sigset_t *set)
     231             : {
     232         280 :         int i;
     233             : 
     234         280 :         seq_puts(m, header);
     235             : 
     236         280 :         i = _NSIG;
     237        4480 :         do {
     238        4480 :                 int x = 0;
     239             : 
     240        4480 :                 i -= 4;
     241        4480 :                 if (sigismember(set, i+1)) x |= 1;
     242        4480 :                 if (sigismember(set, i+2)) x |= 2;
     243        4480 :                 if (sigismember(set, i+3)) x |= 4;
     244        4480 :                 if (sigismember(set, i+4)) x |= 8;
     245        4480 :                 seq_putc(m, hex_asc[x]);
     246        4480 :         } while (i >= 4);
     247             : 
     248         280 :         seq_putc(m, '\n');
     249         280 : }
     250             : 
     251         197 : static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *sigign,
     252             :                                     sigset_t *sigcatch)
     253             : {
     254         197 :         struct k_sigaction *k;
     255         197 :         int i;
     256             : 
     257         197 :         k = p->sighand->action;
     258       12805 :         for (i = 1; i <= _NSIG; ++i, ++k) {
     259       12608 :                 if (k->sa.sa_handler == SIG_IGN)
     260        3021 :                         sigaddset(sigign, i);
     261        9587 :                 else if (k->sa.sa_handler != SIG_DFL)
     262       12608 :                         sigaddset(sigcatch, i);
     263             :         }
     264         197 : }
     265             : 
     266          56 : static inline void task_sig(struct seq_file *m, struct task_struct *p)
     267             : {
     268          56 :         unsigned long flags;
     269          56 :         sigset_t pending, shpending, blocked, ignored, caught;
     270          56 :         int num_threads = 0;
     271          56 :         unsigned int qsize = 0;
     272          56 :         unsigned long qlim = 0;
     273             : 
     274          56 :         sigemptyset(&pending);
     275          56 :         sigemptyset(&shpending);
     276          56 :         sigemptyset(&blocked);
     277          56 :         sigemptyset(&ignored);
     278          56 :         sigemptyset(&caught);
     279             : 
     280          56 :         if (lock_task_sighand(p, &flags)) {
     281          56 :                 pending = p->pending.signal;
     282          56 :                 shpending = p->signal->shared_pending.signal;
     283          56 :                 blocked = p->blocked;
     284          56 :                 collect_sigign_sigcatch(p, &ignored, &caught);
     285          56 :                 num_threads = get_nr_threads(p);
     286          56 :                 rcu_read_lock();  /* FIXME: is this correct? */
     287          56 :                 qsize = atomic_read(&__task_cred(p)->user->sigpending);
     288          56 :                 rcu_read_unlock();
     289          56 :                 qlim = task_rlimit(p, RLIMIT_SIGPENDING);
     290          56 :                 unlock_task_sighand(p, &flags);
     291             :         }
     292             : 
     293          56 :         seq_put_decimal_ull(m, "Threads:\t", num_threads);
     294          56 :         seq_put_decimal_ull(m, "\nSigQ:\t", qsize);
     295          56 :         seq_put_decimal_ull(m, "/", qlim);
     296             : 
     297             :         /* render them all */
     298          56 :         render_sigset_t(m, "\nSigPnd:\t", &pending);
     299          56 :         render_sigset_t(m, "ShdPnd:\t", &shpending);
     300          56 :         render_sigset_t(m, "SigBlk:\t", &blocked);
     301          56 :         render_sigset_t(m, "SigIgn:\t", &ignored);
     302          56 :         render_sigset_t(m, "SigCgt:\t", &caught);
     303          56 : }
     304             : 
     305         280 : static void render_cap_t(struct seq_file *m, const char *header,
     306             :                         kernel_cap_t *a)
     307             : {
     308         280 :         unsigned __capi;
     309             : 
     310         280 :         seq_puts(m, header);
     311        1120 :         CAP_FOR_EACH_U32(__capi) {
     312         560 :                 seq_put_hex_ll(m, NULL,
     313         560 :                            a->cap[CAP_LAST_U32 - __capi], 8);
     314             :         }
     315         280 :         seq_putc(m, '\n');
     316         280 : }
     317             : 
     318          56 : static inline void task_cap(struct seq_file *m, struct task_struct *p)
     319             : {
     320          56 :         const struct cred *cred;
     321          56 :         kernel_cap_t cap_inheritable, cap_permitted, cap_effective,
     322             :                         cap_bset, cap_ambient;
     323             : 
     324          56 :         rcu_read_lock();
     325          56 :         cred = __task_cred(p);
     326          56 :         cap_inheritable = cred->cap_inheritable;
     327          56 :         cap_permitted   = cred->cap_permitted;
     328          56 :         cap_effective   = cred->cap_effective;
     329          56 :         cap_bset        = cred->cap_bset;
     330          56 :         cap_ambient     = cred->cap_ambient;
     331          56 :         rcu_read_unlock();
     332             : 
     333          56 :         render_cap_t(m, "CapInh:\t", &cap_inheritable);
     334          56 :         render_cap_t(m, "CapPrm:\t", &cap_permitted);
     335          56 :         render_cap_t(m, "CapEff:\t", &cap_effective);
     336          56 :         render_cap_t(m, "CapBnd:\t", &cap_bset);
     337          56 :         render_cap_t(m, "CapAmb:\t", &cap_ambient);
     338          56 : }
     339             : 
     340          56 : static inline void task_seccomp(struct seq_file *m, struct task_struct *p)
     341             : {
     342          56 :         seq_put_decimal_ull(m, "NoNewPrivs:\t", task_no_new_privs(p));
     343             : #ifdef CONFIG_SECCOMP
     344             :         seq_put_decimal_ull(m, "\nSeccomp:\t", p->seccomp.mode);
     345             :         seq_put_decimal_ull(m, "\nSeccomp_filters:\t",
     346             :                             atomic_read(&p->seccomp.filter_count));
     347             : #endif
     348          56 :         seq_puts(m, "\nSpeculation_Store_Bypass:\t");
     349          56 :         switch (arch_prctl_spec_ctrl_get(p, PR_SPEC_STORE_BYPASS)) {
     350           0 :         case -EINVAL:
     351           0 :                 seq_puts(m, "unknown");
     352           0 :                 break;
     353           0 :         case PR_SPEC_NOT_AFFECTED:
     354           0 :                 seq_puts(m, "not vulnerable");
     355           0 :                 break;
     356           0 :         case PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE:
     357           0 :                 seq_puts(m, "thread force mitigated");
     358           0 :                 break;
     359           0 :         case PR_SPEC_PRCTL | PR_SPEC_DISABLE:
     360           0 :                 seq_puts(m, "thread mitigated");
     361           0 :                 break;
     362          56 :         case PR_SPEC_PRCTL | PR_SPEC_ENABLE:
     363          56 :                 seq_puts(m, "thread vulnerable");
     364          56 :                 break;
     365           0 :         case PR_SPEC_DISABLE:
     366           0 :                 seq_puts(m, "globally mitigated");
     367           0 :                 break;
     368           0 :         default:
     369           0 :                 seq_puts(m, "vulnerable");
     370           0 :                 break;
     371             :         }
     372             : 
     373          56 :         seq_puts(m, "\nSpeculationIndirectBranch:\t");
     374          56 :         switch (arch_prctl_spec_ctrl_get(p, PR_SPEC_INDIRECT_BRANCH)) {
     375           0 :         case -EINVAL:
     376           0 :                 seq_puts(m, "unsupported");
     377           0 :                 break;
     378           0 :         case PR_SPEC_NOT_AFFECTED:
     379           0 :                 seq_puts(m, "not affected");
     380           0 :                 break;
     381           0 :         case PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE:
     382           0 :                 seq_puts(m, "conditional force disabled");
     383           0 :                 break;
     384           0 :         case PR_SPEC_PRCTL | PR_SPEC_DISABLE:
     385           0 :                 seq_puts(m, "conditional disabled");
     386           0 :                 break;
     387           0 :         case PR_SPEC_PRCTL | PR_SPEC_ENABLE:
     388           0 :                 seq_puts(m, "conditional enabled");
     389           0 :                 break;
     390          56 :         case PR_SPEC_ENABLE:
     391          56 :                 seq_puts(m, "always enabled");
     392          56 :                 break;
     393           0 :         case PR_SPEC_DISABLE:
     394           0 :                 seq_puts(m, "always disabled");
     395           0 :                 break;
     396           0 :         default:
     397           0 :                 seq_puts(m, "unknown");
     398           0 :                 break;
     399             :         }
     400          56 :         seq_putc(m, '\n');
     401          56 : }
     402             : 
     403          56 : static inline void task_context_switch_counts(struct seq_file *m,
     404             :                                                 struct task_struct *p)
     405             : {
     406          56 :         seq_put_decimal_ull(m, "voluntary_ctxt_switches:\t", p->nvcsw);
     407          56 :         seq_put_decimal_ull(m, "\nnonvoluntary_ctxt_switches:\t", p->nivcsw);
     408          56 :         seq_putc(m, '\n');
     409          56 : }
     410             : 
     411          56 : static void task_cpus_allowed(struct seq_file *m, struct task_struct *task)
     412             : {
     413          56 :         seq_printf(m, "Cpus_allowed:\t%*pb\n",
     414          56 :                    cpumask_pr_args(&task->cpus_mask));
     415          56 :         seq_printf(m, "Cpus_allowed_list:\t%*pbl\n",
     416             :                    cpumask_pr_args(&task->cpus_mask));
     417          56 : }
     418             : 
     419          55 : static inline void task_core_dumping(struct seq_file *m, struct mm_struct *mm)
     420             : {
     421          55 :         seq_put_decimal_ull(m, "CoreDumping:\t", !!mm->core_state);
     422          55 :         seq_putc(m, '\n');
     423          55 : }
     424             : 
     425          55 : static inline void task_thp_status(struct seq_file *m, struct mm_struct *mm)
     426             : {
     427          55 :         bool thp_enabled = IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE);
     428             : 
     429          55 :         if (thp_enabled)
     430          55 :                 thp_enabled = !test_bit(MMF_DISABLE_THP, &mm->flags);
     431          55 :         seq_printf(m, "THP_enabled:\t%d\n", thp_enabled);
     432          55 : }
     433             : 
     434          56 : int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
     435             :                         struct pid *pid, struct task_struct *task)
     436             : {
     437          56 :         struct mm_struct *mm = get_task_mm(task);
     438             : 
     439          56 :         seq_puts(m, "Name:\t");
     440          56 :         proc_task_name(m, task, true);
     441          56 :         seq_putc(m, '\n');
     442             : 
     443          56 :         task_state(m, ns, pid, task);
     444             : 
     445          56 :         if (mm) {
     446          55 :                 task_mem(m, mm);
     447          55 :                 task_core_dumping(m, mm);
     448          55 :                 task_thp_status(m, mm);
     449          55 :                 mmput(mm);
     450             :         }
     451          56 :         task_sig(m, task);
     452          56 :         task_cap(m, task);
     453          56 :         task_seccomp(m, task);
     454          56 :         task_cpus_allowed(m, task);
     455          56 :         cpuset_task_status_allowed(m, task);
     456          56 :         task_context_switch_counts(m, task);
     457          56 :         return 0;
     458             : }
     459             : 
     460         141 : static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
     461             :                         struct pid *pid, struct task_struct *task, int whole)
     462             : {
     463         141 :         unsigned long vsize, eip, esp, wchan = 0;
     464         141 :         int priority, nice;
     465         141 :         int tty_pgrp = -1, tty_nr = 0;
     466         141 :         sigset_t sigign, sigcatch;
     467         141 :         char state;
     468         141 :         pid_t ppid = 0, pgid = -1, sid = -1;
     469         141 :         int num_threads = 0;
     470         141 :         int permitted;
     471         141 :         struct mm_struct *mm;
     472         141 :         unsigned long long start_time;
     473         141 :         unsigned long cmin_flt = 0, cmaj_flt = 0;
     474         141 :         unsigned long  min_flt = 0,  maj_flt = 0;
     475         141 :         u64 cutime, cstime, utime, stime;
     476         141 :         u64 cgtime, gtime;
     477         141 :         unsigned long rsslim = 0;
     478         141 :         unsigned long flags;
     479             : 
     480         141 :         state = *get_task_state(task);
     481         141 :         vsize = eip = esp = 0;
     482         141 :         permitted = ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS | PTRACE_MODE_NOAUDIT);
     483         141 :         mm = get_task_mm(task);
     484         141 :         if (mm) {
     485          96 :                 vsize = task_vsize(mm);
     486             :                 /*
     487             :                  * esp and eip are intentionally zeroed out.  There is no
     488             :                  * non-racy way to read them without freezing the task.
     489             :                  * Programs that need reliable values can use ptrace(2).
     490             :                  *
     491             :                  * The only exception is if the task is core dumping because
     492             :                  * a program is not able to use ptrace(2) in that case. It is
     493             :                  * safe because the task has stopped executing permanently.
     494             :                  */
     495          96 :                 if (permitted && (task->flags & (PF_EXITING|PF_DUMPCORE))) {
     496           0 :                         if (try_get_task_stack(task)) {
     497           0 :                                 eip = KSTK_EIP(task);
     498           0 :                                 esp = KSTK_ESP(task);
     499           0 :                                 put_task_stack(task);
     500             :                         }
     501             :                 }
     502             :         }
     503             : 
     504         141 :         sigemptyset(&sigign);
     505         141 :         sigemptyset(&sigcatch);
     506         141 :         cutime = cstime = utime = stime = 0;
     507         141 :         cgtime = gtime = 0;
     508             : 
     509         141 :         if (lock_task_sighand(task, &flags)) {
     510         141 :                 struct signal_struct *sig = task->signal;
     511             : 
     512         141 :                 if (sig->tty) {
     513           0 :                         struct pid *pgrp = tty_get_pgrp(sig->tty);
     514           0 :                         tty_pgrp = pid_nr_ns(pgrp, ns);
     515           0 :                         put_pid(pgrp);
     516           0 :                         tty_nr = new_encode_dev(tty_devnum(sig->tty));
     517             :                 }
     518             : 
     519         141 :                 num_threads = get_nr_threads(task);
     520         141 :                 collect_sigign_sigcatch(task, &sigign, &sigcatch);
     521             : 
     522         141 :                 cmin_flt = sig->cmin_flt;
     523         141 :                 cmaj_flt = sig->cmaj_flt;
     524         141 :                 cutime = sig->cutime;
     525         141 :                 cstime = sig->cstime;
     526         141 :                 cgtime = sig->cgtime;
     527         141 :                 rsslim = READ_ONCE(sig->rlim[RLIMIT_RSS].rlim_cur);
     528             : 
     529             :                 /* add up live thread stats at the group level */
     530         141 :                 if (whole) {
     531             :                         struct task_struct *t = task;
     532         141 :                         do {
     533         141 :                                 min_flt += t->min_flt;
     534         141 :                                 maj_flt += t->maj_flt;
     535         141 :                                 gtime += task_gtime(t);
     536         141 :                         } while_each_thread(task, t);
     537             : 
     538         141 :                         min_flt += sig->min_flt;
     539         141 :                         maj_flt += sig->maj_flt;
     540         141 :                         thread_group_cputime_adjusted(task, &utime, &stime);
     541         141 :                         gtime += sig->gtime;
     542             :                 }
     543             : 
     544         141 :                 sid = task_session_nr_ns(task, ns);
     545         141 :                 ppid = task_tgid_nr_ns(task->real_parent, ns);
     546         141 :                 pgid = task_pgrp_nr_ns(task, ns);
     547             : 
     548         141 :                 unlock_task_sighand(task, &flags);
     549             :         }
     550             : 
     551         141 :         if (permitted && (!whole || num_threads < 2))
     552         141 :                 wchan = get_wchan(task);
     553         141 :         if (!whole) {
     554           0 :                 min_flt = task->min_flt;
     555           0 :                 maj_flt = task->maj_flt;
     556           0 :                 task_cputime_adjusted(task, &utime, &stime);
     557           0 :                 gtime = task_gtime(task);
     558             :         }
     559             : 
     560             :         /* scale priority and nice values from timeslices to -20..20 */
     561             :         /* to make it look like a "normal" Unix priority/nice value  */
     562         141 :         priority = task_prio(task);
     563         141 :         nice = task_nice(task);
     564             : 
     565             :         /* apply timens offset for boottime and convert nsec -> ticks */
     566         141 :         start_time =
     567         141 :                 nsec_to_clock_t(timens_add_boottime_ns(task->start_boottime));
     568             : 
     569         141 :         seq_put_decimal_ull(m, "", pid_nr_ns(pid, ns));
     570         141 :         seq_puts(m, " (");
     571         141 :         proc_task_name(m, task, false);
     572         141 :         seq_puts(m, ") ");
     573         141 :         seq_putc(m, state);
     574         141 :         seq_put_decimal_ll(m, " ", ppid);
     575         141 :         seq_put_decimal_ll(m, " ", pgid);
     576         141 :         seq_put_decimal_ll(m, " ", sid);
     577         141 :         seq_put_decimal_ll(m, " ", tty_nr);
     578         141 :         seq_put_decimal_ll(m, " ", tty_pgrp);
     579         141 :         seq_put_decimal_ull(m, " ", task->flags);
     580         141 :         seq_put_decimal_ull(m, " ", min_flt);
     581         141 :         seq_put_decimal_ull(m, " ", cmin_flt);
     582         141 :         seq_put_decimal_ull(m, " ", maj_flt);
     583         141 :         seq_put_decimal_ull(m, " ", cmaj_flt);
     584         141 :         seq_put_decimal_ull(m, " ", nsec_to_clock_t(utime));
     585         141 :         seq_put_decimal_ull(m, " ", nsec_to_clock_t(stime));
     586         141 :         seq_put_decimal_ll(m, " ", nsec_to_clock_t(cutime));
     587         141 :         seq_put_decimal_ll(m, " ", nsec_to_clock_t(cstime));
     588         141 :         seq_put_decimal_ll(m, " ", priority);
     589         141 :         seq_put_decimal_ll(m, " ", nice);
     590         141 :         seq_put_decimal_ll(m, " ", num_threads);
     591         141 :         seq_put_decimal_ull(m, " ", 0);
     592         141 :         seq_put_decimal_ull(m, " ", start_time);
     593         141 :         seq_put_decimal_ull(m, " ", vsize);
     594         141 :         seq_put_decimal_ull(m, " ", mm ? get_mm_rss(mm) : 0);
     595         141 :         seq_put_decimal_ull(m, " ", rsslim);
     596         141 :         seq_put_decimal_ull(m, " ", mm ? (permitted ? mm->start_code : 1) : 0);
     597         141 :         seq_put_decimal_ull(m, " ", mm ? (permitted ? mm->end_code : 1) : 0);
     598         141 :         seq_put_decimal_ull(m, " ", (permitted && mm) ? mm->start_stack : 0);
     599         141 :         seq_put_decimal_ull(m, " ", esp);
     600         141 :         seq_put_decimal_ull(m, " ", eip);
     601             :         /* The signal information here is obsolete.
     602             :          * It must be decimal for Linux 2.0 compatibility.
     603             :          * Use /proc/#/status for real-time signals.
     604             :          */
     605         141 :         seq_put_decimal_ull(m, " ", task->pending.signal.sig[0] & 0x7fffffffUL);
     606         141 :         seq_put_decimal_ull(m, " ", task->blocked.sig[0] & 0x7fffffffUL);
     607         141 :         seq_put_decimal_ull(m, " ", sigign.sig[0] & 0x7fffffffUL);
     608         141 :         seq_put_decimal_ull(m, " ", sigcatch.sig[0] & 0x7fffffffUL);
     609             : 
     610             :         /*
     611             :          * We used to output the absolute kernel address, but that's an
     612             :          * information leak - so instead we show a 0/1 flag here, to signal
     613             :          * to user-space whether there's a wchan field in /proc/PID/wchan.
     614             :          *
     615             :          * This works with older implementations of procps as well.
     616             :          */
     617         141 :         if (wchan)
     618          52 :                 seq_puts(m, " 1");
     619             :         else
     620          89 :                 seq_puts(m, " 0");
     621             : 
     622         141 :         seq_put_decimal_ull(m, " ", 0);
     623         141 :         seq_put_decimal_ull(m, " ", 0);
     624         141 :         seq_put_decimal_ll(m, " ", task->exit_signal);
     625         141 :         seq_put_decimal_ll(m, " ", task_cpu(task));
     626         141 :         seq_put_decimal_ull(m, " ", task->rt_priority);
     627         141 :         seq_put_decimal_ull(m, " ", task->policy);
     628         282 :         seq_put_decimal_ull(m, " ", delayacct_blkio_ticks(task));
     629         141 :         seq_put_decimal_ull(m, " ", nsec_to_clock_t(gtime));
     630         141 :         seq_put_decimal_ll(m, " ", nsec_to_clock_t(cgtime));
     631             : 
     632         141 :         if (mm && permitted) {
     633          96 :                 seq_put_decimal_ull(m, " ", mm->start_data);
     634          96 :                 seq_put_decimal_ull(m, " ", mm->end_data);
     635          96 :                 seq_put_decimal_ull(m, " ", mm->start_brk);
     636          96 :                 seq_put_decimal_ull(m, " ", mm->arg_start);
     637          96 :                 seq_put_decimal_ull(m, " ", mm->arg_end);
     638          96 :                 seq_put_decimal_ull(m, " ", mm->env_start);
     639          96 :                 seq_put_decimal_ull(m, " ", mm->env_end);
     640             :         } else
     641          45 :                 seq_puts(m, " 0 0 0 0 0 0 0");
     642             : 
     643         141 :         if (permitted)
     644         141 :                 seq_put_decimal_ll(m, " ", task->exit_code);
     645             :         else
     646           0 :                 seq_puts(m, " 0");
     647             : 
     648         141 :         seq_putc(m, '\n');
     649         141 :         if (mm)
     650          96 :                 mmput(mm);
     651         141 :         return 0;
     652             : }
     653             : 
     654           0 : int proc_tid_stat(struct seq_file *m, struct pid_namespace *ns,
     655             :                         struct pid *pid, struct task_struct *task)
     656             : {
     657           0 :         return do_task_stat(m, ns, pid, task, 0);
     658             : }
     659             : 
     660         141 : int proc_tgid_stat(struct seq_file *m, struct pid_namespace *ns,
     661             :                         struct pid *pid, struct task_struct *task)
     662             : {
     663         141 :         return do_task_stat(m, ns, pid, task, 1);
     664             : }
     665             : 
     666           0 : int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns,
     667             :                         struct pid *pid, struct task_struct *task)
     668             : {
     669           0 :         struct mm_struct *mm = get_task_mm(task);
     670             : 
     671           0 :         if (mm) {
     672           0 :                 unsigned long size;
     673           0 :                 unsigned long resident = 0;
     674           0 :                 unsigned long shared = 0;
     675           0 :                 unsigned long text = 0;
     676           0 :                 unsigned long data = 0;
     677             : 
     678           0 :                 size = task_statm(mm, &shared, &text, &data, &resident);
     679           0 :                 mmput(mm);
     680             : 
     681             :                 /*
     682             :                  * For quick read, open code by putting numbers directly
     683             :                  * expected format is
     684             :                  * seq_printf(m, "%lu %lu %lu %lu 0 %lu 0\n",
     685             :                  *               size, resident, shared, text, data);
     686             :                  */
     687           0 :                 seq_put_decimal_ull(m, "", size);
     688           0 :                 seq_put_decimal_ull(m, " ", resident);
     689           0 :                 seq_put_decimal_ull(m, " ", shared);
     690           0 :                 seq_put_decimal_ull(m, " ", text);
     691           0 :                 seq_put_decimal_ull(m, " ", 0);
     692           0 :                 seq_put_decimal_ull(m, " ", data);
     693           0 :                 seq_put_decimal_ull(m, " ", 0);
     694           0 :                 seq_putc(m, '\n');
     695             :         } else {
     696           0 :                 seq_write(m, "0 0 0 0 0 0 0\n", 14);
     697             :         }
     698           0 :         return 0;
     699             : }
     700             : 
     701             : #ifdef CONFIG_PROC_CHILDREN
     702             : static struct pid *
     703             : get_children_pid(struct inode *inode, struct pid *pid_prev, loff_t pos)
     704             : {
     705             :         struct task_struct *start, *task;
     706             :         struct pid *pid = NULL;
     707             : 
     708             :         read_lock(&tasklist_lock);
     709             : 
     710             :         start = pid_task(proc_pid(inode), PIDTYPE_PID);
     711             :         if (!start)
     712             :                 goto out;
     713             : 
     714             :         /*
     715             :          * Lets try to continue searching first, this gives
     716             :          * us significant speedup on children-rich processes.
     717             :          */
     718             :         if (pid_prev) {
     719             :                 task = pid_task(pid_prev, PIDTYPE_PID);
     720             :                 if (task && task->real_parent == start &&
     721             :                     !(list_empty(&task->sibling))) {
     722             :                         if (list_is_last(&task->sibling, &start->children))
     723             :                                 goto out;
     724             :                         task = list_first_entry(&task->sibling,
     725             :                                                 struct task_struct, sibling);
     726             :                         pid = get_pid(task_pid(task));
     727             :                         goto out;
     728             :                 }
     729             :         }
     730             : 
     731             :         /*
     732             :          * Slow search case.
     733             :          *
     734             :          * We might miss some children here if children
     735             :          * are exited while we were not holding the lock,
     736             :          * but it was never promised to be accurate that
     737             :          * much.
     738             :          *
     739             :          * "Just suppose that the parent sleeps, but N children
     740             :          *  exit after we printed their tids. Now the slow paths
     741             :          *  skips N extra children, we miss N tasks." (c)
     742             :          *
     743             :          * So one need to stop or freeze the leader and all
     744             :          * its children to get a precise result.
     745             :          */
     746             :         list_for_each_entry(task, &start->children, sibling) {
     747             :                 if (pos-- == 0) {
     748             :                         pid = get_pid(task_pid(task));
     749             :                         break;
     750             :                 }
     751             :         }
     752             : 
     753             : out:
     754             :         read_unlock(&tasklist_lock);
     755             :         return pid;
     756             : }
     757             : 
     758             : static int children_seq_show(struct seq_file *seq, void *v)
     759             : {
     760             :         struct inode *inode = file_inode(seq->file);
     761             : 
     762             :         seq_printf(seq, "%d ", pid_nr_ns(v, proc_pid_ns(inode->i_sb)));
     763             :         return 0;
     764             : }
     765             : 
     766             : static void *children_seq_start(struct seq_file *seq, loff_t *pos)
     767             : {
     768             :         return get_children_pid(file_inode(seq->file), NULL, *pos);
     769             : }
     770             : 
     771             : static void *children_seq_next(struct seq_file *seq, void *v, loff_t *pos)
     772             : {
     773             :         struct pid *pid;
     774             : 
     775             :         pid = get_children_pid(file_inode(seq->file), v, *pos + 1);
     776             :         put_pid(v);
     777             : 
     778             :         ++*pos;
     779             :         return pid;
     780             : }
     781             : 
     782             : static void children_seq_stop(struct seq_file *seq, void *v)
     783             : {
     784             :         put_pid(v);
     785             : }
     786             : 
     787             : static const struct seq_operations children_seq_ops = {
     788             :         .start  = children_seq_start,
     789             :         .next   = children_seq_next,
     790             :         .stop   = children_seq_stop,
     791             :         .show   = children_seq_show,
     792             : };
     793             : 
     794             : static int children_seq_open(struct inode *inode, struct file *file)
     795             : {
     796             :         return seq_open(file, &children_seq_ops);
     797             : }
     798             : 
     799             : const struct file_operations proc_tid_children_operations = {
     800             :         .open    = children_seq_open,
     801             :         .read    = seq_read,
     802             :         .llseek  = seq_lseek,
     803             :         .release = seq_release,
     804             : };
     805             : #endif /* CONFIG_PROC_CHILDREN */

Generated by: LCOV version 1.14