base.c 85.3 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0
Linus Torvalds's avatar
Linus Torvalds committed
2
3
4
5
6
7
8
9
10
11
12
13
14
/*
 *  linux/fs/proc/base.c
 *
 *  Copyright (C) 1991, 1992 Linus Torvalds
 *
 *  proc base directory handling functions
 *
 *  1999, Al Viro. Rewritten. Now it covers the whole per-process part.
 *  Instead of using magical inumbers to determine the kind of object
 *  we allocate and fill in-core inodes upon lookup. They don't even
 *  go into icache. We cache the reference to task_struct upon lookup too.
 *  Eventually it should become a filesystem in its own. We don't use the
 *  rest of procfs anymore.
Mauricio Lin's avatar
Mauricio Lin committed
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
 *
 *
 *  Changelog:
 *  17-Jan-2005
 *  Allan Bezerra
 *  Bruna Moreira <bruna.moreira@indt.org.br>
 *  Edjard Mota <edjard.mota@indt.org.br>
 *  Ilias Biris <ilias.biris@indt.org.br>
 *  Mauricio Lin <mauricio.lin@indt.org.br>
 *
 *  Embedded Linux Lab - 10LE Instituto Nokia de Tecnologia - INdT
 *
 *  A new process specific entry (smaps) included in /proc. It shows the
 *  size of rss for each memory area. The maps entry lacks information
 *  about physical memory size (rss) for each mapped file, i.e.,
 *  rss information for executables and library files.
 *  This additional information is useful for any tools that need to know
 *  about physical memory consumption for a process specific library.
 *
 *  Changelog:
 *  21-Feb-2005
 *  Embedded Linux Lab - 10LE Instituto Nokia de Tecnologia - INdT
 *  Pud inclusion in the page table walking.
 *
 *  ChangeLog:
 *  10-Mar-2005
 *  10LE Instituto Nokia de Tecnologia - INdT:
 *  A better way to walks through the page table as suggested by Hugh Dickins.
 *
 *  Simo Piiroinen <simo.piiroinen@nokia.com>:
 *  Smaps information related to shared, private, clean and dirty pages.
 *
 *  Paul Mundt <paul.mundt@nokia.com>:
 *  Overall revision about smaps.
Linus Torvalds's avatar
Linus Torvalds committed
49
50
 */

51
#include <linux/uaccess.h>
Linus Torvalds's avatar
Linus Torvalds committed
52
53
54
55
56

#include <linux/errno.h>
#include <linux/time.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
57
#include <linux/task_io_accounting_ops.h>
Linus Torvalds's avatar
Linus Torvalds committed
58
#include <linux/init.h>
59
#include <linux/capability.h>
Linus Torvalds's avatar
Linus Torvalds committed
60
#include <linux/file.h>
Al Viro's avatar
Al Viro committed
61
#include <linux/fdtable.h>
Linus Torvalds's avatar
Linus Torvalds committed
62
63
64
#include <linux/string.h>
#include <linux/seq_file.h>
#include <linux/namei.h>
65
#include <linux/mnt_namespace.h>
Linus Torvalds's avatar
Linus Torvalds committed
66
#include <linux/mm.h>
67
#include <linux/swap.h>
68
#include <linux/rcupdate.h>
Linus Torvalds's avatar
Linus Torvalds committed
69
#include <linux/kallsyms.h>
Ken Chen's avatar
Ken Chen committed
70
#include <linux/stacktrace.h>
71
#include <linux/resource.h>
Kees Cook's avatar
Kees Cook committed
72
#include <linux/module.h>
Linus Torvalds's avatar
Linus Torvalds committed
73
74
75
#include <linux/mount.h>
#include <linux/security.h>
#include <linux/ptrace.h>
76
#include <linux/tracehook.h>
Andrew Morton's avatar
Andrew Morton committed
77
#include <linux/printk.h>
Alexey Dobriyan's avatar
Alexey Dobriyan committed
78
#include <linux/cache.h>
79
#include <linux/cgroup.h>
Linus Torvalds's avatar
Linus Torvalds committed
80
81
#include <linux/cpuset.h>
#include <linux/audit.h>
Al Viro's avatar
Al Viro committed
82
#include <linux/poll.h>
83
#include <linux/nsproxy.h>
84
#include <linux/oom.h>
85
#include <linux/elf.h>
86
#include <linux/pid_namespace.h>
87
#include <linux/user_namespace.h>
88
#include <linux/fs_struct.h>
89
#include <linux/slab.h>
90
#include <linux/sched/autogroup.h>
91
#include <linux/sched/mm.h>
92
#include <linux/sched/coredump.h>
93
#include <linux/sched/debug.h>
94
#include <linux/sched/stat.h>
95
#include <linux/flex_array.h>
96
#include <linux/posix-timers.h>
97
#include <trace/events/oom.h>
Linus Torvalds's avatar
Linus Torvalds committed
98
#include "internal.h"
99
#include "fd.h"
Linus Torvalds's avatar
Linus Torvalds committed
100

