Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  *  linux/fs/proc/base.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *  Copyright (C) 1991, 1992 Linus Torvalds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  *  proc base directory handling functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  *  1999, Al Viro. Rewritten. Now it covers the whole per-process part.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  *  Instead of using magical inumbers to determine the kind of object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  *  we allocate and fill in-core inodes upon lookup. They don't even
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  *  go into icache. We cache the reference to task_struct upon lookup too.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  *  Eventually it should become a filesystem in its own. We don't use the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  *  rest of procfs anymore.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17)  *  Changelog:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18)  *  17-Jan-2005
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19)  *  Allan Bezerra
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20)  *  Bruna Moreira <bruna.moreira@indt.org.br>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21)  *  Edjard Mota <edjard.mota@indt.org.br>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22)  *  Ilias Biris <ilias.biris@indt.org.br>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23)  *  Mauricio Lin <mauricio.lin@indt.org.br>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25)  *  Embedded Linux Lab - 10LE Instituto Nokia de Tecnologia - INdT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27)  *  A new process specific entry (smaps) included in /proc. It shows the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28)  *  size of rss for each memory area. The maps entry lacks information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29)  *  about physical memory size (rss) for each mapped file, i.e.,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30)  *  rss information for executables and library files.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31)  *  This additional information is useful for any tools that need to know
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32)  *  about physical memory consumption for a process specific library.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34)  *  Changelog:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35)  *  21-Feb-2005
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36)  *  Embedded Linux Lab - 10LE Instituto Nokia de Tecnologia - INdT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37)  *  Pud inclusion in the page table walking.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39)  *  ChangeLog:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40)  *  10-Mar-2005
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41)  *  10LE Instituto Nokia de Tecnologia - INdT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42)  *  A better way to walks through the page table as suggested by Hugh Dickins.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44)  *  Simo Piiroinen <simo.piiroinen@nokia.com>:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45)  *  Smaps information related to shared, private, clean and dirty pages.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47)  *  Paul Mundt <paul.mundt@nokia.com>:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48)  *  Overall revision about smaps.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) #include <linux/proc_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) #include <linux/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) #include <linux/task_io_accounting_ops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) #include <linux/capability.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) #include <linux/file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) #include <linux/fdtable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) #include <linux/generic-radix-tree.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) #include <linux/namei.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) #include <linux/mnt_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) #include <linux/swap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) #include <linux/rcupdate.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) #include <linux/kallsyms.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) #include <linux/stacktrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) #include <linux/resource.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) #include <linux/mount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) #include <linux/security.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) #include <linux/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) #include <linux/tracehook.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) #include <linux/printk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) #include <linux/cache.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) #include <linux/cgroup.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) #include <linux/cpuset.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) #include <linux/audit.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) #include <linux/poll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) #include <linux/nsproxy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) #include <linux/oom.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) #include <linux/elf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) #include <linux/pid_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) #include <linux/user_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) #include <linux/fs_struct.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) #include <linux/sched/autogroup.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) #include <linux/sched/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) #include <linux/sched/coredump.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) #include <linux/sched/debug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) #include <linux/sched/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) #include <linux/posix-timers.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) #include <linux/time_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) #include <linux/resctrl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) #include <linux/cpufreq_times.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) #include <trace/events/oom.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) #include "fd.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) #include "../../lib/kstrtox.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) /* NOTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107)  *	Implementing inode permission operations in /proc is almost
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108)  *	certainly an error.  Permission checks need to happen during
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109)  *	each system call not at open time.  The reason is that most of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110)  *	what we wish to check for permissions in /proc varies at runtime.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112)  *	The classic example of a problem is opening file descriptors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113)  *	in /proc for a task before it execs a suid executable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) static u8 nlink_tid __ro_after_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) static u8 nlink_tgid __ro_after_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) struct pid_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	unsigned int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 	umode_t mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 	const struct inode_operations *iop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 	const struct file_operations *fop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	union proc_op op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) #define NOD(NAME, MODE, IOP, FOP, OP) {			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	.name = (NAME),					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 	.len  = sizeof(NAME) - 1,			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	.mode = MODE,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	.iop  = IOP,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	.fop  = FOP,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	.op   = OP,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) #define DIR(NAME, MODE, iops, fops)	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	NOD(NAME, (S_IFDIR|(MODE)), &iops, &fops, {} )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) #define LNK(NAME, get_link)					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	NOD(NAME, (S_IFLNK|S_IRWXUGO),				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 		&proc_pid_link_inode_operations, NULL,		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 		{ .proc_get_link = get_link } )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) #define REG(NAME, MODE, fops)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	NOD(NAME, (S_IFREG|(MODE)), NULL, &fops, {})
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) #define ONE(NAME, MODE, show)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	NOD(NAME, (S_IFREG|(MODE)),			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 		NULL, &proc_single_file_operations,	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 		{ .proc_show = show } )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) #define ATTR(LSM, NAME, MODE)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	NOD(NAME, (S_IFREG|(MODE)),			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 		NULL, &proc_pid_attr_operations,	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 		{ .lsm = LSM })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155)  * Count the number of hardlinks for the pid_entry table, excluding the .
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156)  * and .. links.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) static unsigned int __init pid_entry_nlink(const struct pid_entry *entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	unsigned int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	unsigned int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	for (i = 0; i < n; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 		if (S_ISDIR(entries[i].mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 			++count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) static int get_task_root(struct task_struct *task, struct path *root)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	int result = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	task_lock(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	if (task->fs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 		get_fs_root(task->fs, root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 		result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	task_unlock(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) static int proc_cwd_link(struct dentry *dentry, struct path *path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	struct task_struct *task = get_proc_task(d_inode(dentry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	int result = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	if (task) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 		task_lock(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 		if (task->fs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 			get_fs_pwd(task->fs, path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 			result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 		task_unlock(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 		put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) static int proc_root_link(struct dentry *dentry, struct path *path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	struct task_struct *task = get_proc_task(d_inode(dentry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	int result = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	if (task) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 		result = get_task_root(task, path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 		put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216)  * If the user used setproctitle(), we just get the string from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217)  * user space at arg_start, and limit it to a maximum of one page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) static ssize_t get_mm_proctitle(struct mm_struct *mm, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 				size_t count, unsigned long pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 				unsigned long arg_start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	char *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	int ret, got;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	if (pos >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	page = (char *)__get_free_page(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	if (!page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 	ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 	got = access_remote_vm(mm, arg_start, page, PAGE_SIZE, FOLL_ANON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	if (got > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 		int len = strnlen(page, got);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 		/* Include the NUL character if it was found */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 		if (len < got)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 			len++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 		if (len > pos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 			len -= pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 			if (len > count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 				len = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 			len -= copy_to_user(buf, page+pos, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 			if (!len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 				len = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 			ret = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	free_page((unsigned long)page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) static ssize_t get_mm_cmdline(struct mm_struct *mm, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 			      size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 	unsigned long arg_start, arg_end, env_start, env_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	unsigned long pos, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 	char *page, c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	/* Check if process spawned far enough to have cmdline. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	if (!mm->env_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 	spin_lock(&mm->arg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 	arg_start = mm->arg_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	arg_end = mm->arg_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 	env_start = mm->env_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	env_end = mm->env_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	spin_unlock(&mm->arg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	if (arg_start >= arg_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	 * We allow setproctitle() to overwrite the argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	 * strings, and overflow past the original end. But
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	 * only when it overflows into the environment area.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 	if (env_start != arg_end || env_end < env_start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 		env_start = env_end = arg_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 	len = env_end - arg_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	/* We're not going to care if "*ppos" has high bits set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	pos = *ppos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	if (pos >= len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	if (count > len - pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 		count = len - pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 	if (!count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	 * Magical special case: if the argv[] end byte is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	 * zero, the user has overwritten it with setproctitle(3).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	 * Possible future enhancement: do this only once when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 	 * pos is 0, and set a flag in the 'struct file'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 	if (access_remote_vm(mm, arg_end-1, &c, 1, FOLL_ANON) == 1 && c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 		return get_mm_proctitle(mm, buf, count, pos, arg_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 	 * For the non-setproctitle() case we limit things strictly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	 * to the [arg_start, arg_end[ range.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	pos += arg_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 	if (pos < arg_start || pos >= arg_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	if (count > arg_end - pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 		count = arg_end - pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 	page = (char *)__get_free_page(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 	if (!page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 	len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	while (count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 		int got;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 		size_t size = min_t(size_t, PAGE_SIZE, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 		got = access_remote_vm(mm, pos, page, size, FOLL_ANON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 		if (got <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 		got -= copy_to_user(buf, page, got);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 		if (unlikely(!got)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 			if (!len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 				len = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 		pos += got;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 		buf += got;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 		len += got;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 		count -= got;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	free_page((unsigned long)page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) static ssize_t get_task_cmdline(struct task_struct *tsk, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 				size_t count, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 	struct mm_struct *mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 	mm = get_task_mm(tsk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	if (!mm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	ret = get_mm_cmdline(mm, buf, count, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	mmput(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 				     size_t count, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	struct task_struct *tsk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 	BUG_ON(*pos < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 	tsk = get_proc_task(file_inode(file));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	if (!tsk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 		return -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	ret = get_task_cmdline(tsk, buf, count, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	put_task_struct(tsk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	if (ret > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 		*pos += ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) static const struct file_operations proc_pid_cmdline_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	.read	= proc_pid_cmdline_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	.llseek	= generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) #ifdef CONFIG_KALLSYMS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383)  * Provides a wchan file via kallsyms in a proper one-value-per-file format.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384)  * Returns the resolved symbol.  If that fails, simply return the address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) static int proc_pid_wchan(struct seq_file *m, struct pid_namespace *ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 			  struct pid *pid, struct task_struct *task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 	unsigned long wchan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 	char symname[KSYM_NAME_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 	if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 		goto print0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 	wchan = get_wchan(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	if (wchan && !lookup_symbol_name(wchan, symname)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 		seq_puts(m, symname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) print0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	seq_putc(m, '0');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) #endif /* CONFIG_KALLSYMS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) static int lock_trace(struct task_struct *task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 	int err = down_read_killable(&task->signal->exec_update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	if (!ptrace_may_access(task, PTRACE_MODE_ATTACH_FSCREDS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 		up_read(&task->signal->exec_update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) static void unlock_trace(struct task_struct *task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	up_read(&task->signal->exec_update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) #ifdef CONFIG_STACKTRACE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) #define MAX_STACK_TRACE_DEPTH	64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) static int proc_pid_stack(struct seq_file *m, struct pid_namespace *ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 			  struct pid *pid, struct task_struct *task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	unsigned long *entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 	 * The ability to racily run the kernel stack unwinder on a running task
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	 * and then observe the unwinder output is scary; while it is useful for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 	 * debugging kernel issues, it can also allow an attacker to leak kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	 * stack contents.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	 * Doing this in a manner that is at least safe from races would require
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 	 * some work to ensure that the remote task can not be scheduled; and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 	 * even then, this would still expose the unwinder as local attack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	 * surface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 	 * Therefore, this interface is restricted to root.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	if (!file_ns_capable(m->file, &init_user_ns, CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 		return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 	entries = kmalloc_array(MAX_STACK_TRACE_DEPTH, sizeof(*entries),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 				GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 	if (!entries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	err = lock_trace(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 		unsigned int i, nr_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 		nr_entries = stack_trace_save_tsk(task, entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 						  MAX_STACK_TRACE_DEPTH, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 		for (i = 0; i < nr_entries; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 			seq_printf(m, "[<0>] %pB\n", (void *)entries[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 		unlock_trace(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 	kfree(entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) #ifdef CONFIG_SCHED_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474)  * Provides /proc/PID/schedstat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) static int proc_pid_schedstat(struct seq_file *m, struct pid_namespace *ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 			      struct pid *pid, struct task_struct *task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	if (unlikely(!sched_info_on()))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 		seq_puts(m, "0 0 0\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 		seq_printf(m, "%llu %llu %lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 		   (unsigned long long)task->se.sum_exec_runtime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 		   (unsigned long long)task->sched_info.run_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 		   task->sched_info.pcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) #ifdef CONFIG_LATENCYTOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) static int lstats_show_proc(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 	struct inode *inode = m->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 	struct task_struct *task = get_proc_task(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	if (!task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 		return -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 	seq_puts(m, "Latency Top version : v0.1\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 	for (i = 0; i < LT_SAVECOUNT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 		struct latency_record *lr = &task->latency_record[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 		if (lr->backtrace[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 			int q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 			seq_printf(m, "%i %li %li",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 				   lr->count, lr->time, lr->max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 			for (q = 0; q < LT_BACKTRACEDEPTH; q++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 				unsigned long bt = lr->backtrace[q];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 				if (!bt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 				seq_printf(m, " %ps", (void *)bt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 			seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) static int lstats_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 	return single_open(file, lstats_show_proc, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) static ssize_t lstats_write(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 			    size_t count, loff_t *offs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 	struct task_struct *task = get_proc_task(file_inode(file));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	if (!task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 		return -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	clear_tsk_latency_tracing(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 	put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) static const struct file_operations proc_lstats_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	.open		= lstats_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	.read		= seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 	.write		= lstats_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	.llseek		= seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	.release	= single_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) static int proc_oom_score(struct seq_file *m, struct pid_namespace *ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 			  struct pid *pid, struct task_struct *task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	unsigned long totalpages = totalram_pages() + total_swap_pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	unsigned long points = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	long badness;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	badness = oom_badness(task, totalpages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 	 * Special case OOM_SCORE_ADJ_MIN for all others scale the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	 * badness value into [0, 2000] range which we have been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	 * exporting for a long time so userspace might depend on it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	if (badness != LONG_MIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 		points = (1000 + badness * 1000 / (long)totalpages) * 2 / 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	seq_printf(m, "%lu\n", points);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) struct limit_names {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	const char *unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) static const struct limit_names lnames[RLIM_NLIMITS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 	[RLIMIT_CPU] = {"Max cpu time", "seconds"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	[RLIMIT_FSIZE] = {"Max file size", "bytes"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	[RLIMIT_DATA] = {"Max data size", "bytes"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	[RLIMIT_STACK] = {"Max stack size", "bytes"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	[RLIMIT_CORE] = {"Max core file size", "bytes"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	[RLIMIT_RSS] = {"Max resident set", "bytes"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	[RLIMIT_NPROC] = {"Max processes", "processes"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	[RLIMIT_NOFILE] = {"Max open files", "files"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	[RLIMIT_MEMLOCK] = {"Max locked memory", "bytes"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	[RLIMIT_AS] = {"Max address space", "bytes"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	[RLIMIT_LOCKS] = {"Max file locks", "locks"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	[RLIMIT_SIGPENDING] = {"Max pending signals", "signals"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	[RLIMIT_MSGQUEUE] = {"Max msgqueue size", "bytes"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	[RLIMIT_NICE] = {"Max nice priority", NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	[RLIMIT_RTPRIO] = {"Max realtime priority", NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 	[RLIMIT_RTTIME] = {"Max realtime timeout", "us"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) /* Display limits for a process */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) static int proc_pid_limits(struct seq_file *m, struct pid_namespace *ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 			   struct pid *pid, struct task_struct *task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	struct rlimit rlim[RLIM_NLIMITS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	if (!lock_task_sighand(task, &flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	memcpy(rlim, task->signal->rlim, sizeof(struct rlimit) * RLIM_NLIMITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	unlock_task_sighand(task, &flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 	 * print the file header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	seq_puts(m, "Limit                     "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 		"Soft Limit           "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 		"Hard Limit           "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 		"Units     \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	for (i = 0; i < RLIM_NLIMITS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 		if (rlim[i].rlim_cur == RLIM_INFINITY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 			seq_printf(m, "%-25s %-20s ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 				   lnames[i].name, "unlimited");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 			seq_printf(m, "%-25s %-20lu ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 				   lnames[i].name, rlim[i].rlim_cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 		if (rlim[i].rlim_max == RLIM_INFINITY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 			seq_printf(m, "%-20s ", "unlimited");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 			seq_printf(m, "%-20lu ", rlim[i].rlim_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 		if (lnames[i].unit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 			seq_printf(m, "%-10s\n", lnames[i].unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 			seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) #ifdef CONFIG_HAVE_ARCH_TRACEHOOK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) static int proc_pid_syscall(struct seq_file *m, struct pid_namespace *ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 			    struct pid *pid, struct task_struct *task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	struct syscall_info info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	u64 *args = &info.data.args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 	res = lock_trace(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 	if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 		return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 	if (task_current_syscall(task, &info))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 		seq_puts(m, "running\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	else if (info.data.nr < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 		seq_printf(m, "%d 0x%llx 0x%llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 			   info.data.nr, info.sp, info.data.instruction_pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 		seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 		       "%d 0x%llx 0x%llx 0x%llx 0x%llx 0x%llx 0x%llx 0x%llx 0x%llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 		       info.data.nr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 		       args[0], args[1], args[2], args[3], args[4], args[5],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 		       info.sp, info.data.instruction_pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 	unlock_trace(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) #endif /* CONFIG_HAVE_ARCH_TRACEHOOK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) /************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) /*                       Here the fs part begins                        */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) /************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) /* permission checks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) static int proc_fd_access_allowed(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 	struct task_struct *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 	int allowed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 	/* Allow access to a task's file descriptors if it is us or we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 	 * may use ptrace attach to the process and find out that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	 * information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	task = get_proc_task(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	if (task) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 		allowed = ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 		put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	return allowed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) int proc_setattr(struct dentry *dentry, struct iattr *attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	struct inode *inode = d_inode(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 	if (attr->ia_valid & ATTR_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 	error = setattr_prepare(dentry, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	setattr_copy(inode, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	mark_inode_dirty(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707)  * May current process learn task's sched/cmdline info (for hide_pid_min=1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708)  * or euid/egid (for hide_pid_min=2)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) static bool has_pid_permissions(struct proc_fs_info *fs_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 				 struct task_struct *task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 				 enum proc_hidepid hide_pid_min)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 	 * If 'hidpid' mount option is set force a ptrace check,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	 * we indicate that we are using a filesystem syscall
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 	 * by passing PTRACE_MODE_READ_FSCREDS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	if (fs_info->hide_pid == HIDEPID_NOT_PTRACEABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 		return ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	if (fs_info->hide_pid < hide_pid_min)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 	if (in_group_p(fs_info->pid_gid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	return ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) static int proc_pid_permission(struct inode *inode, int mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	struct proc_fs_info *fs_info = proc_sb_info(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	struct task_struct *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	bool has_perms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 	task = get_proc_task(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 	if (!task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 		return -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 	has_perms = has_pid_permissions(fs_info, task, HIDEPID_NO_ACCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 	put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 	if (!has_perms) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 		if (fs_info->hide_pid == HIDEPID_INVISIBLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 			 * Let's make getdents(), stat(), and open()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 			 * consistent with each other.  If a process
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 			 * may not stat() a file, it shouldn't be seen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 			 * in procfs at all.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 			return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	return generic_permission(inode, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) static const struct inode_operations proc_def_inode_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 	.setattr	= proc_setattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) static int proc_single_show(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	struct inode *inode = m->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	struct pid_namespace *ns = proc_pid_ns(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	struct pid *pid = proc_pid(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 	struct task_struct *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 	task = get_pid_task(pid, PIDTYPE_PID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	if (!task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 		return -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 	ret = PROC_I(inode)->op.proc_show(m, ns, pid, task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 	put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) static int proc_single_open(struct inode *inode, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 	return single_open(filp, proc_single_show, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) static const struct file_operations proc_single_file_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	.open		= proc_single_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	.read		= seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	.llseek		= seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	.release	= single_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) struct mm_struct *proc_mem_open(struct inode *inode, unsigned int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 	struct task_struct *task = get_proc_task(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	struct mm_struct *mm = ERR_PTR(-ESRCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	if (task) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 		mm = mm_access(task, mode | PTRACE_MODE_FSCREDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 		put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 		if (!IS_ERR_OR_NULL(mm)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 			/* ensure this mm_struct can't be freed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 			mmgrab(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 			/* but do not pin its memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 			mmput(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 	return mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) static int __mem_open(struct inode *inode, struct file *file, unsigned int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	struct mm_struct *mm = proc_mem_open(inode, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	if (IS_ERR(mm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 		return PTR_ERR(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 	file->private_data = mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) static int mem_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 	int ret = __mem_open(inode, file, PTRACE_MODE_ATTACH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 	/* OK to pass negative loff_t, we can catch out-of-range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	file->f_mode |= FMODE_UNSIGNED_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) static ssize_t mem_rw(struct file *file, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 			size_t count, loff_t *ppos, int write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 	struct mm_struct *mm = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 	unsigned long addr = *ppos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 	ssize_t copied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	char *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	unsigned int flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	if (!mm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	page = (char *)__get_free_page(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	if (!page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	copied = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	if (!mmget_not_zero(mm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 		goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	flags = FOLL_FORCE | (write ? FOLL_WRITE : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 	while (count > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 		size_t this_len = min_t(size_t, count, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 		if (write && copy_from_user(page, buf, this_len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 			copied = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 		this_len = access_remote_vm(mm, addr, page, this_len, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 		if (!this_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 			if (!copied)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 				copied = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 		if (!write && copy_to_user(buf, page, this_len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 			copied = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 		buf += this_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 		addr += this_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 		copied += this_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 		count -= this_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	*ppos = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	mmput(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	free_page((unsigned long) page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	return copied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) static ssize_t mem_read(struct file *file, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 			size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	return mem_rw(file, buf, count, ppos, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) static ssize_t mem_write(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 			 size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	return mem_rw(file, (char __user*)buf, count, ppos, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) loff_t mem_lseek(struct file *file, loff_t offset, int orig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	switch (orig) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 		file->f_pos = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 		file->f_pos += offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 	force_successful_syscall_return();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	return file->f_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) static int mem_release(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	struct mm_struct *mm = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	if (mm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 		mmdrop(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) static const struct file_operations proc_mem_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 	.llseek		= mem_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	.read		= mem_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	.write		= mem_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	.open		= mem_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 	.release	= mem_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) static int environ_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	return __mem_open(inode, file, PTRACE_MODE_READ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) static ssize_t environ_read(struct file *file, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 			size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	char *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 	unsigned long src = *ppos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	struct mm_struct *mm = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	unsigned long env_start, env_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	/* Ensure the process spawned far enough to have an environment. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	if (!mm || !mm->env_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	page = (char *)__get_free_page(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	if (!page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	if (!mmget_not_zero(mm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 		goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	spin_lock(&mm->arg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	env_start = mm->env_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	env_end = mm->env_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	spin_unlock(&mm->arg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	while (count > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 		size_t this_len, max_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 		int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 		if (src >= (env_end - env_start))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 		this_len = env_end - (env_start + src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 		max_len = min_t(size_t, PAGE_SIZE, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 		this_len = min(max_len, this_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 		retval = access_remote_vm(mm, (env_start + src), page, this_len, FOLL_ANON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 		if (retval <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 			ret = retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 		if (copy_to_user(buf, page, retval)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 			ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 		ret += retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 		src += retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 		buf += retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 		count -= retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	*ppos = src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	mmput(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 	free_page((unsigned long) page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) static const struct file_operations proc_environ_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	.open		= environ_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	.read		= environ_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	.llseek		= generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	.release	= mem_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) static int auxv_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	return __mem_open(inode, file, PTRACE_MODE_READ_FSCREDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) static ssize_t auxv_read(struct file *file, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 			size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	struct mm_struct *mm = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	unsigned int nwords = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	if (!mm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 		nwords += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	} while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	return simple_read_from_buffer(buf, count, ppos, mm->saved_auxv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 				       nwords * sizeof(mm->saved_auxv[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) static const struct file_operations proc_auxv_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	.open		= auxv_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	.read		= auxv_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	.llseek		= generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	.release	= mem_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) static ssize_t oom_adj_read(struct file *file, char __user *buf, size_t count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 			    loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 	struct task_struct *task = get_proc_task(file_inode(file));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	char buffer[PROC_NUMBUF];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 	int oom_adj = OOM_ADJUST_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 	if (!task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 		return -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	if (task->signal->oom_score_adj == OOM_SCORE_ADJ_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 		oom_adj = OOM_ADJUST_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 		oom_adj = (task->signal->oom_score_adj * -OOM_DISABLE) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 			  OOM_SCORE_ADJ_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 	put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 	if (oom_adj > OOM_ADJUST_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 		oom_adj = OOM_ADJUST_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 	len = snprintf(buffer, sizeof(buffer), "%d\n", oom_adj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	return simple_read_from_buffer(buf, count, ppos, buffer, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) static int __set_oom_adj(struct file *file, int oom_adj, bool legacy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 	struct mm_struct *mm = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	struct task_struct *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 	task = get_proc_task(file_inode(file));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 	if (!task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 		return -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	mutex_lock(&oom_adj_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	if (legacy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 		if (oom_adj < task->signal->oom_score_adj &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 				!capable(CAP_SYS_RESOURCE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 			err = -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 			goto err_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 		 * /proc/pid/oom_adj is provided for legacy purposes, ask users to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 		 * /proc/pid/oom_score_adj instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 		pr_warn_once("%s (%d): /proc/%d/oom_adj is deprecated, please use /proc/%d/oom_score_adj instead.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 			  current->comm, task_pid_nr(current), task_pid_nr(task),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 			  task_pid_nr(task));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 		if ((short)oom_adj < task->signal->oom_score_adj_min &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 				!capable(CAP_SYS_RESOURCE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 			err = -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 			goto err_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 	 * Make sure we will check other processes sharing the mm if this is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 	 * not vfrok which wants its own oom_score_adj.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 	 * pin the mm so it doesn't go away and get reused after task_unlock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 	if (!task->vfork_done) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 		struct task_struct *p = find_lock_task_mm(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 		if (p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 			if (test_bit(MMF_MULTIPROCESS, &p->mm->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 				mm = p->mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 				mmgrab(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 			task_unlock(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	task->signal->oom_score_adj = oom_adj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	if (!legacy && has_capability_noaudit(current, CAP_SYS_RESOURCE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 		task->signal->oom_score_adj_min = (short)oom_adj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	trace_oom_score_adj_update(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	if (mm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 		struct task_struct *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 		rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 		for_each_process(p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 			if (same_thread_group(task, p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 			/* do not touch kernel threads or the global init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 			if (p->flags & PF_KTHREAD || is_global_init(p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 			task_lock(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 			if (!p->vfork_done && process_shares_mm(p, mm)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 				p->signal->oom_score_adj = oom_adj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 				if (!legacy && has_capability_noaudit(current, CAP_SYS_RESOURCE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 					p->signal->oom_score_adj_min = (short)oom_adj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 			task_unlock(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 		mmdrop(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) err_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 	mutex_unlock(&oom_adj_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 	put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)  * /proc/pid/oom_adj exists solely for backwards compatibility with previous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)  * kernels.  The effective policy is defined by oom_score_adj, which has a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)  * different scale: oom_adj grew exponentially and oom_score_adj grows linearly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)  * Values written to oom_adj are simply mapped linearly to oom_score_adj.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)  * Processes that become oom disabled via oom_adj will still be oom disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)  * with this implementation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)  * oom_adj cannot be removed since existing userspace binaries use it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) static ssize_t oom_adj_write(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 			     size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 	char buffer[PROC_NUMBUF];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	int oom_adj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	memset(buffer, 0, sizeof(buffer));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	if (count > sizeof(buffer) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 		count = sizeof(buffer) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 	if (copy_from_user(buffer, buf, count)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 		err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 	err = kstrtoint(strstrip(buffer), 0, &oom_adj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 	if ((oom_adj < OOM_ADJUST_MIN || oom_adj > OOM_ADJUST_MAX) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 	     oom_adj != OOM_DISABLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 	 * Scale /proc/pid/oom_score_adj appropriately ensuring that a maximum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 	 * value is always attainable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 	if (oom_adj == OOM_ADJUST_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 		oom_adj = OOM_SCORE_ADJ_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 		oom_adj = (oom_adj * OOM_SCORE_ADJ_MAX) / -OOM_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 	err = __set_oom_adj(file, oom_adj, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 	return err < 0 ? err : count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) static const struct file_operations proc_oom_adj_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 	.read		= oom_adj_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 	.write		= oom_adj_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 	.llseek		= generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) static ssize_t oom_score_adj_read(struct file *file, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 					size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 	struct task_struct *task = get_proc_task(file_inode(file));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 	char buffer[PROC_NUMBUF];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	short oom_score_adj = OOM_SCORE_ADJ_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 	size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 	if (!task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 		return -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	oom_score_adj = task->signal->oom_score_adj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 	put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 	len = snprintf(buffer, sizeof(buffer), "%hd\n", oom_score_adj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 	return simple_read_from_buffer(buf, count, ppos, buffer, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) static ssize_t oom_score_adj_write(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 					size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 	char buffer[PROC_NUMBUF];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 	int oom_score_adj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 	memset(buffer, 0, sizeof(buffer));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 	if (count > sizeof(buffer) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 		count = sizeof(buffer) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 	if (copy_from_user(buffer, buf, count)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 		err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 	err = kstrtoint(strstrip(buffer), 0, &oom_score_adj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 	if (oom_score_adj < OOM_SCORE_ADJ_MIN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 			oom_score_adj > OOM_SCORE_ADJ_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 	err = __set_oom_adj(file, oom_score_adj, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 	return err < 0 ? err : count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) static const struct file_operations proc_oom_score_adj_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 	.read		= oom_score_adj_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	.write		= oom_score_adj_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 	.llseek		= default_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) #ifdef CONFIG_AUDIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) #define TMPBUFLEN 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) static ssize_t proc_loginuid_read(struct file * file, char __user * buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 				  size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 	struct inode * inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 	struct task_struct *task = get_proc_task(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 	ssize_t length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 	char tmpbuf[TMPBUFLEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 	if (!task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 		return -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 	length = scnprintf(tmpbuf, TMPBUFLEN, "%u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 			   from_kuid(file->f_cred->user_ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 				     audit_get_loginuid(task)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 	put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 	return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) static ssize_t proc_loginuid_write(struct file * file, const char __user * buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 				   size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 	struct inode * inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 	uid_t loginuid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 	kuid_t kloginuid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 	int rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 	/* Don't let kthreads write their own loginuid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 	if (current->flags & PF_KTHREAD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 	if (current != pid_task(proc_pid(inode), PIDTYPE_PID)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 	if (*ppos != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 		/* No partial writes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 	rv = kstrtou32_from_user(buf, count, 10, &loginuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 	if (rv < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 		return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 	/* is userspace tring to explicitly UNSET the loginuid? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 	if (loginuid == AUDIT_UID_UNSET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 		kloginuid = INVALID_UID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 		kloginuid = make_kuid(file->f_cred->user_ns, loginuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 		if (!uid_valid(kloginuid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 	rv = audit_set_loginuid(kloginuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 	if (rv < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 		return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) static const struct file_operations proc_loginuid_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 	.read		= proc_loginuid_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 	.write		= proc_loginuid_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 	.llseek		= generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) static ssize_t proc_sessionid_read(struct file * file, char __user * buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 				  size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 	struct inode * inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 	struct task_struct *task = get_proc_task(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 	ssize_t length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 	char tmpbuf[TMPBUFLEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 	if (!task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 		return -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 	length = scnprintf(tmpbuf, TMPBUFLEN, "%u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 				audit_get_sessionid(task));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 	put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 	return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) static const struct file_operations proc_sessionid_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 	.read		= proc_sessionid_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 	.llseek		= generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) #ifdef CONFIG_FAULT_INJECTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) static ssize_t proc_fault_inject_read(struct file * file, char __user * buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 				      size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 	struct task_struct *task = get_proc_task(file_inode(file));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 	char buffer[PROC_NUMBUF];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 	size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 	int make_it_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 	if (!task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 		return -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 	make_it_fail = task->make_it_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 	put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	len = snprintf(buffer, sizeof(buffer), "%i\n", make_it_fail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 	return simple_read_from_buffer(buf, count, ppos, buffer, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) static ssize_t proc_fault_inject_write(struct file * file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 			const char __user * buf, size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 	struct task_struct *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 	char buffer[PROC_NUMBUF];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 	int make_it_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 	int rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 	if (!capable(CAP_SYS_RESOURCE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 	memset(buffer, 0, sizeof(buffer));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 	if (count > sizeof(buffer) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 		count = sizeof(buffer) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 	if (copy_from_user(buffer, buf, count))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 	rv = kstrtoint(strstrip(buffer), 0, &make_it_fail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 	if (rv < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 		return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 	if (make_it_fail < 0 || make_it_fail > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 	task = get_proc_task(file_inode(file));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 	if (!task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 		return -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 	task->make_it_fail = make_it_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 	put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) static const struct file_operations proc_fault_inject_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 	.read		= proc_fault_inject_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 	.write		= proc_fault_inject_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 	.llseek		= generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) static ssize_t proc_fail_nth_write(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 				   size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 	struct task_struct *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 	unsigned int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 	err = kstrtouint_from_user(buf, count, 0, &n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 	task = get_proc_task(file_inode(file));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 	if (!task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 		return -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 	task->fail_nth = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 	put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) static ssize_t proc_fail_nth_read(struct file *file, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 				  size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 	struct task_struct *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 	char numbuf[PROC_NUMBUF];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 	ssize_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 	task = get_proc_task(file_inode(file));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 	if (!task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 		return -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 	len = snprintf(numbuf, sizeof(numbuf), "%u\n", task->fail_nth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 	put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 	return simple_read_from_buffer(buf, count, ppos, numbuf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) static const struct file_operations proc_fail_nth_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 	.read		= proc_fail_nth_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 	.write		= proc_fail_nth_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) #ifdef CONFIG_SCHED_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436)  * Print out various scheduling related per-task fields:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) static int sched_show(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 	struct inode *inode = m->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 	struct pid_namespace *ns = proc_pid_ns(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 	struct task_struct *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 	p = get_proc_task(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 		return -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 	proc_sched_show_task(p, ns, m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 	put_task_struct(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) sched_write(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 	    size_t count, loff_t *offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 	struct inode *inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 	struct task_struct *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 	p = get_proc_task(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 		return -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 	proc_sched_set_task(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 	put_task_struct(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) static int sched_open(struct inode *inode, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 	return single_open(filp, sched_show, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) static const struct file_operations proc_pid_sched_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 	.open		= sched_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 	.read		= seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 	.write		= sched_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 	.llseek		= seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 	.release	= single_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) #ifdef CONFIG_SCHED_AUTOGROUP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488)  * Print out autogroup related information:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) static int sched_autogroup_show(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 	struct inode *inode = m->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 	struct task_struct *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 	p = get_proc_task(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 		return -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 	proc_sched_autogroup_show_task(p, m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 	put_task_struct(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) sched_autogroup_write(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 	    size_t count, loff_t *offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 	struct inode *inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 	struct task_struct *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 	char buffer[PROC_NUMBUF];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 	int nice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 	memset(buffer, 0, sizeof(buffer));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 	if (count > sizeof(buffer) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 		count = sizeof(buffer) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 	if (copy_from_user(buffer, buf, count))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 	err = kstrtoint(strstrip(buffer), 0, &nice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 	p = get_proc_task(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 		return -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 	err = proc_sched_autogroup_set_nice(p, nice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 		count = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 	put_task_struct(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) static int sched_autogroup_open(struct inode *inode, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 	ret = single_open(filp, sched_autogroup_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 	if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 		struct seq_file *m = filp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 		m->private = inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) static const struct file_operations proc_pid_sched_autogroup_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 	.open		= sched_autogroup_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 	.read		= seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 	.write		= sched_autogroup_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 	.llseek		= seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 	.release	= single_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) #endif /* CONFIG_SCHED_AUTOGROUP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) #ifdef CONFIG_TIME_NS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) static int timens_offsets_show(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 	struct task_struct *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 	p = get_proc_task(file_inode(m->file));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 		return -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 	proc_timens_show_offsets(p, m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 	put_task_struct(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) static ssize_t timens_offsets_write(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 				    size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 	struct inode *inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 	struct proc_timens_offset offsets[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 	char *kbuf = NULL, *pos, *next_line;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 	struct task_struct *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 	int ret, noffsets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 	/* Only allow < page size writes at the beginning of the file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 	if ((*ppos != 0) || (count >= PAGE_SIZE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 	/* Slurp in the user data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 	kbuf = memdup_user_nul(buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 	if (IS_ERR(kbuf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 		return PTR_ERR(kbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 	/* Parse the user data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 	ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 	noffsets = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 	for (pos = kbuf; pos; pos = next_line) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 		struct proc_timens_offset *off = &offsets[noffsets];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 		char clock[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 		int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 		/* Find the end of line and ensure we don't look past it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 		next_line = strchr(pos, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 		if (next_line) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 			*next_line = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 			next_line++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 			if (*next_line == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 				next_line = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 		err = sscanf(pos, "%9s %lld %lu", clock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 				&off->val.tv_sec, &off->val.tv_nsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 		if (err != 3 || off->val.tv_nsec >= NSEC_PER_SEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 		clock[sizeof(clock) - 1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 		if (strcmp(clock, "monotonic") == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 		    strcmp(clock, __stringify(CLOCK_MONOTONIC)) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 			off->clockid = CLOCK_MONOTONIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 		else if (strcmp(clock, "boottime") == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) 			 strcmp(clock, __stringify(CLOCK_BOOTTIME)) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 			off->clockid = CLOCK_BOOTTIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 		noffsets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 		if (noffsets == ARRAY_SIZE(offsets)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 			if (next_line)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 				count = next_line - kbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 	ret = -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 	p = get_proc_task(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 	ret = proc_timens_set_offset(file, p, offsets, noffsets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 	put_task_struct(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 	ret = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 	kfree(kbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) static int timens_offsets_open(struct inode *inode, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 	return single_open(filp, timens_offsets_show, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) static const struct file_operations proc_timens_offsets_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 	.open		= timens_offsets_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 	.read		= seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 	.write		= timens_offsets_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 	.llseek		= seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 	.release	= single_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) #endif /* CONFIG_TIME_NS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) static ssize_t comm_write(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 				size_t count, loff_t *offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 	struct inode *inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 	struct task_struct *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 	char buffer[TASK_COMM_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 	const size_t maxlen = sizeof(buffer) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 	memset(buffer, 0, sizeof(buffer));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 	if (copy_from_user(buffer, buf, count > maxlen ? maxlen : count))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 	p = get_proc_task(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 		return -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 	if (same_thread_group(current, p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 		set_task_comm(p, buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 		count = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 	put_task_struct(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) static int comm_show(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 	struct inode *inode = m->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 	struct task_struct *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 	p = get_proc_task(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 		return -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 	proc_task_name(m, p, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 	seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 	put_task_struct(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) static int comm_open(struct inode *inode, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 	return single_open(filp, comm_show, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) static const struct file_operations proc_pid_set_comm_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 	.open		= comm_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 	.read		= seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 	.write		= comm_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 	.llseek		= seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 	.release	= single_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) static int proc_exe_link(struct dentry *dentry, struct path *exe_path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 	struct task_struct *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 	struct file *exe_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 	task = get_proc_task(d_inode(dentry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 	if (!task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 	exe_file = get_task_exe_file(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 	put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 	if (exe_file) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 		*exe_path = exe_file->f_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 		path_get(&exe_file->f_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 		fput(exe_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) static const char *proc_pid_get_link(struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 				     struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 				     struct delayed_call *done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 	struct path path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 	int error = -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 	if (!dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 		return ERR_PTR(-ECHILD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 	/* Are we allowed to snoop on the tasks file descriptors? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 	if (!proc_fd_access_allowed(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 	error = PROC_I(inode)->op.proc_get_link(dentry, &path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 	error = nd_jump_link(&path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 	return ERR_PTR(error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) static int do_proc_readlink(struct path *path, char __user *buffer, int buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 	char *tmp = (char *)__get_free_page(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 	char *pathname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 	int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 	if (!tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 	pathname = d_path(path, tmp, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 	len = PTR_ERR(pathname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 	if (IS_ERR(pathname))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 	len = tmp + PAGE_SIZE - 1 - pathname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) 	if (len > buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 		len = buflen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 	if (copy_to_user(buffer, pathname, len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 		len = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) 	free_page((unsigned long)tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) static int proc_pid_readlink(struct dentry * dentry, char __user * buffer, int buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) 	int error = -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) 	struct inode *inode = d_inode(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) 	struct path path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) 	/* Are we allowed to snoop on the tasks file descriptors? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 	if (!proc_fd_access_allowed(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) 	error = PROC_I(inode)->op.proc_get_link(dentry, &path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) 	error = do_proc_readlink(&path, buffer, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) 	path_put(&path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) const struct inode_operations proc_pid_link_inode_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) 	.readlink	= proc_pid_readlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) 	.get_link	= proc_pid_get_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 	.setattr	= proc_setattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) /* building an inode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) void task_dump_owner(struct task_struct *task, umode_t mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 		     kuid_t *ruid, kgid_t *rgid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 	/* Depending on the state of dumpable compute who should own a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) 	 * proc file for a task.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) 	const struct cred *cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) 	kuid_t uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) 	kgid_t gid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 	if (unlikely(task->flags & PF_KTHREAD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 		*ruid = GLOBAL_ROOT_UID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) 		*rgid = GLOBAL_ROOT_GID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 	/* Default to the tasks effective ownership */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) 	cred = __task_cred(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) 	uid = cred->euid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) 	gid = cred->egid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) 	 * Before the /proc/pid/status file was created the only way to read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) 	 * the effective uid of a /process was to stat /proc/pid.  Reading
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) 	 * /proc/pid/status is slow enough that procps and other packages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) 	 * kept stating /proc/pid.  To keep the rules in /proc simple I have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) 	 * made this apply to all per process world readable and executable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 	 * directories.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) 	if (mode != (S_IFDIR|S_IRUGO|S_IXUGO)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 		struct mm_struct *mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) 		task_lock(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) 		mm = task->mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 		/* Make non-dumpable tasks owned by some root */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) 		if (mm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) 			if (get_dumpable(mm) != SUID_DUMP_USER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 				struct user_namespace *user_ns = mm->user_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 				uid = make_kuid(user_ns, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) 				if (!uid_valid(uid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 					uid = GLOBAL_ROOT_UID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) 				gid = make_kgid(user_ns, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) 				if (!gid_valid(gid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 					gid = GLOBAL_ROOT_GID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 			uid = GLOBAL_ROOT_UID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 			gid = GLOBAL_ROOT_GID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 		task_unlock(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) 	*ruid = uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) 	*rgid = gid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) void proc_pid_evict_inode(struct proc_inode *ei)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) 	struct pid *pid = ei->pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) 	if (S_ISDIR(ei->vfs_inode.i_mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) 		spin_lock(&pid->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) 		hlist_del_init_rcu(&ei->sibling_inodes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) 		spin_unlock(&pid->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) 	put_pid(pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) struct inode *proc_pid_make_inode(struct super_block * sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) 				  struct task_struct *task, umode_t mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) 	struct inode * inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) 	struct proc_inode *ei;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) 	struct pid *pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 	/* We need a new inode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) 	inode = new_inode(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 	if (!inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) 	/* Common stuff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) 	ei = PROC_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) 	inode->i_mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 	inode->i_ino = get_next_ino();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 	inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) 	inode->i_op = &proc_def_inode_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) 	 * grab the reference to task.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) 	pid = get_task_pid(task, PIDTYPE_PID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) 	if (!pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) 		goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) 	/* Let the pid remember us for quick removal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 	ei->pid = pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) 	if (S_ISDIR(mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) 		spin_lock(&pid->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 		hlist_add_head_rcu(&ei->sibling_inodes, &pid->inodes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) 		spin_unlock(&pid->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 	task_dump_owner(task, 0, &inode->i_uid, &inode->i_gid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) 	security_task_to_inode(task, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) 	return inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) 	iput(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) int pid_getattr(const struct path *path, struct kstat *stat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 		u32 request_mask, unsigned int query_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) 	struct inode *inode = d_inode(path->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) 	struct proc_fs_info *fs_info = proc_sb_info(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) 	struct task_struct *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 	generic_fillattr(inode, stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 	stat->uid = GLOBAL_ROOT_UID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 	stat->gid = GLOBAL_ROOT_GID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) 	task = pid_task(proc_pid(inode), PIDTYPE_PID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) 	if (task) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) 		if (!has_pid_permissions(fs_info, task, HIDEPID_INVISIBLE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) 			rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) 			 * This doesn't prevent learning whether PID exists,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) 			 * it only makes getattr() consistent with readdir().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) 			return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) 		task_dump_owner(task, inode->i_mode, &stat->uid, &stat->gid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) /* dentry stuff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962)  * Set <pid>/... inode ownership (can change due to setuid(), etc.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) void pid_update_inode(struct task_struct *task, struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) 	task_dump_owner(task, inode->i_mode, &inode->i_uid, &inode->i_gid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) 	inode->i_mode &= ~(S_ISUID | S_ISGID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) 	security_task_to_inode(task, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973)  * Rewrite the inode's ownerships here because the owning task may have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974)  * performed a setuid(), etc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) static int pid_revalidate(struct dentry *dentry, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) 	struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) 	struct task_struct *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) 	if (flags & LOOKUP_RCU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) 		return -ECHILD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) 	inode = d_inode(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) 	task = get_proc_task(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) 	if (task) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) 		pid_update_inode(task, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) 		put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) static inline bool proc_inode_is_dead(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) 	return !proc_pid(inode)->tasks[PIDTYPE_PID].first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) int pid_delete_dentry(const struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) 	/* Is the task we represent dead?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) 	 * If so, then don't put the dentry on the lru list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) 	 * kill it immediately.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) 	return proc_inode_is_dead(d_inode(dentry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) const struct dentry_operations pid_dentry_operations =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) 	.d_revalidate	= pid_revalidate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) 	.d_delete	= pid_delete_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) /* Lookups */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019)  * Fill a directory entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021)  * If possible create the dcache entry and derive our inode number and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022)  * file type from dcache entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024)  * Since all of the proc inode numbers are dynamically generated, the inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025)  * numbers do not exist until the inode is cache.  This means creating the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026)  * the dcache entry in readdir is necessary to keep the inode numbers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027)  * reported by readdir in sync with the inode numbers reported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028)  * by stat.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) bool proc_fill_cache(struct file *file, struct dir_context *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) 	const char *name, unsigned int len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) 	instantiate_t instantiate, struct task_struct *task, const void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) 	struct dentry *child, *dir = file->f_path.dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) 	struct qstr qname = QSTR_INIT(name, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) 	struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) 	unsigned type = DT_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) 	ino_t ino = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) 	child = d_hash_and_lookup(dir, &qname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) 	if (!child) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) 		DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) 		child = d_alloc_parallel(dir, &qname, &wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) 		if (IS_ERR(child))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) 			goto end_instantiate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) 		if (d_in_lookup(child)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) 			struct dentry *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) 			res = instantiate(child, task, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) 			d_lookup_done(child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) 			if (unlikely(res)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) 				dput(child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) 				child = res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) 				if (IS_ERR(child))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) 					goto end_instantiate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) 	inode = d_inode(child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) 	ino = inode->i_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) 	type = inode->i_mode >> 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) 	dput(child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) end_instantiate:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) 	return dir_emit(ctx, name, len, ino, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067)  * dname_to_vma_addr - maps a dentry name into two unsigned longs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068)  * which represent vma start and end addresses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) static int dname_to_vma_addr(struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) 			     unsigned long *start, unsigned long *end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) 	const char *str = dentry->d_name.name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) 	unsigned long long sval, eval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) 	unsigned int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) 	if (str[0] == '0' && str[1] != '-')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) 	len = _parse_integer(str, 16, &sval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) 	if (len & KSTRTOX_OVERFLOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) 	if (sval != (unsigned long)sval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) 	str += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) 	if (*str != '-')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) 	str++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) 	if (str[0] == '0' && str[1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) 	len = _parse_integer(str, 16, &eval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) 	if (len & KSTRTOX_OVERFLOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) 	if (eval != (unsigned long)eval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) 	str += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) 	if (*str != '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) 	*start = sval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) 	*end = eval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) static int map_files_d_revalidate(struct dentry *dentry, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) 	unsigned long vm_start, vm_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) 	bool exact_vma_exists = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) 	struct mm_struct *mm = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) 	struct task_struct *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) 	struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) 	int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) 	if (flags & LOOKUP_RCU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) 		return -ECHILD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) 	inode = d_inode(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) 	task = get_proc_task(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) 	if (!task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) 		goto out_notask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) 	mm = mm_access(task, PTRACE_MODE_READ_FSCREDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) 	if (IS_ERR_OR_NULL(mm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) 	if (!dname_to_vma_addr(dentry, &vm_start, &vm_end)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) 		status = mmap_read_lock_killable(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) 		if (!status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) 			exact_vma_exists = !!find_exact_vma(mm, vm_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) 							    vm_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) 			mmap_read_unlock(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) 	mmput(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) 	if (exact_vma_exists) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) 		task_dump_owner(task, 0, &inode->i_uid, &inode->i_gid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) 		security_task_to_inode(task, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) 		status = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) 	put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) out_notask:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) static const struct dentry_operations tid_map_files_dentry_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) 	.d_revalidate	= map_files_d_revalidate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) 	.d_delete	= pid_delete_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) static int map_files_get_link(struct dentry *dentry, struct path *path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) 	unsigned long vm_start, vm_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) 	struct vm_area_struct *vma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) 	struct task_struct *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) 	struct mm_struct *mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) 	rc = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) 	task = get_proc_task(d_inode(dentry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) 	if (!task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) 	mm = get_task_mm(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) 	put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) 	if (!mm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) 	rc = dname_to_vma_addr(dentry, &vm_start, &vm_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) 		goto out_mmput;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) 	rc = mmap_read_lock_killable(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) 		goto out_mmput;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) 	rc = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) 	vma = find_exact_vma(mm, vm_start, vm_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) 	if (vma && vma->vm_file) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) 		*path = vma->vm_file->f_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) 		path_get(path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) 		rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) 	mmap_read_unlock(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) out_mmput:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) 	mmput(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) struct map_files_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) 	unsigned long	start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) 	unsigned long	end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) 	fmode_t		mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207)  * Only allow CAP_SYS_ADMIN and CAP_CHECKPOINT_RESTORE to follow the links, due
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208)  * to concerns about how the symlinks may be used to bypass permissions on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209)  * ancestor directories in the path to the file in question.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) static const char *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) proc_map_files_get_link(struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) 			struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) 		        struct delayed_call *done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) 	if (!checkpoint_restore_ns_capable(&init_user_ns))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) 		return ERR_PTR(-EPERM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) 	return proc_pid_get_link(dentry, inode, done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223)  * Identical to proc_pid_link_inode_operations except for get_link()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) static const struct inode_operations proc_map_files_link_inode_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) 	.readlink	= proc_pid_readlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) 	.get_link	= proc_map_files_get_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) 	.setattr	= proc_setattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) static struct dentry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) proc_map_files_instantiate(struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) 			   struct task_struct *task, const void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) 	fmode_t mode = (fmode_t)(unsigned long)ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) 	struct proc_inode *ei;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) 	struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) 	inode = proc_pid_make_inode(dentry->d_sb, task, S_IFLNK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) 				    ((mode & FMODE_READ ) ? S_IRUSR : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) 				    ((mode & FMODE_WRITE) ? S_IWUSR : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) 	if (!inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) 		return ERR_PTR(-ENOENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) 	ei = PROC_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) 	ei->op.proc_get_link = map_files_get_link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) 	inode->i_op = &proc_map_files_link_inode_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) 	inode->i_size = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) 	d_set_d_op(dentry, &tid_map_files_dentry_operations);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) 	return d_splice_alias(inode, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) static struct dentry *proc_map_files_lookup(struct inode *dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) 		struct dentry *dentry, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) 	unsigned long vm_start, vm_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) 	struct vm_area_struct *vma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) 	struct task_struct *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) 	struct dentry *result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) 	struct mm_struct *mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) 	result = ERR_PTR(-ENOENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) 	task = get_proc_task(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) 	if (!task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) 	result = ERR_PTR(-EACCES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) 	if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) 		goto out_put_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) 	result = ERR_PTR(-ENOENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) 	if (dname_to_vma_addr(dentry, &vm_start, &vm_end))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) 		goto out_put_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) 	mm = get_task_mm(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) 	if (!mm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) 		goto out_put_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) 	result = ERR_PTR(-EINTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) 	if (mmap_read_lock_killable(mm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) 		goto out_put_mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) 	result = ERR_PTR(-ENOENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) 	vma = find_exact_vma(mm, vm_start, vm_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) 	if (!vma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) 		goto out_no_vma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) 	if (vma->vm_file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) 		result = proc_map_files_instantiate(dentry, task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) 				(void *)(unsigned long)vma->vm_file->f_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) out_no_vma:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) 	mmap_read_unlock(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) out_put_mm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) 	mmput(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) out_put_task:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) 	put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) static const struct inode_operations proc_map_files_inode_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) 	.lookup		= proc_map_files_lookup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) 	.permission	= proc_fd_permission,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) 	.setattr	= proc_setattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) proc_map_files_readdir(struct file *file, struct dir_context *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) 	struct vm_area_struct *vma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) 	struct task_struct *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) 	struct mm_struct *mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) 	unsigned long nr_files, pos, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) 	GENRADIX(struct map_files_info) fa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) 	struct map_files_info *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) 	genradix_init(&fa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) 	ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) 	task = get_proc_task(file_inode(file));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) 	if (!task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) 	ret = -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) 	if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) 		goto out_put_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) 	ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) 	if (!dir_emit_dots(file, ctx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) 		goto out_put_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) 	mm = get_task_mm(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) 	if (!mm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) 		goto out_put_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) 	ret = mmap_read_lock_killable(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) 		mmput(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) 		goto out_put_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) 	nr_files = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) 	 * We need two passes here:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) 	 *  1) Collect vmas of mapped files with mmap_lock taken
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) 	 *  2) Release mmap_lock and instantiate entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) 	 * otherwise we get lockdep complained, since filldir()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) 	 * routine might require mmap_lock taken in might_fault().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) 	for (vma = mm->mmap, pos = 2; vma; vma = vma->vm_next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) 		if (!vma->vm_file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) 		if (++pos <= ctx->pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) 		p = genradix_ptr_alloc(&fa, nr_files++, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) 		if (!p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) 			ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) 			mmap_read_unlock(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) 			mmput(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) 			goto out_put_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) 		p->start = vma->vm_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) 		p->end = vma->vm_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) 		p->mode = vma->vm_file->f_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) 	mmap_read_unlock(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) 	mmput(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) 	for (i = 0; i < nr_files; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) 		char buf[4 * sizeof(long) + 2];	/* max: %lx-%lx\0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) 		unsigned int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) 		p = genradix_ptr(&fa, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) 		len = snprintf(buf, sizeof(buf), "%lx-%lx", p->start, p->end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) 		if (!proc_fill_cache(file, ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) 				      buf, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) 				      proc_map_files_instantiate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) 				      task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) 				      (void *)(unsigned long)p->mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) 		ctx->pos++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) out_put_task:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) 	put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) 	genradix_free(&fa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) static const struct file_operations proc_map_files_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) 	.read		= generic_read_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) 	.iterate_shared	= proc_map_files_readdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) 	.llseek		= generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) #if defined(CONFIG_CHECKPOINT_RESTORE) && defined(CONFIG_POSIX_TIMERS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) struct timers_private {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) 	struct pid *pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) 	struct task_struct *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) 	struct sighand_struct *sighand;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) 	struct pid_namespace *ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) static void *timers_start(struct seq_file *m, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) 	struct timers_private *tp = m->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) 	tp->task = get_pid_task(tp->pid, PIDTYPE_PID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) 	if (!tp->task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) 		return ERR_PTR(-ESRCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) 	tp->sighand = lock_task_sighand(tp->task, &tp->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) 	if (!tp->sighand)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) 		return ERR_PTR(-ESRCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) 	return seq_list_start(&tp->task->signal->posix_timers, *pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) static void *timers_next(struct seq_file *m, void *v, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) 	struct timers_private *tp = m->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) 	return seq_list_next(v, &tp->task->signal->posix_timers, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) static void timers_stop(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) 	struct timers_private *tp = m->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) 	if (tp->sighand) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) 		unlock_task_sighand(tp->task, &tp->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) 		tp->sighand = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) 	if (tp->task) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) 		put_task_struct(tp->task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) 		tp->task = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) static int show_timer(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) 	struct k_itimer *timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) 	struct timers_private *tp = m->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) 	int notify;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) 	static const char * const nstr[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) 		[SIGEV_SIGNAL] = "signal",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) 		[SIGEV_NONE] = "none",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) 		[SIGEV_THREAD] = "thread",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) 	timer = list_entry((struct list_head *)v, struct k_itimer, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) 	notify = timer->it_sigev_notify;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) 	seq_printf(m, "ID: %d\n", timer->it_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) 	seq_printf(m, "signal: %d/%px\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) 		   timer->sigq->info.si_signo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) 		   timer->sigq->info.si_value.sival_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) 	seq_printf(m, "notify: %s/%s.%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) 		   nstr[notify & ~SIGEV_THREAD_ID],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) 		   (notify & SIGEV_THREAD_ID) ? "tid" : "pid",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) 		   pid_nr_ns(timer->it_pid, tp->ns));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) 	seq_printf(m, "ClockID: %d\n", timer->it_clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) static const struct seq_operations proc_timers_seq_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) 	.start	= timers_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) 	.next	= timers_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) 	.stop	= timers_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) 	.show	= show_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) static int proc_timers_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) 	struct timers_private *tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) 	tp = __seq_open_private(file, &proc_timers_seq_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) 			sizeof(struct timers_private));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) 	if (!tp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) 	tp->pid = proc_pid(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) 	tp->ns = proc_pid_ns(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) static const struct file_operations proc_timers_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) 	.open		= proc_timers_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) 	.read		= seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) 	.llseek		= seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) 	.release	= seq_release_private,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) static ssize_t timerslack_ns_write(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) 					size_t count, loff_t *offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) 	struct inode *inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) 	struct task_struct *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) 	u64 slack_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) 	err = kstrtoull_from_user(buf, count, 10, &slack_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) 	p = get_proc_task(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) 		return -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) 	if (p != current) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) 		rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) 		if (!ns_capable(__task_cred(p)->user_ns, CAP_SYS_NICE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) 			rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) 			count = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) 		err = security_task_setscheduler(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) 			count = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) 	task_lock(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) 	if (slack_ns == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) 		p->timer_slack_ns = p->default_timer_slack_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) 		p->timer_slack_ns = slack_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) 	task_unlock(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) 	put_task_struct(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) static int timerslack_ns_show(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) 	struct inode *inode = m->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) 	struct task_struct *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) 	p = get_proc_task(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) 		return -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) 	if (p != current) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) 		rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) 		if (!ns_capable(__task_cred(p)->user_ns, CAP_SYS_NICE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) 			rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) 			err = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) 		err = security_task_getscheduler(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) 	task_lock(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) 	seq_printf(m, "%llu\n", p->timer_slack_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) 	task_unlock(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) 	put_task_struct(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) static int timerslack_ns_open(struct inode *inode, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) 	return single_open(filp, timerslack_ns_show, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) static const struct file_operations proc_pid_set_timerslack_ns_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) 	.open		= timerslack_ns_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) 	.read		= seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) 	.write		= timerslack_ns_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) 	.llseek		= seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) 	.release	= single_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) static struct dentry *proc_pident_instantiate(struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) 	struct task_struct *task, const void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) 	const struct pid_entry *p = ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) 	struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) 	struct proc_inode *ei;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) 	inode = proc_pid_make_inode(dentry->d_sb, task, p->mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) 	if (!inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) 		return ERR_PTR(-ENOENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) 	ei = PROC_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) 	if (S_ISDIR(inode->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) 		set_nlink(inode, 2);	/* Use getattr to fix if necessary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) 	if (p->iop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) 		inode->i_op = p->iop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) 	if (p->fop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) 		inode->i_fop = p->fop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) 	ei->op = p->op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) 	pid_update_inode(task, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) 	d_set_d_op(dentry, &pid_dentry_operations);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) 	return d_splice_alias(inode, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) static struct dentry *proc_pident_lookup(struct inode *dir, 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) 					 struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) 					 const struct pid_entry *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) 					 const struct pid_entry *end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) 	struct task_struct *task = get_proc_task(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) 	struct dentry *res = ERR_PTR(-ENOENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) 	if (!task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) 		goto out_no_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) 	 * Yes, it does not scale. And it should not. Don't add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) 	 * new entries into /proc/<tgid>/ without very good reasons.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) 	for (; p < end; p++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) 		if (p->len != dentry->d_name.len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) 		if (!memcmp(dentry->d_name.name, p->name, p->len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) 			res = proc_pident_instantiate(dentry, task, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) 	put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) out_no_task:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) 	return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) static int proc_pident_readdir(struct file *file, struct dir_context *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) 		const struct pid_entry *ents, unsigned int nents)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) 	struct task_struct *task = get_proc_task(file_inode(file));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) 	const struct pid_entry *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) 	if (!task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) 	if (!dir_emit_dots(file, ctx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) 	if (ctx->pos >= nents + 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) 	for (p = ents + (ctx->pos - 2); p < ents + nents; p++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) 		if (!proc_fill_cache(file, ctx, p->name, p->len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) 				proc_pident_instantiate, task, p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) 		ctx->pos++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) 	put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) #ifdef CONFIG_SECURITY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) static int proc_pid_attr_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) 	file->private_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) 	__mem_open(inode, file, PTRACE_MODE_READ_FSCREDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) static ssize_t proc_pid_attr_read(struct file * file, char __user * buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) 				  size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) 	struct inode * inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) 	char *p = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) 	ssize_t length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) 	struct task_struct *task = get_proc_task(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) 	if (!task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) 		return -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) 	length = security_getprocattr(task, PROC_I(inode)->op.lsm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) 				      (char*)file->f_path.dentry->d_name.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) 				      &p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) 	put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) 	if (length > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) 		length = simple_read_from_buffer(buf, count, ppos, p, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) 	kfree(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) 	return length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) 				   size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) 	struct inode * inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) 	struct task_struct *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) 	void *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) 	int rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) 	/* A task may only write when it was the opener. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) 	if (file->private_data != current->mm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) 	task = pid_task(proc_pid(inode), PIDTYPE_PID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) 	if (!task) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) 		return -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) 	/* A task may only write its own attributes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) 	if (current != task) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) 		return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) 	/* Prevent changes to overridden credentials. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) 	if (current_cred() != current_real_cred()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) 	if (count > PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) 		count = PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) 	/* No partial writes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) 	if (*ppos != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) 	page = memdup_user(buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) 	if (IS_ERR(page)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) 		rv = PTR_ERR(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) 	/* Guard against adverse ptrace interaction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) 	rv = mutex_lock_interruptible(&current->signal->cred_guard_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) 	if (rv < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) 	rv = security_setprocattr(PROC_I(inode)->op.lsm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) 				  file->f_path.dentry->d_name.name, page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) 				  count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) 	mutex_unlock(&current->signal->cred_guard_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) 	kfree(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) 	return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) static const struct file_operations proc_pid_attr_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) 	.open		= proc_pid_attr_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) 	.read		= proc_pid_attr_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) 	.write		= proc_pid_attr_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) 	.llseek		= generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) 	.release	= mem_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) #define LSM_DIR_OPS(LSM) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) static int proc_##LSM##_attr_dir_iterate(struct file *filp, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) 			     struct dir_context *ctx) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) 	return proc_pident_readdir(filp, ctx, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) 				   LSM##_attr_dir_stuff, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) 				   ARRAY_SIZE(LSM##_attr_dir_stuff)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) static const struct file_operations proc_##LSM##_attr_dir_ops = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) 	.read		= generic_read_dir, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) 	.iterate	= proc_##LSM##_attr_dir_iterate, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) 	.llseek		= default_llseek, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) }; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) static struct dentry *proc_##LSM##_attr_dir_lookup(struct inode *dir, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) 				struct dentry *dentry, unsigned int flags) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) 	return proc_pident_lookup(dir, dentry, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) 				  LSM##_attr_dir_stuff, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) 				  LSM##_attr_dir_stuff + ARRAY_SIZE(LSM##_attr_dir_stuff)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) static const struct inode_operations proc_##LSM##_attr_dir_inode_ops = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) 	.lookup		= proc_##LSM##_attr_dir_lookup, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) 	.getattr	= pid_getattr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) 	.setattr	= proc_setattr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) #ifdef CONFIG_SECURITY_SMACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) static const struct pid_entry smack_attr_dir_stuff[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) 	ATTR("smack", "current",	0666),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) LSM_DIR_OPS(smack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) #ifdef CONFIG_SECURITY_APPARMOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) static const struct pid_entry apparmor_attr_dir_stuff[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) 	ATTR("apparmor", "current",	0666),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) 	ATTR("apparmor", "prev",	0444),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) 	ATTR("apparmor", "exec",	0666),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) LSM_DIR_OPS(apparmor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) static const struct pid_entry attr_dir_stuff[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) 	ATTR(NULL, "current",		0666),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) 	ATTR(NULL, "prev",		0444),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) 	ATTR(NULL, "exec",		0666),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) 	ATTR(NULL, "fscreate",		0666),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) 	ATTR(NULL, "keycreate",		0666),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) 	ATTR(NULL, "sockcreate",	0666),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) #ifdef CONFIG_SECURITY_SMACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) 	DIR("smack",			0555,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) 	    proc_smack_attr_dir_inode_ops, proc_smack_attr_dir_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) #ifdef CONFIG_SECURITY_APPARMOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) 	DIR("apparmor",			0555,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) 	    proc_apparmor_attr_dir_inode_ops, proc_apparmor_attr_dir_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) static int proc_attr_dir_readdir(struct file *file, struct dir_context *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) 	return proc_pident_readdir(file, ctx, 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) 				   attr_dir_stuff, ARRAY_SIZE(attr_dir_stuff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) static const struct file_operations proc_attr_dir_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) 	.read		= generic_read_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) 	.iterate_shared	= proc_attr_dir_readdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) 	.llseek		= generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) static struct dentry *proc_attr_dir_lookup(struct inode *dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) 				struct dentry *dentry, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) 	return proc_pident_lookup(dir, dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) 				  attr_dir_stuff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) 				  attr_dir_stuff + ARRAY_SIZE(attr_dir_stuff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) static const struct inode_operations proc_attr_dir_inode_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) 	.lookup		= proc_attr_dir_lookup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) 	.getattr	= pid_getattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) 	.setattr	= proc_setattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) #ifdef CONFIG_ELF_CORE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) static ssize_t proc_coredump_filter_read(struct file *file, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) 					 size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) 	struct task_struct *task = get_proc_task(file_inode(file));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) 	struct mm_struct *mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) 	char buffer[PROC_NUMBUF];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) 	size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) 	if (!task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) 		return -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) 	ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) 	mm = get_task_mm(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) 	if (mm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) 		len = snprintf(buffer, sizeof(buffer), "%08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) 			       ((mm->flags & MMF_DUMP_FILTER_MASK) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) 				MMF_DUMP_FILTER_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) 		mmput(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) 		ret = simple_read_from_buffer(buf, count, ppos, buffer, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) 	put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) static ssize_t proc_coredump_filter_write(struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) 					  const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) 					  size_t count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) 					  loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) 	struct task_struct *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) 	struct mm_struct *mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) 	unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) 	unsigned long mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) 	ret = kstrtouint_from_user(buf, count, 0, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) 	ret = -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) 	task = get_proc_task(file_inode(file));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) 	if (!task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) 		goto out_no_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) 	mm = get_task_mm(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) 	if (!mm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) 		goto out_no_mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) 	ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) 	for (i = 0, mask = 1; i < MMF_DUMP_FILTER_BITS; i++, mask <<= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) 		if (val & mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) 			set_bit(i + MMF_DUMP_FILTER_SHIFT, &mm->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) 			clear_bit(i + MMF_DUMP_FILTER_SHIFT, &mm->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) 	mmput(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925)  out_no_mm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) 	put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927)  out_no_task:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) static const struct file_operations proc_coredump_filter_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) 	.read		= proc_coredump_filter_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) 	.write		= proc_coredump_filter_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) 	.llseek		= generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) #ifdef CONFIG_TASK_IO_ACCOUNTING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) static int do_io_accounting(struct task_struct *task, struct seq_file *m, int whole)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) 	struct task_io_accounting acct = task->ioac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) 	int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) 	result = down_read_killable(&task->signal->exec_update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) 	if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) 		return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) 	if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) 		result = -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) 		goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) 	if (whole && lock_task_sighand(task, &flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) 		struct task_struct *t = task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) 		task_io_accounting_add(&acct, &task->signal->ioac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) 		while_each_thread(task, t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) 			task_io_accounting_add(&acct, &t->ioac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) 		unlock_task_sighand(task, &flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) 	seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) 		   "rchar: %llu\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) 		   "wchar: %llu\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) 		   "syscr: %llu\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) 		   "syscw: %llu\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) 		   "read_bytes: %llu\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) 		   "write_bytes: %llu\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) 		   "cancelled_write_bytes: %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) 		   (unsigned long long)acct.rchar,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) 		   (unsigned long long)acct.wchar,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) 		   (unsigned long long)acct.syscr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) 		   (unsigned long long)acct.syscw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) 		   (unsigned long long)acct.read_bytes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) 		   (unsigned long long)acct.write_bytes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) 		   (unsigned long long)acct.cancelled_write_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) 	result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) 	up_read(&task->signal->exec_update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) static int proc_tid_io_accounting(struct seq_file *m, struct pid_namespace *ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) 				  struct pid *pid, struct task_struct *task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) 	return do_io_accounting(task, m, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) static int proc_tgid_io_accounting(struct seq_file *m, struct pid_namespace *ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) 				   struct pid *pid, struct task_struct *task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) 	return do_io_accounting(task, m, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) #endif /* CONFIG_TASK_IO_ACCOUNTING */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) #ifdef CONFIG_USER_NS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) static int proc_id_map_open(struct inode *inode, struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) 	const struct seq_operations *seq_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) 	struct user_namespace *ns = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) 	struct task_struct *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) 	struct seq_file *seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) 	int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) 	task = get_proc_task(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) 	if (task) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) 		rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) 		ns = get_user_ns(task_cred_xxx(task, user_ns));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) 		put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) 	if (!ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) 	ret = seq_open(file, seq_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) 		goto err_put_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) 	seq = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) 	seq->private = ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) err_put_ns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) 	put_user_ns(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) static int proc_id_map_release(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) 	struct seq_file *seq = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) 	struct user_namespace *ns = seq->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) 	put_user_ns(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) 	return seq_release(inode, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) static int proc_uid_map_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) 	return proc_id_map_open(inode, file, &proc_uid_seq_operations);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) static int proc_gid_map_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) 	return proc_id_map_open(inode, file, &proc_gid_seq_operations);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) static int proc_projid_map_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) 	return proc_id_map_open(inode, file, &proc_projid_seq_operations);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) static const struct file_operations proc_uid_map_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) 	.open		= proc_uid_map_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) 	.write		= proc_uid_map_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) 	.read		= seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) 	.llseek		= seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) 	.release	= proc_id_map_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) static const struct file_operations proc_gid_map_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) 	.open		= proc_gid_map_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) 	.write		= proc_gid_map_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) 	.read		= seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) 	.llseek		= seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) 	.release	= proc_id_map_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) static const struct file_operations proc_projid_map_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) 	.open		= proc_projid_map_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) 	.write		= proc_projid_map_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) 	.read		= seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) 	.llseek		= seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) 	.release	= proc_id_map_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) static int proc_setgroups_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) 	struct user_namespace *ns = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) 	struct task_struct *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) 	ret = -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) 	task = get_proc_task(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) 	if (task) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) 		rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) 		ns = get_user_ns(task_cred_xxx(task, user_ns));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) 		put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) 	if (!ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) 	if (file->f_mode & FMODE_WRITE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) 		ret = -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) 		if (!ns_capable(ns, CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) 			goto err_put_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) 	ret = single_open(file, &proc_setgroups_show, ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) 		goto err_put_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) err_put_ns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) 	put_user_ns(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) static int proc_setgroups_release(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) 	struct seq_file *seq = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) 	struct user_namespace *ns = seq->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) 	int ret = single_release(inode, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) 	put_user_ns(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) static const struct file_operations proc_setgroups_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) 	.open		= proc_setgroups_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) 	.write		= proc_setgroups_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) 	.read		= seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) 	.llseek		= seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) 	.release	= proc_setgroups_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) #endif /* CONFIG_USER_NS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) static int proc_pid_personality(struct seq_file *m, struct pid_namespace *ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) 				struct pid *pid, struct task_struct *task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) 	int err = lock_trace(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) 	if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) 		seq_printf(m, "%08x\n", task->personality);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) 		unlock_trace(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) #ifdef CONFIG_LIVEPATCH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) static int proc_pid_patch_state(struct seq_file *m, struct pid_namespace *ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) 				struct pid *pid, struct task_struct *task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) 	seq_printf(m, "%d\n", task->patch_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) #endif /* CONFIG_LIVEPATCH */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) #ifdef CONFIG_STACKLEAK_METRICS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) static int proc_stack_depth(struct seq_file *m, struct pid_namespace *ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) 				struct pid *pid, struct task_struct *task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) 	unsigned long prev_depth = THREAD_SIZE -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) 				(task->prev_lowest_stack & (THREAD_SIZE - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) 	unsigned long depth = THREAD_SIZE -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) 				(task->lowest_stack & (THREAD_SIZE - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) 	seq_printf(m, "previous stack depth: %lu\nstack depth: %lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) 							prev_depth, depth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) #endif /* CONFIG_STACKLEAK_METRICS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168)  * Thread groups
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) static const struct file_operations proc_task_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) static const struct inode_operations proc_task_inode_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) static const struct pid_entry tgid_base_stuff[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) 	DIR("task",       S_IRUGO|S_IXUGO, proc_task_inode_operations, proc_task_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) 	DIR("fd",         S_IRUSR|S_IXUSR, proc_fd_inode_operations, proc_fd_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) 	DIR("map_files",  S_IRUSR|S_IXUSR, proc_map_files_inode_operations, proc_map_files_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) 	DIR("fdinfo",     S_IRUGO|S_IXUGO, proc_fdinfo_inode_operations, proc_fdinfo_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) 	DIR("ns",	  S_IRUSR|S_IXUGO, proc_ns_dir_inode_operations, proc_ns_dir_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) #ifdef CONFIG_NET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) 	DIR("net",        S_IRUGO|S_IXUGO, proc_net_inode_operations, proc_net_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) 	REG("environ",    S_IRUSR, proc_environ_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) 	REG("auxv",       S_IRUSR, proc_auxv_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) 	ONE("status",     S_IRUGO, proc_pid_status),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) 	ONE("personality", S_IRUSR, proc_pid_personality),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) 	ONE("limits",	  S_IRUGO, proc_pid_limits),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) #ifdef CONFIG_SCHED_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) 	REG("sched",      S_IRUGO|S_IWUSR, proc_pid_sched_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) #ifdef CONFIG_SCHED_AUTOGROUP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) 	REG("autogroup",  S_IRUGO|S_IWUSR, proc_pid_sched_autogroup_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) #ifdef CONFIG_TIME_NS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) 	REG("timens_offsets",  S_IRUGO|S_IWUSR, proc_timens_offsets_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) 	REG("comm",      S_IRUGO|S_IWUSR, proc_pid_set_comm_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) #ifdef CONFIG_HAVE_ARCH_TRACEHOOK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) 	ONE("syscall",    S_IRUSR, proc_pid_syscall),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) 	REG("cmdline",    S_IRUGO, proc_pid_cmdline_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) 	ONE("stat",       S_IRUGO, proc_tgid_stat),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) 	ONE("statm",      S_IRUGO, proc_pid_statm),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) 	REG("maps",       S_IRUGO, proc_pid_maps_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) #ifdef CONFIG_NUMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) 	REG("numa_maps",  S_IRUGO, proc_pid_numa_maps_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) 	REG("mem",        S_IRUSR|S_IWUSR, proc_mem_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) 	LNK("cwd",        proc_cwd_link),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) 	LNK("root",       proc_root_link),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) 	LNK("exe",        proc_exe_link),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) 	REG("mounts",     S_IRUGO, proc_mounts_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) 	REG("mountinfo",  S_IRUGO, proc_mountinfo_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) 	REG("mountstats", S_IRUSR, proc_mountstats_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) #ifdef CONFIG_PROC_PAGE_MONITOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) 	REG("clear_refs", S_IWUSR, proc_clear_refs_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) 	REG("smaps",      S_IRUGO, proc_pid_smaps_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) 	REG("smaps_rollup", S_IRUGO, proc_pid_smaps_rollup_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) 	REG("pagemap",    S_IRUSR, proc_pagemap_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) #ifdef CONFIG_SECURITY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) 	DIR("attr",       S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) #ifdef CONFIG_KALLSYMS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) 	ONE("wchan",      S_IRUGO, proc_pid_wchan),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) #ifdef CONFIG_STACKTRACE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) 	ONE("stack",      S_IRUSR, proc_pid_stack),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) #ifdef CONFIG_SCHED_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) 	ONE("schedstat",  S_IRUGO, proc_pid_schedstat),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) #ifdef CONFIG_LATENCYTOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) 	REG("latency",  S_IRUGO, proc_lstats_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) #ifdef CONFIG_PROC_PID_CPUSET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) 	ONE("cpuset",     S_IRUGO, proc_cpuset_show),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) #ifdef CONFIG_CGROUPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) 	ONE("cgroup",  S_IRUGO, proc_cgroup_show),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) #ifdef CONFIG_PROC_CPU_RESCTRL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) 	ONE("cpu_resctrl_groups", S_IRUGO, proc_resctrl_show),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) 	ONE("oom_score",  S_IRUGO, proc_oom_score),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) 	REG("oom_adj",    S_IRUGO|S_IWUSR, proc_oom_adj_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) 	REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) #ifdef CONFIG_AUDIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) 	REG("loginuid",   S_IWUSR|S_IRUGO, proc_loginuid_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) 	REG("sessionid",  S_IRUGO, proc_sessionid_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) #ifdef CONFIG_FAULT_INJECTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) 	REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) 	REG("fail-nth", 0644, proc_fail_nth_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) #ifdef CONFIG_ELF_CORE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) 	REG("coredump_filter", S_IRUGO|S_IWUSR, proc_coredump_filter_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) #ifdef CONFIG_TASK_IO_ACCOUNTING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) 	ONE("io",	S_IRUSR, proc_tgid_io_accounting),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) #ifdef CONFIG_USER_NS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) 	REG("uid_map",    S_IRUGO|S_IWUSR, proc_uid_map_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) 	REG("gid_map",    S_IRUGO|S_IWUSR, proc_gid_map_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) 	REG("projid_map", S_IRUGO|S_IWUSR, proc_projid_map_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) 	REG("setgroups",  S_IRUGO|S_IWUSR, proc_setgroups_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) #if defined(CONFIG_CHECKPOINT_RESTORE) && defined(CONFIG_POSIX_TIMERS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) 	REG("timers",	  S_IRUGO, proc_timers_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) 	REG("timerslack_ns", S_IRUGO|S_IWUGO, proc_pid_set_timerslack_ns_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) #ifdef CONFIG_LIVEPATCH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) 	ONE("patch_state",  S_IRUSR, proc_pid_patch_state),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) #ifdef CONFIG_CPU_FREQ_TIMES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) 	ONE("time_in_state", 0444, proc_time_in_state_show),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) #ifdef CONFIG_STACKLEAK_METRICS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) 	ONE("stack_depth", S_IRUGO, proc_stack_depth),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) #ifdef CONFIG_PROC_PID_ARCH_STATUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) 	ONE("arch_status", S_IRUGO, proc_pid_arch_status),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) static int proc_tgid_base_readdir(struct file *file, struct dir_context *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) 	return proc_pident_readdir(file, ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) 				   tgid_base_stuff, ARRAY_SIZE(tgid_base_stuff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) static const struct file_operations proc_tgid_base_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) 	.read		= generic_read_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) 	.iterate_shared	= proc_tgid_base_readdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) 	.llseek		= generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) struct pid *tgid_pidfd_to_pid(const struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) 	if (file->f_op != &proc_tgid_base_operations)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) 		return ERR_PTR(-EBADF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) 	return proc_pid(file_inode(file));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) 	return proc_pident_lookup(dir, dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) 				  tgid_base_stuff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) 				  tgid_base_stuff + ARRAY_SIZE(tgid_base_stuff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) static const struct inode_operations proc_tgid_base_inode_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) 	.lookup		= proc_tgid_base_lookup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) 	.getattr	= pid_getattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) 	.setattr	= proc_setattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) 	.permission	= proc_pid_permission,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320)  * proc_flush_pid -  Remove dcache entries for @pid from the /proc dcache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321)  * @pid: pid that should be flushed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323)  * This function walks a list of inodes (that belong to any proc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324)  * filesystem) that are attached to the pid and flushes them from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325)  * the dentry cache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327)  * It is safe and reasonable to cache /proc entries for a task until
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328)  * that task exits.  After that they just clog up the dcache with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329)  * useless entries, possibly causing useful dcache entries to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330)  * flushed instead.  This routine is provided to flush those useless
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331)  * dcache entries when a process is reaped.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333)  * NOTE: This routine is just an optimization so it does not guarantee
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334)  *       that no dcache entries will exist after a process is reaped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335)  *       it just makes it very unlikely that any will persist.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) void proc_flush_pid(struct pid *pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) 	proc_invalidate_siblings_dcache(&pid->inodes, &pid->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) static struct dentry *proc_pid_instantiate(struct dentry * dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) 				   struct task_struct *task, const void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) 	struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) 	inode = proc_pid_make_inode(dentry->d_sb, task, S_IFDIR | S_IRUGO | S_IXUGO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) 	if (!inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) 		return ERR_PTR(-ENOENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) 	inode->i_op = &proc_tgid_base_inode_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) 	inode->i_fop = &proc_tgid_base_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) 	inode->i_flags|=S_IMMUTABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) 	set_nlink(inode, nlink_tgid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) 	pid_update_inode(task, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) 	d_set_d_op(dentry, &pid_dentry_operations);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) 	return d_splice_alias(inode, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) struct dentry *proc_pid_lookup(struct dentry *dentry, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) 	struct task_struct *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) 	unsigned tgid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) 	struct proc_fs_info *fs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) 	struct pid_namespace *ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) 	struct dentry *result = ERR_PTR(-ENOENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) 	tgid = name_to_int(&dentry->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) 	if (tgid == ~0U)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) 	fs_info = proc_sb_info(dentry->d_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) 	ns = fs_info->pid_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) 	task = find_task_by_pid_ns(tgid, ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) 	if (task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) 		get_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) 	if (!task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) 	/* Limit procfs to only ptraceable tasks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) 	if (fs_info->hide_pid == HIDEPID_NOT_PTRACEABLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) 		if (!has_pid_permissions(fs_info, task, HIDEPID_NO_ACCESS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) 			goto out_put_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) 	result = proc_pid_instantiate(dentry, task, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) out_put_task:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) 	put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399)  * Find the first task with tgid >= tgid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) struct tgid_iter {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) 	unsigned int tgid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) 	struct task_struct *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) static struct tgid_iter next_tgid(struct pid_namespace *ns, struct tgid_iter iter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) 	struct pid *pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) 	if (iter.task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) 		put_task_struct(iter.task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) 	iter.task = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) 	pid = find_ge_pid(iter.tgid, ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) 	if (pid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) 		iter.tgid = pid_nr_ns(pid, ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) 		iter.task = pid_task(pid, PIDTYPE_TGID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) 		if (!iter.task) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) 			iter.tgid += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) 			goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) 		get_task_struct(iter.task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) 	return iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) #define TGID_OFFSET (FIRST_PROCESS_ENTRY + 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) /* for the /proc/ directory itself, after non-process stuff has been done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) int proc_pid_readdir(struct file *file, struct dir_context *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) 	struct tgid_iter iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) 	struct proc_fs_info *fs_info = proc_sb_info(file_inode(file)->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) 	struct pid_namespace *ns = proc_pid_ns(file_inode(file)->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) 	loff_t pos = ctx->pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) 	if (pos >= PID_MAX_LIMIT + TGID_OFFSET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) 	if (pos == TGID_OFFSET - 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) 		struct inode *inode = d_inode(fs_info->proc_self);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) 		if (!dir_emit(ctx, "self", 4, inode->i_ino, DT_LNK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) 		ctx->pos = pos = pos + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) 	if (pos == TGID_OFFSET - 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) 		struct inode *inode = d_inode(fs_info->proc_thread_self);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) 		if (!dir_emit(ctx, "thread-self", 11, inode->i_ino, DT_LNK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) 		ctx->pos = pos = pos + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) 	iter.tgid = pos - TGID_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) 	iter.task = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) 	for (iter = next_tgid(ns, iter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) 	     iter.task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) 	     iter.tgid += 1, iter = next_tgid(ns, iter)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) 		char name[10 + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) 		unsigned int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) 		cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) 		if (!has_pid_permissions(fs_info, iter.task, HIDEPID_INVISIBLE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) 		len = snprintf(name, sizeof(name), "%u", iter.tgid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) 		ctx->pos = iter.tgid + TGID_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) 		if (!proc_fill_cache(file, ctx, name, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) 				     proc_pid_instantiate, iter.task, NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) 			put_task_struct(iter.task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) 	ctx->pos = PID_MAX_LIMIT + TGID_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479)  * proc_tid_comm_permission is a special permission function exclusively
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480)  * used for the node /proc/<pid>/task/<tid>/comm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481)  * It bypasses generic permission checks in the case where a task of the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482)  * task group attempts to access the node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483)  * The rationale behind this is that glibc and bionic access this node for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484)  * cross thread naming (pthread_set/getname_np(!self)). However, if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485)  * PR_SET_DUMPABLE gets set to 0 this node among others becomes uid=0 gid=0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486)  * which locks out the cross thread naming implementation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487)  * This function makes sure that the node is always accessible for members of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488)  * same thread group.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) static int proc_tid_comm_permission(struct inode *inode, int mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) 	bool is_same_tgroup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) 	struct task_struct *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) 	task = get_proc_task(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) 	if (!task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) 		return -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) 	is_same_tgroup = same_thread_group(current, task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) 	put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) 	if (likely(is_same_tgroup && !(mask & MAY_EXEC))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) 		/* This file (/proc/<pid>/task/<tid>/comm) can always be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) 		 * read or written by the members of the corresponding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) 		 * thread group.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) 	return generic_permission(inode, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) static const struct inode_operations proc_tid_comm_inode_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) 		.permission = proc_tid_comm_permission,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517)  * Tasks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) static const struct pid_entry tid_base_stuff[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) 	DIR("fd",        S_IRUSR|S_IXUSR, proc_fd_inode_operations, proc_fd_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) 	DIR("fdinfo",    S_IRUGO|S_IXUGO, proc_fdinfo_inode_operations, proc_fdinfo_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) 	DIR("ns",	 S_IRUSR|S_IXUGO, proc_ns_dir_inode_operations, proc_ns_dir_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) #ifdef CONFIG_NET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) 	DIR("net",        S_IRUGO|S_IXUGO, proc_net_inode_operations, proc_net_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) 	REG("environ",   S_IRUSR, proc_environ_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) 	REG("auxv",      S_IRUSR, proc_auxv_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) 	ONE("status",    S_IRUGO, proc_pid_status),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) 	ONE("personality", S_IRUSR, proc_pid_personality),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) 	ONE("limits",	 S_IRUGO, proc_pid_limits),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) #ifdef CONFIG_SCHED_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) 	REG("sched",     S_IRUGO|S_IWUSR, proc_pid_sched_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) 	NOD("comm",      S_IFREG|S_IRUGO|S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) 			 &proc_tid_comm_inode_operations,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) 			 &proc_pid_set_comm_operations, {}),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) #ifdef CONFIG_HAVE_ARCH_TRACEHOOK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) 	ONE("syscall",   S_IRUSR, proc_pid_syscall),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) 	REG("cmdline",   S_IRUGO, proc_pid_cmdline_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) 	ONE("stat",      S_IRUGO, proc_tid_stat),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) 	ONE("statm",     S_IRUGO, proc_pid_statm),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) 	REG("maps",      S_IRUGO, proc_pid_maps_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) #ifdef CONFIG_PROC_CHILDREN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) 	REG("children",  S_IRUGO, proc_tid_children_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) #ifdef CONFIG_NUMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) 	REG("numa_maps", S_IRUGO, proc_pid_numa_maps_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) 	REG("mem",       S_IRUSR|S_IWUSR, proc_mem_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) 	LNK("cwd",       proc_cwd_link),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) 	LNK("root",      proc_root_link),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) 	LNK("exe",       proc_exe_link),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) 	REG("mounts",    S_IRUGO, proc_mounts_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) 	REG("mountinfo",  S_IRUGO, proc_mountinfo_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) #ifdef CONFIG_PROC_PAGE_MONITOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) 	REG("clear_refs", S_IWUSR, proc_clear_refs_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) 	REG("smaps",     S_IRUGO, proc_pid_smaps_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) 	REG("smaps_rollup", S_IRUGO, proc_pid_smaps_rollup_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) 	REG("pagemap",    S_IRUSR, proc_pagemap_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) #ifdef CONFIG_SECURITY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) 	DIR("attr",      S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) #ifdef CONFIG_KALLSYMS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) 	ONE("wchan",     S_IRUGO, proc_pid_wchan),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) #ifdef CONFIG_STACKTRACE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) 	ONE("stack",      S_IRUSR, proc_pid_stack),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) #ifdef CONFIG_SCHED_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) 	ONE("schedstat", S_IRUGO, proc_pid_schedstat),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) #ifdef CONFIG_LATENCYTOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) 	REG("latency",  S_IRUGO, proc_lstats_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) #ifdef CONFIG_PROC_PID_CPUSET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) 	ONE("cpuset",    S_IRUGO, proc_cpuset_show),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) #ifdef CONFIG_CGROUPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) 	ONE("cgroup",  S_IRUGO, proc_cgroup_show),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) #ifdef CONFIG_PROC_CPU_RESCTRL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) 	ONE("cpu_resctrl_groups", S_IRUGO, proc_resctrl_show),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) 	ONE("oom_score", S_IRUGO, proc_oom_score),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) 	REG("oom_adj",   S_IRUGO|S_IWUSR, proc_oom_adj_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) 	REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) #ifdef CONFIG_AUDIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) 	REG("loginuid",  S_IWUSR|S_IRUGO, proc_loginuid_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) 	REG("sessionid",  S_IRUGO, proc_sessionid_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) #ifdef CONFIG_FAULT_INJECTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) 	REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) 	REG("fail-nth", 0644, proc_fail_nth_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) #ifdef CONFIG_TASK_IO_ACCOUNTING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) 	ONE("io",	S_IRUSR, proc_tid_io_accounting),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) #ifdef CONFIG_USER_NS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) 	REG("uid_map",    S_IRUGO|S_IWUSR, proc_uid_map_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) 	REG("gid_map",    S_IRUGO|S_IWUSR, proc_gid_map_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) 	REG("projid_map", S_IRUGO|S_IWUSR, proc_projid_map_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) 	REG("setgroups",  S_IRUGO|S_IWUSR, proc_setgroups_operations),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) #ifdef CONFIG_LIVEPATCH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) 	ONE("patch_state",  S_IRUSR, proc_pid_patch_state),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) #ifdef CONFIG_PROC_PID_ARCH_STATUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) 	ONE("arch_status", S_IRUGO, proc_pid_arch_status),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) #ifdef CONFIG_CPU_FREQ_TIMES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) 	ONE("time_in_state", 0444, proc_time_in_state_show),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) static int proc_tid_base_readdir(struct file *file, struct dir_context *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) 	return proc_pident_readdir(file, ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) 				   tid_base_stuff, ARRAY_SIZE(tid_base_stuff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) static struct dentry *proc_tid_base_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) 	return proc_pident_lookup(dir, dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) 				  tid_base_stuff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) 				  tid_base_stuff + ARRAY_SIZE(tid_base_stuff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) static const struct file_operations proc_tid_base_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) 	.read		= generic_read_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) 	.iterate_shared	= proc_tid_base_readdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) 	.llseek		= generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) static const struct inode_operations proc_tid_base_inode_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) 	.lookup		= proc_tid_base_lookup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) 	.getattr	= pid_getattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) 	.setattr	= proc_setattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) static struct dentry *proc_task_instantiate(struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) 	struct task_struct *task, const void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) 	struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) 	inode = proc_pid_make_inode(dentry->d_sb, task, S_IFDIR | S_IRUGO | S_IXUGO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) 	if (!inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) 		return ERR_PTR(-ENOENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) 	inode->i_op = &proc_tid_base_inode_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) 	inode->i_fop = &proc_tid_base_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) 	inode->i_flags |= S_IMMUTABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) 	set_nlink(inode, nlink_tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) 	pid_update_inode(task, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) 	d_set_d_op(dentry, &pid_dentry_operations);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) 	return d_splice_alias(inode, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) 	struct task_struct *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) 	struct task_struct *leader = get_proc_task(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) 	unsigned tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) 	struct proc_fs_info *fs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) 	struct pid_namespace *ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) 	struct dentry *result = ERR_PTR(-ENOENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) 	if (!leader)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) 		goto out_no_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) 	tid = name_to_int(&dentry->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) 	if (tid == ~0U)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) 	fs_info = proc_sb_info(dentry->d_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) 	ns = fs_info->pid_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) 	task = find_task_by_pid_ns(tid, ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) 	if (task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) 		get_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) 	if (!task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) 	if (!same_thread_group(leader, task))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) 		goto out_drop_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) 	result = proc_task_instantiate(dentry, task, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) out_drop_task:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) 	put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) 	put_task_struct(leader);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) out_no_task:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699)  * Find the first tid of a thread group to return to user space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701)  * Usually this is just the thread group leader, but if the users
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702)  * buffer was too small or there was a seek into the middle of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703)  * directory we have more work todo.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705)  * In the case of a short read we start with find_task_by_pid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707)  * In the case of a seek we start with the leader and walk nr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708)  * threads past it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) static struct task_struct *first_tid(struct pid *pid, int tid, loff_t f_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) 					struct pid_namespace *ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) 	struct task_struct *pos, *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) 	unsigned long nr = f_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) 	if (nr != f_pos)	/* 32bit overflow? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) 	task = pid_task(pid, PIDTYPE_PID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) 	if (!task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) 		goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) 	/* Attempt to start with the tid of a thread */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) 	if (tid && nr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) 		pos = find_task_by_pid_ns(tid, ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) 		if (pos && same_thread_group(pos, task))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) 			goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) 	/* If nr exceeds the number of threads there is nothing todo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) 	if (nr >= get_nr_threads(task))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) 		goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) 	/* If we haven't found our starting place yet start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) 	 * with the leader and walk nr threads forward.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) 	pos = task = task->group_leader;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) 		if (!nr--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) 			goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) 	} while_each_thread(task, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) 	pos = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) 	goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) 	get_task_struct(pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) 	return pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754)  * Find the next thread in the thread list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755)  * Return NULL if there is an error or no next thread.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757)  * The reference to the input task_struct is released.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) static struct task_struct *next_tid(struct task_struct *start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) 	struct task_struct *pos = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) 	if (pid_alive(start)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) 		pos = next_thread(start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) 		if (thread_group_leader(pos))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) 			pos = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) 			get_task_struct(pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) 	put_task_struct(start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) 	return pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) /* for the /proc/TGID/task/ directories */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) static int proc_task_readdir(struct file *file, struct dir_context *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) 	struct inode *inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) 	struct task_struct *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) 	struct pid_namespace *ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) 	int tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) 	if (proc_inode_is_dead(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) 	if (!dir_emit_dots(file, ctx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) 	/* f_version caches the tgid value that the last readdir call couldn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) 	 * return. lseek aka telldir automagically resets f_version to 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) 	ns = proc_pid_ns(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) 	tid = (int)file->f_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) 	file->f_version = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) 	for (task = first_tid(proc_pid(inode), tid, ctx->pos - 2, ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) 	     task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) 	     task = next_tid(task), ctx->pos++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) 		char name[10 + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) 		unsigned int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) 		tid = task_pid_nr_ns(task, ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) 		len = snprintf(name, sizeof(name), "%u", tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) 		if (!proc_fill_cache(file, ctx, name, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) 				proc_task_instantiate, task, NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) 			/* returning this tgid failed, save it as the first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) 			 * pid for the next readir call */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) 			file->f_version = (u64)tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) 			put_task_struct(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) static int proc_task_getattr(const struct path *path, struct kstat *stat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) 			     u32 request_mask, unsigned int query_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) 	struct inode *inode = d_inode(path->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) 	struct task_struct *p = get_proc_task(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) 	generic_fillattr(inode, stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) 	if (p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) 		stat->nlink += get_nr_threads(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) 		put_task_struct(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) static const struct inode_operations proc_task_inode_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) 	.lookup		= proc_task_lookup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) 	.getattr	= proc_task_getattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) 	.setattr	= proc_setattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) 	.permission	= proc_pid_permission,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) static const struct file_operations proc_task_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) 	.read		= generic_read_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) 	.iterate_shared	= proc_task_readdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) 	.llseek		= generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) void __init set_proc_pid_nlink(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845) 	nlink_tid = pid_entry_nlink(tid_base_stuff, ARRAY_SIZE(tid_base_stuff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) 	nlink_tgid = pid_entry_nlink(tgid_base_stuff, ARRAY_SIZE(tgid_base_stuff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) }