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

Generated by: LCOV version 1.14