101
102
#include "../../lib/kstrtox.h"

103
104
105
106
107
108
109
110
111
112
/* NOTE:
 *	Implementing inode permission operations in /proc is almost
 *	certainly an error.  Permission checks need to happen during
 *	each system call not at open time.  The reason is that most of
 *	what we wish to check for permissions in /proc varies at runtime.
 *
 *	The classic example of a problem is opening file descriptors
 *	in /proc for a task before it execs a suid executable.
 */

Alexey Dobriyan's avatar
Alexey Dobriyan committed
113
114
static u8 nlink_tid __ro_after_init;
static u8 nlink_tgid __ro_after_init;
115

Linus Torvalds's avatar
Linus Torvalds committed
116
struct pid_entry {
117
	const char *name;
118
	unsigned int len;
Al Viro's avatar
Al Viro committed
119
	umode_t mode;
120
	const struct inode_operations *iop;
121
	const struct file_operations *fop;
122
	union proc_op op;
Linus Torvalds's avatar
Linus Torvalds committed
123
124
};

125
#define NOD(NAME, MODE, IOP, FOP, OP) {			\
126
	.name = (NAME),					\
127
	.len  = sizeof(NAME) - 1,			\
128
129
130
131
132
133
	.mode = MODE,					\
	.iop  = IOP,					\
	.fop  = FOP,					\
	.op   = OP,					\
}

Alexey Dobriyan's avatar
Alexey Dobriyan committed
134
135
136
#define DIR(NAME, MODE, iops, fops)	\
	NOD(NAME, (S_IFDIR|(MODE)), &iops, &fops, {} )
#define LNK(NAME, get_link)					\
137
	NOD(NAME, (S_IFLNK|S_IRWXUGO),				\
138
		&proc_pid_link_inode_operations, NULL,		\
Alexey Dobriyan's avatar
Alexey Dobriyan committed
139
140
141
142
		{ .proc_get_link = get_link } )
#define REG(NAME, MODE, fops)				\
	NOD(NAME, (S_IFREG|(MODE)), NULL, &fops, {})
#define ONE(NAME, MODE, show)				\
143
144
	NOD(NAME, (S_IFREG|(MODE)), 			\
		NULL, &proc_single_file_operations,	\
Alexey Dobriyan's avatar
Alexey Dobriyan committed
145
		{ .proc_show = show } )
Linus Torvalds's avatar
Linus Torvalds committed
146

147
148
149
150
/*
 * Count the number of hardlinks for the pid_entry table, excluding the .
 * and .. links.
 */
151
static unsigned int __init pid_entry_nlink(const struct pid_entry *entries,
152
153
154
155
156
	unsigned int n)
{
	unsigned int i;
	unsigned int count;

157
	count = 2;
158
159
160
161
162
163
164
165
	for (i = 0; i < n; ++i) {
		if (S_ISDIR(entries[i].mode))
			++count;
	}

	return count;
}

166
static int get_task_root(struct task_struct *task, struct path *root)
Linus Torvalds's avatar
Linus Torvalds committed
167
{
Hugh Dickins's avatar
Hugh Dickins committed
168
169
	int result = -ENOENT;

170
	task_lock(task);
171
172
	if (task->fs) {
		get_fs_root(task->fs, root);
Hugh Dickins's avatar
Hugh Dickins committed
173
174
		result = 0;
	}
175
	task_unlock(task);
Hugh Dickins's avatar
Hugh Dickins committed
176
	return result;
177
178
}

179
static int proc_cwd_link(struct dentry *dentry, struct path *path)
180
{
181
	struct task_struct *task = get_proc_task(d_inode(dentry));
182
	int result = -ENOENT;
183
184

	if (task) {
185
186
187
188
189
190
		task_lock(task);
		if (task->fs) {
			get_fs_pwd(task->fs, path);
			result = 0;
		}
		task_unlock(task);
191
192
		put_task_struct(task);
	}
Linus Torvalds's avatar
Linus Torvalds committed
193
194
195
	return result;
}

196
static int proc_root_link(struct dentry *dentry, struct path *path)
Linus Torvalds's avatar
Linus Torvalds committed
197
{
198
	struct task_struct *task = get_proc_task(d_inode(dentry));
Linus Torvalds's avatar
Linus Torvalds committed
199
	int result = -ENOENT;
200
201

	if (task) {
202
		result = get_task_root(task, path);
203
204
		put_task_struct(task);
	}
Linus Torvalds's avatar
Linus Torvalds committed
205
206
207
	return result;
}

208
209
static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf,
				     size_t _count, loff_t *pos)
