LCOV - code coverage report
Current view: top level - fs/proc - array.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 356 0.0 %
Date: 2023-07-19 18:55:55 Functions: 0 15 0.0 %

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

Generated by: LCOV version 1.14