^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(¤t->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(¤t->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) }