Linus Torvalds's avatar
Linus Torvalds committed
210
{
211
212
213
214
215
216
217
	struct task_struct *tsk;
	struct mm_struct *mm;
	char *page;
	unsigned long count = _count;
	unsigned long arg_start, arg_end, env_start, env_end;
	unsigned long len1, len2, len;
	unsigned long p;
218
	char __user *buf0 = buf;
219
	char c;
220
	int rv;
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236

	BUG_ON(*pos < 0);

	tsk = get_proc_task(file_inode(file));
	if (!tsk)
		return -ESRCH;
	mm = get_task_mm(tsk);
	put_task_struct(tsk);
	if (!mm)
		return 0;
	/* Check if process spawned far enough to have cmdline. */
	if (!mm->env_end) {
		rv = 0;
		goto out_mmput;
	}

237
	page = (char *)__get_free_page(GFP_KERNEL);
238
239
240
241
242
	if (!page) {
		rv = -ENOMEM;
		goto out_mmput;
	}

243
	spin_lock(&mm->arg_lock);
244
245
246
247
	arg_start = mm->arg_start;
	arg_end = mm->arg_end;
	env_start = mm->env_start;
	env_end = mm->env_end;
248
	spin_unlock(&mm->arg_lock);
249
250
251
252
253
254
255

	BUG_ON(arg_start > arg_end);
	BUG_ON(env_start > env_end);

	len1 = arg_end - arg_start;
	len2 = env_end - env_start;

256
	/* Empty ARGV. */
257
258
259
	if (len1 == 0)
		goto end;

260
	/*
261
262
	 * Inherently racy -- command line shares address space
	 * with code and data.
263
	 */
264
265
	if (access_remote_vm(mm, arg_end - 1, &c, 1, FOLL_ANON) != 1)
		goto end;
266
267
268
269

	if (c == '\0') {
		/* Command line (set of strings) occupies whole ARGV. */
		if (len1 <= *pos)
270
			goto end;
271
272
273
274

		p = arg_start + *pos;
		len = len1 - *pos;
		while (count > 0 && len > 0) {
275
276
277
278
279
			unsigned int nr_read;

			nr_read = min3(count, len, PAGE_SIZE);
			nr_read = access_remote_vm(mm, p, page, nr_read, FOLL_ANON);
			if (nr_read == 0)
280
				goto end;
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296

			if (copy_to_user(buf, page, nr_read)) {
				rv = -EFAULT;
				goto out_free_page;
			}

			p	+= nr_read;
			len	-= nr_read;
			buf	+= nr_read;
			count	-= nr_read;
		}
	} else {
		/*
		 * Command line (1 string) occupies ARGV and
		 * extends into ENVP.
		 */
297
298
299
300
301
302
303
304
305
306
307
308
309
310
		struct {
			unsigned long p;
			unsigned long len;
		} cmdline[2] = {
			{ .p = arg_start, .len = len1 },
			{ .p = env_start, .len = len2 },
		};
		loff_t pos1 = *pos;
		unsigned int i;

		i = 0;
		while (i < 2 && pos1 >= cmdline[i].len) {
			pos1 -= cmdline[i].len;
			i++;
311
		}
312
313
314
315
		while (i < 2) {
			p = cmdline[i].p + pos1;
			len = cmdline[i].len - pos1;
			while (count > 0 && len > 0) {
316
				unsigned int nr_read, nr_write;
317

318
319
320
				nr_read = min3(count, len, PAGE_SIZE);
				nr_read = access_remote_vm(mm, p, page, nr_read, FOLL_ANON);
				if (nr_read == 0)
321
					goto end;
322
323
324
325
326

				/*
				 * Command line can be shorter than whole ARGV
				 * even if last "marker" byte says it is not.
				 */
327
				nr_write = strnlen(page, nr_read);
328

329
				if (copy_to_user(buf, page, nr_write)) {
330
331
332
333
					rv = -EFAULT;
					goto out_free_page;
				}

334
335
336
337
				p	+= nr_write;
				len	-= nr_write;
				buf	+= nr_write;
				count	-= nr_write;
338

339
				if (nr_write < nr_read)
340
					goto end;
341
342
			}

343
344
345
			/* Only first chunk can be read partially. */
			pos1 = 0;
			i++;
346
347
348
		}
	}

349
350
351
end:
	*pos += buf - buf0;
	rv = buf - buf0;
352
353
354
355
356
out_free_page:
	free_page((unsigned long)page);
out_mmput:
	mmput(mm);
	return rv;
Linus Torvalds's avatar
Linus Torvalds committed
357
358
}

359
360
361
362
363
static const struct file_operations proc_pid_cmdline_ops = {
	.read	= proc_pid_cmdline_read,
	.llseek	= generic_file_llseek,
};

