#include <linux/uaccess.h>
#include <linux/errno.h>
#include <linux/time.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
#include <linux/task_io_accounting_ops.h>
#include <linux/init.h>
#include <linux/capability.h>
#include <linux/file.h>
#include <linux/fdtable.h>
#include <linux/generic-radix-tree.h>
#include <linux/string.h>
#include <linux/seq_file.h>
#include <linux/namei.h>
#include <linux/mnt_namespace.h>
#include <linux/mm.h>
#include <linux/swap.h>
#include <linux/rcupdate.h>
#include <linux/kallsyms.h>
#include <linux/stacktrace.h>
#include <linux/resource.h>
#include <linux/module.h>
#include <linux/mount.h>
#include <linux/security.h>
#include <linux/ptrace.h>
#include <linux/printk.h>
#include <linux/cache.h>
#include <linux/cgroup.h>
#include <linux/cpuset.h>
#include <linux/audit.h>
#include <linux/poll.h>
#include <linux/nsproxy.h>
#include <linux/oom.h>
#include <linux/elf.h>
#include <linux/pid_namespace.h>
#include <linux/user_namespace.h>
#include <linux/fs_struct.h>
#include <linux/slab.h>
#include <linux/sched/autogroup.h>
#include <linux/sched/mm.h>
#include <linux/sched/coredump.h>
#include <linux/sched/debug.h>
#include <linux/sched/stat.h>
#include <linux/posix-timers.h>
#include <linux/time_namespace.h>
#include <linux/resctrl.h>
#include <linux/cn_proc.h>
#include <linux/ksm.h>
#include <uapi/linux/lsm.h>
#include <trace/events/oom.h>
#include "internal.h"
#include "fd.h"
#include "../../lib/kstrtox.h"
static u8 nlink_tid __ro_after_init;
static u8 nlink_tgid __ro_after_init;
struct pid_entry { … };
#define NOD(NAME, MODE, IOP, FOP, OP) …
#define DIR(NAME, MODE, iops, fops) …
#define LNK(NAME, get_link) …
#define REG(NAME, MODE, fops) …
#define ONE(NAME, MODE, show) …
#define ATTR(LSMID, NAME, MODE) …
static unsigned int __init pid_entry_nlink(const struct pid_entry *entries,
unsigned int n)
{ … }
static int get_task_root(struct task_struct *task, struct path *root)
{ … }
static int proc_cwd_link(struct dentry *dentry, struct path *path)
{ … }
static int proc_root_link(struct dentry *dentry, struct path *path)
{ … }
static ssize_t get_mm_proctitle(struct mm_struct *mm, char __user *buf,
size_t count, unsigned long pos,
unsigned long arg_start)
{ … }
static ssize_t get_mm_cmdline(struct mm_struct *mm, char __user *buf,
size_t count, loff_t *ppos)
{ … }
static ssize_t get_task_cmdline(struct task_struct *tsk, char __user *buf,
size_t count, loff_t *pos)
{ … }
static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf,
size_t count, loff_t *pos)
{ … }
static const struct file_operations proc_pid_cmdline_ops = …;
#ifdef CONFIG_KALLSYMS
static int proc_pid_wchan(struct seq_file *m, struct pid_namespace *ns,
struct pid *pid, struct task_struct *task)
{ … }
#endif
static int lock_trace(struct task_struct *task)
{ … }
static void unlock_trace(struct task_struct *task)
{ … }
#ifdef CONFIG_STACKTRACE
#define MAX_STACK_TRACE_DEPTH …
static int proc_pid_stack(struct seq_file *m, struct pid_namespace *ns,
struct pid *pid, struct task_struct *task)
{ … }
#endif
#ifdef CONFIG_SCHED_INFO
static int proc_pid_schedstat(struct seq_file *m, struct pid_namespace *ns,
struct pid *pid, struct task_struct *task)
{ … }
#endif
#ifdef CONFIG_LATENCYTOP
static int lstats_show_proc(struct seq_file *m, void *v)
{ … }
static int lstats_open(struct inode *inode, struct file *file)
{ … }
static ssize_t lstats_write(struct file *file, const char __user *buf,
size_t count, loff_t *offs)
{ … }
static const struct file_operations proc_lstats_operations = …;
#endif
static int proc_oom_score(struct seq_file *m, struct pid_namespace *ns,
struct pid *pid, struct task_struct *task)
{ … }
struct limit_names { … };
static const struct limit_names lnames[RLIM_NLIMITS] = …;
static int proc_pid_limits(struct seq_file *m, struct pid_namespace *ns,
struct pid *pid, struct task_struct *task)
{ … }
#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
static int proc_pid_syscall(struct seq_file *m, struct pid_namespace *ns,
struct pid *pid, struct task_struct *task)
{ … }
#endif
static bool proc_fd_access_allowed(struct inode *inode)
{ … }
int proc_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
struct iattr *attr)
{ … }
static bool has_pid_permissions(struct proc_fs_info *fs_info,
struct task_struct *task,
enum proc_hidepid hide_pid_min)
{ … }
static int proc_pid_permission(struct mnt_idmap *idmap,
struct inode *inode, int mask)
{ … }
static const struct inode_operations proc_def_inode_operations = …;
static int proc_single_show(struct seq_file *m, void *v)
{ … }
static int proc_single_open(struct inode *inode, struct file *filp)
{ … }
static const struct file_operations proc_single_file_operations = …;
struct mm_struct *proc_mem_open(struct inode *inode, unsigned int mode)
{ … }
static int __mem_open(struct inode *inode, struct file *file, unsigned int mode)
{ … }
static int mem_open(struct inode *inode, struct file *file)
{ … }
static ssize_t mem_rw(struct file *file, char __user *buf,
size_t count, loff_t *ppos, int write)
{ … }
static ssize_t mem_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{ … }
static ssize_t mem_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{ … }
loff_t mem_lseek(struct file *file, loff_t offset, int orig)
{ … }
static int mem_release(struct inode *inode, struct file *file)
{ … }
static const struct file_operations proc_mem_operations = …;
static int environ_open(struct inode *inode, struct file *file)
{ … }
static ssize_t environ_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{ … }
static const struct file_operations proc_environ_operations = …;
static int auxv_open(struct inode *inode, struct file *file)
{ … }
static ssize_t auxv_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{ … }
static const struct file_operations proc_auxv_operations = …;
static ssize_t oom_adj_read(struct file *file, char __user *buf, size_t count,
loff_t *ppos)
{ … }
static int __set_oom_adj(struct file *file, int oom_adj, bool legacy)
{ … }
static ssize_t oom_adj_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{ … }
static const struct file_operations proc_oom_adj_operations = …;
static ssize_t oom_score_adj_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{ … }
static ssize_t oom_score_adj_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{ … }
static const struct file_operations proc_oom_score_adj_operations = …;
#ifdef CONFIG_AUDIT
#define TMPBUFLEN …
static ssize_t proc_loginuid_read(struct file * file, char __user * buf,
size_t count, loff_t *ppos)
{ … }
static ssize_t proc_loginuid_write(struct file * file, const char __user * buf,
size_t count, loff_t *ppos)
{ … }
static const struct file_operations proc_loginuid_operations = …;
static ssize_t proc_sessionid_read(struct file * file, char __user * buf,
size_t count, loff_t *ppos)
{ … }
static const struct file_operations proc_sessionid_operations = …;
#endif
#ifdef CONFIG_FAULT_INJECTION
static ssize_t proc_fault_inject_read(struct file * file, char __user * buf,
size_t count, loff_t *ppos)
{ … }
static ssize_t proc_fault_inject_write(struct file * file,
const char __user * buf, size_t count, loff_t *ppos)
{ … }
static const struct file_operations proc_fault_inject_operations = …;
static ssize_t proc_fail_nth_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{ … }
static ssize_t proc_fail_nth_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{ … }
static const struct file_operations proc_fail_nth_operations = …;
#endif
#ifdef CONFIG_SCHED_DEBUG
static int sched_show(struct seq_file *m, void *v)
{ … }
static ssize_t
sched_write(struct file *file, const char __user *buf,
size_t count, loff_t *offset)
{ … }
static int sched_open(struct inode *inode, struct file *filp)
{ … }
static const struct file_operations proc_pid_sched_operations = …;
#endif
#ifdef CONFIG_SCHED_AUTOGROUP
static int sched_autogroup_show(struct seq_file *m, void *v)
{ … }
static ssize_t
sched_autogroup_write(struct file *file, const char __user *buf,
size_t count, loff_t *offset)
{ … }
static int sched_autogroup_open(struct inode *inode, struct file *filp)
{ … }
static const struct file_operations proc_pid_sched_autogroup_operations = …;
#endif
#ifdef CONFIG_TIME_NS
static int timens_offsets_show(struct seq_file *m, void *v)
{ … }
static ssize_t timens_offsets_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{ … }
static int timens_offsets_open(struct inode *inode, struct file *filp)
{ … }
static const struct file_operations proc_timens_offsets_operations = …;
#endif
static ssize_t comm_write(struct file *file, const char __user *buf,
size_t count, loff_t *offset)
{ … }
static int comm_show(struct seq_file *m, void *v)
{ … }
static int comm_open(struct inode *inode, struct file *filp)
{ … }
static const struct file_operations proc_pid_set_comm_operations = …;
static int proc_exe_link(struct dentry *dentry, struct path *exe_path)
{ … }
static const char *proc_pid_get_link(struct dentry *dentry,
struct inode *inode,
struct delayed_call *done)
{ … }
static int do_proc_readlink(const struct path *path, char __user *buffer, int buflen)
{ … }
static int proc_pid_readlink(struct dentry * dentry, char __user * buffer, int buflen)
{ … }
const struct inode_operations proc_pid_link_inode_operations = …;
void task_dump_owner(struct task_struct *task, umode_t mode,
kuid_t *ruid, kgid_t *rgid)
{ … }
void proc_pid_evict_inode(struct proc_inode *ei)
{ … }
struct inode *proc_pid_make_inode(struct super_block *sb,
struct task_struct *task, umode_t mode)
{ … }
static struct inode *proc_pid_make_base_inode(struct super_block *sb,
struct task_struct *task, umode_t mode)
{ … }
int pid_getattr(struct mnt_idmap *idmap, const struct path *path,
struct kstat *stat, u32 request_mask, unsigned int query_flags)
{ … }
void pid_update_inode(struct task_struct *task, struct inode *inode)
{ … }
static int pid_revalidate(struct dentry *dentry, unsigned int flags)
{ … }
static inline bool proc_inode_is_dead(struct inode *inode)
{ … }
int pid_delete_dentry(const struct dentry *dentry)
{ … }
const struct dentry_operations pid_dentry_operations = …;
bool proc_fill_cache(struct file *file, struct dir_context *ctx,
const char *name, unsigned int len,
instantiate_t instantiate, struct task_struct *task, const void *ptr)
{ … }
static int dname_to_vma_addr(struct dentry *dentry,
unsigned long *start, unsigned long *end)
{ … }
static int map_files_d_revalidate(struct dentry *dentry, unsigned int flags)
{ … }
static const struct dentry_operations tid_map_files_dentry_operations = …;
static int map_files_get_link(struct dentry *dentry, struct path *path)
{ … }
struct map_files_info { … };
static const char *
proc_map_files_get_link(struct dentry *dentry,
struct inode *inode,
struct delayed_call *done)
{ … }
static const struct inode_operations proc_map_files_link_inode_operations = …;
static struct dentry *
proc_map_files_instantiate(struct dentry *dentry,
struct task_struct *task, const void *ptr)
{ … }
static struct dentry *proc_map_files_lookup(struct inode *dir,
struct dentry *dentry, unsigned int flags)
{ … }
static const struct inode_operations proc_map_files_inode_operations = …;
static int
proc_map_files_readdir(struct file *file, struct dir_context *ctx)
{ … }
static const struct file_operations proc_map_files_operations = …;
#if defined(CONFIG_CHECKPOINT_RESTORE) && defined(CONFIG_POSIX_TIMERS)
struct timers_private { … };
static void *timers_start(struct seq_file *m, loff_t *pos)
{ … }
static void *timers_next(struct seq_file *m, void *v, loff_t *pos)
{ … }
static void timers_stop(struct seq_file *m, void *v)
{ … }
static int show_timer(struct seq_file *m, void *v)
{ … }
static const struct seq_operations proc_timers_seq_ops = …;
static int proc_timers_open(struct inode *inode, struct file *file)
{ … }
static const struct file_operations proc_timers_operations = …;
#endif
static ssize_t timerslack_ns_write(struct file *file, const char __user *buf,
size_t count, loff_t *offset)
{ … }
static int timerslack_ns_show(struct seq_file *m, void *v)
{ … }
static int timerslack_ns_open(struct inode *inode, struct file *filp)
{ … }
static const struct file_operations proc_pid_set_timerslack_ns_operations = …;
static struct dentry *proc_pident_instantiate(struct dentry *dentry,
struct task_struct *task, const void *ptr)
{ … }
static struct dentry *proc_pident_lookup(struct inode *dir,
struct dentry *dentry,
const struct pid_entry *p,
const struct pid_entry *end)
{ … }
static int proc_pident_readdir(struct file *file, struct dir_context *ctx,
const struct pid_entry *ents, unsigned int nents)
{ … }
#ifdef CONFIG_SECURITY
static int proc_pid_attr_open(struct inode *inode, struct file *file)
{ … }
static ssize_t proc_pid_attr_read(struct file * file, char __user * buf,
size_t count, loff_t *ppos)
{ … }
static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
size_t count, loff_t *ppos)
{ … }
static const struct file_operations proc_pid_attr_operations = …;
#define LSM_DIR_OPS(LSM) …
#ifdef CONFIG_SECURITY_SMACK
static const struct pid_entry smack_attr_dir_stuff[] = …;
LSM_DIR_OPS(…);
#endif
#ifdef CONFIG_SECURITY_APPARMOR
static const struct pid_entry apparmor_attr_dir_stuff[] = …;
LSM_DIR_OPS(…);
#endif
static const struct pid_entry attr_dir_stuff[] = …;
static int proc_attr_dir_readdir(struct file *file, struct dir_context *ctx)
{ … }
static const struct file_operations proc_attr_dir_operations = …;
static struct dentry *proc_attr_dir_lookup(struct inode *dir,
struct dentry *dentry, unsigned int flags)
{ … }
static const struct inode_operations proc_attr_dir_inode_operations = …;
#endif
#ifdef CONFIG_ELF_CORE
static ssize_t proc_coredump_filter_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{ … }
static ssize_t proc_coredump_filter_write(struct file *file,
const char __user *buf,
size_t count,
loff_t *ppos)
{ … }
static const struct file_operations proc_coredump_filter_operations = …;
#endif
#ifdef CONFIG_TASK_IO_ACCOUNTING
static int do_io_accounting(struct task_struct *task, struct seq_file *m, int whole)
{ … }
static int proc_tid_io_accounting(struct seq_file *m, struct pid_namespace *ns,
struct pid *pid, struct task_struct *task)
{ … }
static int proc_tgid_io_accounting(struct seq_file *m, struct pid_namespace *ns,
struct pid *pid, struct task_struct *task)
{ … }
#endif
#ifdef CONFIG_USER_NS
static int proc_id_map_open(struct inode *inode, struct file *file,
const struct seq_operations *seq_ops)
{ … }
static int proc_id_map_release(struct inode *inode, struct file *file)
{ … }
static int proc_uid_map_open(struct inode *inode, struct file *file)
{ … }
static int proc_gid_map_open(struct inode *inode, struct file *file)
{ … }
static int proc_projid_map_open(struct inode *inode, struct file *file)
{ … }
static const struct file_operations proc_uid_map_operations = …;
static const struct file_operations proc_gid_map_operations = …;
static const struct file_operations proc_projid_map_operations = …;
static int proc_setgroups_open(struct inode *inode, struct file *file)
{ … }
static int proc_setgroups_release(struct inode *inode, struct file *file)
{ … }
static const struct file_operations proc_setgroups_operations = …;
#endif
static int proc_pid_personality(struct seq_file *m, struct pid_namespace *ns,
struct pid *pid, struct task_struct *task)
{ … }
#ifdef CONFIG_LIVEPATCH
static int proc_pid_patch_state(struct seq_file *m, struct pid_namespace *ns,
struct pid *pid, struct task_struct *task)
{
seq_printf(m, "%d\n", task->patch_state);
return 0;
}
#endif
#ifdef CONFIG_KSM
static int proc_pid_ksm_merging_pages(struct seq_file *m, struct pid_namespace *ns,
struct pid *pid, struct task_struct *task)
{ … }
static int proc_pid_ksm_stat(struct seq_file *m, struct pid_namespace *ns,
struct pid *pid, struct task_struct *task)
{ … }
#endif
#ifdef CONFIG_STACKLEAK_METRICS
static int proc_stack_depth(struct seq_file *m, struct pid_namespace *ns,
struct pid *pid, struct task_struct *task)
{
unsigned long prev_depth = THREAD_SIZE -
(task->prev_lowest_stack & (THREAD_SIZE - 1));
unsigned long depth = THREAD_SIZE -
(task->lowest_stack & (THREAD_SIZE - 1));
seq_printf(m, "previous stack depth: %lu\nstack depth: %lu\n",
prev_depth, depth);
return 0;
}
#endif
static const struct file_operations proc_task_operations;
static const struct inode_operations proc_task_inode_operations;
static const struct pid_entry tgid_base_stuff[] = …;
static int proc_tgid_base_readdir(struct file *file, struct dir_context *ctx)
{ … }
static const struct file_operations proc_tgid_base_operations = …;
struct pid *tgid_pidfd_to_pid(const struct file *file)
{ … }
static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
{ … }
static const struct inode_operations proc_tgid_base_inode_operations = …;
void proc_flush_pid(struct pid *pid)
{ … }
static struct dentry *proc_pid_instantiate(struct dentry * dentry,
struct task_struct *task, const void *ptr)
{ … }
struct dentry *proc_pid_lookup(struct dentry *dentry, unsigned int flags)
{ … }
struct tgid_iter { … };
static struct tgid_iter next_tgid(struct pid_namespace *ns, struct tgid_iter iter)
{ … }
#define TGID_OFFSET …
int proc_pid_readdir(struct file *file, struct dir_context *ctx)
{ … }
static int proc_tid_comm_permission(struct mnt_idmap *idmap,
struct inode *inode, int mask)
{ … }
static const struct inode_operations proc_tid_comm_inode_operations = …;
static const struct pid_entry tid_base_stuff[] = …;
static int proc_tid_base_readdir(struct file *file, struct dir_context *ctx)
{ … }
static struct dentry *proc_tid_base_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
{ … }
static const struct file_operations proc_tid_base_operations = …;
static const struct inode_operations proc_tid_base_inode_operations = …;
static struct dentry *proc_task_instantiate(struct dentry *dentry,
struct task_struct *task, const void *ptr)
{ … }
static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, unsigned int flags)
{ … }
static struct task_struct *first_tid(struct pid *pid, int tid, loff_t f_pos,
struct pid_namespace *ns)
{ … }
static struct task_struct *next_tid(struct task_struct *start)
{ … }
static int proc_task_readdir(struct file *file, struct dir_context *ctx)
{ … }
static int proc_task_getattr(struct mnt_idmap *idmap,
const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int query_flags)
{ … }
static const struct inode_operations proc_task_inode_operations = …;
static const struct file_operations proc_task_operations = …;
void __init set_proc_pid_nlink(void)
{ … }