Linus Torvalds's avatar
Linus Torvalds committed
364
365
366
367
368
#ifdef CONFIG_KALLSYMS
/*
 * Provides a wchan file via kallsyms in a proper one-value-per-file format.
 * Returns the resolved symbol.  If that fails, simply return the address.
 */
369
370
static int proc_pid_wchan(struct seq_file *m, struct pid_namespace *ns,
			  struct pid *pid, struct task_struct *task)
Linus Torvalds's avatar
Linus Torvalds committed
371
{
Alexey Dobriyan's avatar
Alexey Dobriyan committed
372
	unsigned long wchan;
373
	char symname[KSYM_NAME_LEN];
Linus Torvalds's avatar
Linus Torvalds committed
374

375
376
	if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
		goto print0;
Linus Torvalds's avatar
Linus Torvalds committed
377

378
379
	wchan = get_wchan(task);
	if (wchan && !lookup_symbol_name(wchan, symname)) {
380
		seq_puts(m, symname);
381
382
		return 0;
	}
383

384
385
print0:
	seq_putc(m, '0');
386
	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
387
388
389
}
#endif /* CONFIG_KALLSYMS */

390
391
392
393
394
static int lock_trace(struct task_struct *task)
{
	int err = mutex_lock_killable(&task->signal->cred_guard_mutex);
	if (err)
		return err;
395
	if (!ptrace_may_access(task, PTRACE_MODE_ATTACH_FSCREDS)) {
396
397
398
399
400
401
402
403
404
405
406
		mutex_unlock(&task->signal->cred_guard_mutex);
		return -EPERM;
	}
	return 0;
}

static void unlock_trace(struct task_struct *task)
{
	mutex_unlock(&task->signal->cred_guard_mutex);
}

Ken Chen's avatar
Ken Chen committed
407
408
409
410
411
412
413
414
415
#ifdef CONFIG_STACKTRACE

#define MAX_STACK_TRACE_DEPTH	64

static int proc_pid_stack(struct seq_file *m, struct pid_namespace *ns,
			  struct pid *pid, struct task_struct *task)
{
	struct stack_trace trace;
	unsigned long *entries;
416
	int err;
Ken Chen's avatar
Ken Chen committed
417
418
419
420
421
422
423
424
425
426
427
	int i;

	entries = kmalloc(MAX_STACK_TRACE_DEPTH * sizeof(*entries), GFP_KERNEL);
	if (!entries)
		return -ENOMEM;

	trace.nr_entries	= 0;
	trace.max_entries	= MAX_STACK_TRACE_DEPTH;
	trace.entries		= entries;
	trace.skip		= 0;

428
429
430
431
432
	err = lock_trace(task);
	if (!err) {
		save_stack_trace_tsk(task, &trace);

		for (i = 0; i < trace.nr_entries; i++) {
433
			seq_printf(m, "[<0>] %pB\n", (void *)entries[i]);
434
435
		}
		unlock_trace(task);
Ken Chen's avatar
Ken Chen committed
436
437
438
	}
	kfree(entries);

439
	return err;
Ken Chen's avatar
Ken Chen committed
440
441
442
}
#endif

443
#ifdef CONFIG_SCHED_INFO
Linus Torvalds's avatar
Linus Torvalds committed
444
445
446
/*
 * Provides /proc/PID/schedstat
 */
447
448
static int proc_pid_schedstat(struct seq_file *m, struct pid_namespace *ns,
			      struct pid *pid, struct task_struct *task)
Linus Torvalds's avatar
Linus Torvalds committed
449
{
450
451
452
453
	if (unlikely(!sched_info_on()))
		seq_printf(m, "0 0 0\n");
	else
		seq_printf(m, "%llu %llu %lu\n",
454
455
456
457
458
		   (unsigned long long)task->se.sum_exec_runtime,
		   (unsigned long long)task->sched_info.run_delay,
		   task->sched_info.pcount);

	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
459
460
461
}
#endif

Arjan van de Ven's avatar
Arjan van de Ven committed
462
463
464
465
#ifdef CONFIG_LATENCYTOP
static int lstats_show_proc(struct seq_file *m, void *v)
{
	int i;
466
467
	struct inode *inode = m->private;
	struct task_struct *task = get_proc_task(inode);
Arjan van de Ven's avatar
Arjan van de Ven committed
468

469
470
471
	if (!task)
		return -ESRCH;
	seq_puts(m, "Latency Top version : v0.1\n");
Arjan van de Ven's avatar
Arjan van de Ven committed
472
	for (i = 0; i < 32; i++) {
473
474
		struct latency_record *lr = &task->latency_record[i];
		if (lr->backtrace[0]) {
Arjan van de Ven's avatar
Arjan van de Ven committed
475
			int q;
476
477
			seq_printf(m, "%i %li %li",
				   lr->count, lr->time, lr->max);
Arjan van de Ven's avatar
Arjan van de Ven committed
478
			for (q = 0; q < LT_BACKTRACEDEPTH; q++) {
479
480
				unsigned long bt = lr->backtrace[q];
				if (!bt)
Arjan van de Ven's avatar
Arjan van de Ven committed
481
					break;
482
				if (bt == ULONG_MAX)
Arjan van de Ven's avatar
Arjan van de Ven committed
483
					break;
484
				seq_printf(m, " %ps", (void *)bt);
Arjan van de Ven's avatar
Arjan van de Ven committed
485
			}
486
			seq_putc(m, '\n');
Arjan van de Ven's avatar
Arjan van de Ven committed
487
488
489
		}

	}
490
	put_task_struct(task);
Arjan van de Ven's avatar
Arjan van de Ven committed
491
492
493
494
495
	return 0;
}

static int lstats_open(struct inode *inode, struct file *file)
{
496
	return single_open(file, lstats_show_proc, inode);
497
498
}

Arjan van de Ven's avatar
Arjan van de Ven committed
499
500
501
static ssize_t lstats_write(struct file *file, const char __user *buf,
			    size_t count, loff_t *offs)
{
Al Viro's avatar
Al Viro committed
502
	struct task_struct *task = get_proc_task(file_inode(file));
Arjan van de Ven's avatar
Arjan van de Ven committed
503

504
505
	if (!task)
		return -ESRCH;
Arjan van de Ven's avatar
Arjan van de Ven committed
506
	clear_all_latency_tracing(task);
507
	put_task_struct(task);
Arjan van de Ven's avatar
Arjan van de Ven committed
508
509
510
511
512
513
514
515
516

	return count;
}

static const struct file_operations proc_lstats_operations = {
	.open		= lstats_open,
	.read		= seq_read,
	.write		= lstats_write,
	.llseek		= seq_lseek,
517
	.release	= single_release,
Arjan van de Ven's avatar
Arjan van de Ven committed
518
519
520
521
};

#endif

522
523
static int proc_oom_score(struct seq_file *m, struct pid_namespace *ns,
			  struct pid *pid, struct task_struct *task)
Linus Torvalds's avatar
Linus Torvalds committed
524
{
525
	unsigned long totalpages = totalram_pages + total_swap_pages;
526
	unsigned long points = 0;
Linus Torvalds's avatar
Linus Torvalds committed
527

528
529
	points = oom_badness(task, NULL, NULL, totalpages) *
					1000 / totalpages;
530
531
532
	seq_printf(m, "%lu\n", points);

	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
533
534
}

535
struct limit_names {
536
537
	const char *name;
	const char *unit;
538
539
540
};

static const struct limit_names lnames[RLIM_NLIMITS] = {
541
	[RLIMIT_CPU] = {"Max cpu time", "seconds"},
542
543
544
545
546
547
548
549
550
551
552
553
554
555
	[RLIMIT_FSIZE] = {"Max file size", "bytes"},
	[RLIMIT_DATA] = {"Max data size", "bytes"},
	[RLIMIT_STACK] = {"Max stack size", "bytes"},
	[RLIMIT_CORE] = {"Max core file size", "bytes"},
	[RLIMIT_RSS] = {"Max resident set", "bytes"},
	[RLIMIT_NPROC] = {"Max processes", "processes"},
	[RLIMIT_NOFILE] = {"Max open files", "files"},
	[RLIMIT_MEMLOCK] = {"Max locked memory", "bytes"},
	[RLIMIT_AS] = {"Max address space", "bytes"},
	[RLIMIT_LOCKS] = {"Max file locks", "locks"},
	[RLIMIT_SIGPENDING] = {"Max pending signals", "signals"},
	[RLIMIT_MSGQUEUE] = {"Max msgqueue size", "bytes"},
	[RLIMIT_NICE] = {"Max nice priority", NULL},
	[RLIMIT_RTPRIO] = {"Max realtime priority", NULL},
556
	[RLIMIT_RTTIME] = {"Max realtime timeout", "us"},
557
558
559
};

/* Display limits for a process */
560
561
static int proc_pid_limits(struct seq_file *m, struct pid_namespace *ns,
			   struct pid *pid, struct task_struct *task)
562
563
564
565
566
567
{
	unsigned int i;
	unsigned long flags;

	struct rlimit rlim[RLIM_NLIMITS];

568
	if (!lock_task_sighand(task, &flags))
569
570
571
572
573
574
575
		return 0;
	memcpy(rlim, task->signal->rlim, sizeof(struct rlimit) * RLIM_NLIMITS);
	unlock_task_sighand(task, &flags);

	/*
	 * print the file header
	 */
576
       seq_printf(m, "%-25s %-20s %-20s %-10s\n",
577
		  "Limit", "Soft Limit", "Hard Limit", "Units");
578
579
580

	for (i = 0; i < RLIM_NLIMITS; i++) {
		if (rlim[i].rlim_cur == RLIM_INFINITY)
581
			seq_printf(m, "%-25s %-20s ",
582
				   lnames[i].name, "unlimited");
583
		else
584
			seq_printf(m, "%-25s %-20lu ",
585
				   lnames[i].name, rlim[i].rlim_cur);
586
587

		if (rlim[i].rlim_max == RLIM_INFINITY)
588
			seq_printf(m, "%-20s ", "unlimited");
589
		else
590
			seq_printf(m, "%-20lu ", rlim[i].rlim_max);
591
592

		if (lnames[i].unit)
593
			seq_printf(m, "%-10s\n", lnames[i].unit);
594
		else
595
			seq_putc(m, '\n');
596
597
	}

598
	return 0;
599
600
}

Roland McGrath's avatar
Roland McGrath committed
601
#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
602
603
static int proc_pid_syscall(struct seq_file *m, struct pid_namespace *ns,
			    struct pid *pid, struct task_struct *task)
Roland McGrath's avatar
Roland McGrath committed
604
605
606
{
	long nr;
	unsigned long args[6], sp, pc;
607
608
609
	int res;

	res = lock_trace(task);
610
611
	if (res)
		return res;
Roland McGrath's avatar
Roland McGrath committed
612
613

	if (task_current_syscall(task, &nr, args, 6, &sp, &pc))
614
		seq_puts(m, "running\n");
615
	else if (nr < 0)
616
		seq_printf(m, "%ld 0x%lx 0x%lx\n", nr, sp, pc);
617
	else
618
		seq_printf(m,
Roland McGrath's avatar
Roland McGrath committed
619
620
621
622
		       "%ld 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n",
		       nr,
		       args[0], args[1], args[2], args[3], args[4], args[5],
		       sp, pc);
623
	unlock_trace(task);
624
625

	return 0;
Roland McGrath's avatar
Roland McGrath committed
626
627
628
}
#endif /* CONFIG_HAVE_ARCH_TRACEHOOK */

Linus Torvalds's avatar
Linus Torvalds committed
629
630
631
632
633
/************************************************************************/
/*                       Here the fs part begins                        */
/************************************************************************/

/* permission checks */
634
static int proc_fd_access_allowed(struct inode *inode)
Linus Torvalds's avatar
Linus Torvalds committed
635
{
636
637
	struct task_struct *task;
	int allowed = 0;
638
639
640
	/* Allow access to a task's file descriptors if it is us or we
	 * may use ptrace attach to the process and find out that
	 * information.
641
642
	 */
	task = get_proc_task(inode);
643
	if (task) {
644
		allowed = ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS);
645
		put_task_struct(task);
646
	}
647
	return allowed;
Linus Torvalds's avatar
Linus Torvalds committed
648
649
}

650
int proc_setattr(struct dentry *dentry, struct iattr *attr)
651
652
{
	int error;
653
	struct inode *inode = d_inode(dentry);
654
655
656
657

	if (attr->ia_valid & ATTR_MODE)
		return -EPERM;

658
	error = setattr_prepare(dentry, attr);
Christoph Hellwig's avatar
Christoph Hellwig committed
659
660
661
662
663
664
	if (error)
		return error;

	setattr_copy(inode, attr);
	mark_inode_dirty(inode);
	return 0;
665
666
}

667
668
669
670
671
672
673
674
675
676
677
678
/*
 * May current process learn task's sched/cmdline info (for hide_pid_min=1)
 * or euid/egid (for hide_pid_min=2)?
 */
static bool has_pid_permissions(struct pid_namespace *pid,
				 struct task_struct *task,
				 int hide_pid_min)
{
	if (pid->hide_pid < hide_pid_min)
		return true;
	if (in_group_p(pid->pid_gid))
		return true;
679
	return ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS);
680
681
682
683
684
}


static int proc_pid_permission(struct inode *inode, int mask)
{
685
	struct pid_namespace *pid = proc_pid_ns(inode);
686
687
688
689
	struct task_struct *task;
	bool has_perms;

	task = get_proc_task(inode);
690
691
	if (!task)
		return -ESRCH;
692
	has_perms = has_pid_permissions(pid, task, HIDEPID_NO_ACCESS);
693
694
695
	put_task_struct(task);

	if (!has_perms) {
696
		if (pid->hide_pid == HIDEPID_INVISIBLE) {
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
			/*
			 * Let's make getdents(), stat(), and open()
			 * consistent with each other.  If a process
			 * may not stat() a file, it shouldn't be seen
			 * in procfs at all.
			 */
			return -ENOENT;
		}

		return -EPERM;
	}
	return generic_permission(inode, mask);
}



713
static const struct inode_operations proc_def_inode_operations = {
714
715
716
	.setattr	= proc_setattr,
};

717
718
719
static int proc_single_show(struct seq_file *m, void *v)
{
	struct inode *inode = m->private;
720
721
	struct pid_namespace *ns = proc_pid_ns(inode);
	struct pid *pid = proc_pid(inode);
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
	struct task_struct *task;
	int ret;

	task = get_pid_task(pid, PIDTYPE_PID);
	if (!task)
		return -ESRCH;

	ret = PROC_I(inode)->op.proc_show(m, ns, pid, task);

	put_task_struct(task);
	return ret;
}

static int proc_single_open(struct inode *inode, struct file *filp)
{
Jovi Zhang's avatar
Jovi Zhang committed
737
	return single_open(filp, proc_single_show, inode);
738
739
740
741
742
743
744
745
746
}

static const struct file_operations proc_single_file_operations = {
	.open		= proc_single_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};

747
748

struct mm_struct *proc_mem_open(struct inode *inode, unsigned int mode)
Linus Torvalds's avatar
Linus Torvalds committed
749
{
750
751
	struct task_struct *task = get_proc_task(inode);
	struct mm_struct *mm = ERR_PTR(-ESRCH);
752

753
	if (task) {
754
		mm = mm_access(task, mode | PTRACE_MODE_FSCREDS);
755
		put_task_struct(task);
756

757
758
		if (!IS_ERR_OR_NULL(mm)) {
			/* ensure this mm_struct can't be freed */
Vegard Nossum's avatar
Vegard Nossum committed
759
			mmgrab(mm);
760
761
762
763
764
765
766
767
768
769
770
			/* but do not pin its memory */
			mmput(mm);
		}
	}

	return mm;
}

static int __mem_open(struct inode *inode, struct file *file, unsigned int mode)
{
	struct mm_struct *mm = proc_mem_open(inode, mode);
771
772
773
774
775

	if (IS_ERR(mm))
		return PTR_ERR(mm);

	file->private_data = mm;
Linus Torvalds's avatar
Linus Torvalds committed
776
777
778
	return 0;
}

779
780
static int mem_open(struct inode *inode, struct file *file)
{
781
782
783
784
785
786
	int ret = __mem_open(inode, file, PTRACE_MODE_ATTACH);

	/* OK to pass negative loff_t, we can catch out-of-range */
	file->f_mode |= FMODE_UNSIGNED_OFFSET;

	return ret;
787
788
}

789
790
static ssize_t mem_rw(struct file *file, char __user *buf,
			size_t count, loff_t *ppos, int write)
Linus Torvalds's avatar
Linus Torvalds committed
791
{
792
	struct mm_struct *mm = file->private_data;
793
794
	unsigned long addr = *ppos;
	ssize_t copied;
Linus Torvalds's avatar
Linus Torvalds committed
795
	char *page;
796
	unsigned int flags;
Linus Torvalds's avatar
Linus Torvalds committed
797

798
799
	if (!mm)
		return 0;
800

801
	page = (char *)__get_free_page(GFP_KERNEL);
802
	if (!page)
803
		return -ENOMEM;
Linus Torvalds's avatar
Linus Torvalds committed
804

805
	copied = 0;
806
	if (!mmget_not_zero(mm))
807
808
		goto free;

809
	flags = FOLL_FORCE | (write ? FOLL_WRITE : 0);
810

Linus Torvalds's avatar
Linus Torvalds committed
811
	while (count > 0) {
812
		int this_len = min_t(int, count, PAGE_SIZE);
Linus Torvalds's avatar
Linus Torvalds committed
813

814
		if (write && copy_from_user(page, buf, this_len)) {
Linus Torvalds's avatar
Linus Torvalds committed
815
816
817
			copied = -EFAULT;
			break;
		}
818

819
		this_len = access_remote_vm(mm, addr, page, this_len, flags);
820
		if (!this_len) {
Linus Torvalds's avatar
Linus Torvalds committed
821
822
823
824
			if (!copied)
				copied = -EIO;
			break;
		}
825
826
827
828
829
830
831
832
833
834

		if (!write && copy_to_user(buf, page, this_len)) {
			copied = -EFAULT;
			break;
		}

		buf += this_len;
		addr += this_len;
		copied += this_len;
		count -= this_len;
Linus Torvalds's avatar
Linus Torvalds committed
835
	}
836
	*ppos = addr;
837

838
839
	mmput(mm);
free:
840
	free_page((unsigned long) page);
Linus Torvalds's avatar
Linus Torvalds committed
841
842
843
	return copied;
}

844
845
846
847
848
849
850
851
852
853
854
855
static ssize_t mem_read(struct file *file, char __user *buf,
			size_t count, loff_t *ppos)
{
	return mem_rw(file, buf, count, ppos, 0);
}

static ssize_t mem_write(struct file *file, const char __user *buf,
			 size_t count, loff_t *ppos)
{
	return mem_rw(file, (char __user*)buf, count, ppos, 1);
}

856
loff_t mem_lseek(struct file *file, loff_t offset, int orig)
Linus Torvalds's avatar
Linus Torvalds committed
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
{
	switch (orig) {
	case 0:
		file->f_pos = offset;
		break;
	case 1:
		file->f_pos += offset;
		break;
	default:
		return -EINVAL;
	}
	force_successful_syscall_return();
	return file->f_pos;
}

872
873
874
static int mem_release(struct inode *inode, struct file *file)
{
	struct mm_struct *mm = file->private_data;
875
	if (mm)
876
		mmdrop(mm);
877
878
879
	return 0;
}

880
static const struct file_operations proc_mem_operations = {
Linus Torvalds's avatar
Linus Torvalds committed
881
882
883
884
	.llseek		= mem_lseek,
	.read		= mem_read,
	.write		= mem_write,
	.open		= mem_open,
885
	.release	= mem_release,
Linus Torvalds's avatar
Linus Torvalds committed
886
887
};

888
889
890
891
892
static int environ_open(struct inode *inode, struct file *file)
{
	return __mem_open(inode, file, PTRACE_MODE_READ);
}

893
894
895
896
897
static ssize_t environ_read(struct file *file, char __user *buf,
			size_t count, loff_t *ppos)
{
	char *page;
	unsigned long src = *ppos;
898
899
	int ret = 0;
	struct mm_struct *mm = file->private_data;
900
	unsigned long env_start, env_end;
901

902
903
	/* Ensure the process spawned far enough to have an environment. */
	if (!mm || !mm->env_end)
904
		return 0;
905

906
	page = (char *)__get_free_page(GFP_KERNEL);
907
	if (!page)
908
		return -ENOMEM;
909

Al Viro's avatar
Al Viro committed
910
	ret = 0;
911
	if (!mmget_not_zero(mm))
912
		goto free;
913

914
	spin_lock(&mm->arg_lock);
915
916
	env_start = mm->env_start;
	env_end = mm->env_end;
917
	spin_unlock(&mm->arg_lock);
918

919
	while (count > 0) {
920
921
		size_t this_len, max_len;
		int retval;
922

923
		if (src >= (env_end - env_start))
924
925
			break;

926
		this_len = env_end - (env_start + src);
927
928
929

		max_len = min_t(size_t, PAGE_SIZE, count);
		this_len = min(max_len, this_len);
930

931
		retval = access_remote_vm(mm, (env_start + src), page, this_len, FOLL_ANON);
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949

		if (retval <= 0) {
			ret = retval;
			break;
		}

		if (copy_to_user(buf, page, retval)) {
			ret = -EFAULT;
			break;
		}

		ret += retval;
		src += retval;
		buf += retval;
		count -= retval;
	}
	*ppos = src;
	mmput(mm);
950
951

free:
952
953
954
955
956
	free_page((unsigned long) page);
	return ret;
}

static const struct file_operations proc_environ_operations = {
957
	.open		= environ_open,
958
	.read		= environ_read,
959
	.llseek		= generic_file_llseek,
960
	.release	= mem_release,
961
962
};

963
964
965
966
967
968
969
970
971
972
static int auxv_open(struct inode *inode, struct file *file)
{
	return __mem_open(inode, file, PTRACE_MODE_READ_FSCREDS);
}

static ssize_t auxv_read(struct file *file, char __user *buf,
			size_t count, loff_t *ppos)
{
	struct mm_struct *mm = file->private_data;
	unsigned int nwords = 0;
973
974
975

	if (!mm)
		return 0;
976
977
978
979
980
981
982
983
984
985
986
987
988
989
	do {
		nwords += 2;
	} while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
	return simple_read_from_buffer(buf, count, ppos, mm->saved_auxv,
				       nwords * sizeof(mm->saved_auxv[0]));
}

static const struct file_operations proc_auxv_operations = {
	.open		= auxv_open,
	.read		= auxv_read,
	.llseek		= generic_file_llseek,
	.release	= mem_release,
};

990
991
992
static ssize_t oom_adj_read(struct file *file, char __user *buf, size_t count,
			    loff_t *ppos)
{
Al Viro's avatar
Al Viro committed
993
	struct task_struct *task = get_proc_task(file_inode(file));
994
995
996
997
998
999
	char buffer[PROC_NUMBUF];
	int oom_adj = OOM_ADJUST_MIN;
	size_t len;

	if (!task)
		return -ESRCH;
1000
	if (task->signal->oom_score_adj == OOM_SCORE_ADJ_MAX)
For faster browsing, not all history is shown. View entire blame