base.c 85.4 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
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
	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;
	char c;
	ssize_t rv;

	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;
	}

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

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

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

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

255
256
257
258
259
	/* Empty ARGV. */
	if (len1 == 0) {
		rv = 0;
		goto out_free_page;
	}
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) {
		rv = 0;
266
		goto out_free_page;
267
	}
268
269
270
271
272
273
274
275
276
277
278

	rv = 0;

	if (c == '\0') {
		/* Command line (set of strings) occupies whole ARGV. */
		if (len1 <= *pos)
			goto out_free_page;

		p = arg_start + *pos;
		len = len1 - *pos;
		while (count > 0 && len > 0) {
279
280
281
282
283
			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)
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
				goto out_free_page;

			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;
			rv	+= nr_read;
		}
	} else {
		/*
		 * Command line (1 string) occupies ARGV and
		 * extends into ENVP.
		 */
302
303
304
305
306
307
308
309
310
311
312
313
314
315
		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++;
316
		}
317
318
319
320
		while (i < 2) {
			p = cmdline[i].p + pos1;
			len = cmdline[i].len - pos1;
			while (count > 0 && len > 0) {
321
				unsigned int nr_read, nr_write;
322

323
324
325
				nr_read = min3(count, len, PAGE_SIZE);
				nr_read = access_remote_vm(mm, p, page, nr_read, FOLL_ANON);
				if (nr_read == 0)
326
327
328
329
330
331
					goto out_free_page;

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

334
				if (copy_to_user(buf, page, nr_write)) {
335
336
337
338
					rv = -EFAULT;
					goto out_free_page;
				}

339
340
341
342
343
				p	+= nr_write;
				len	-= nr_write;
				buf	+= nr_write;
				count	-= nr_write;
				rv	+= nr_write;
344

345
				if (nr_write < nr_read)
346
					goto out_free_page;
347
348
			}

349
350
351
			/* Only first chunk can be read partially. */
			pos1 = 0;
			i++;
352
353
354
355
356
357
358
359
360
361
		}
	}

out_free_page:
	free_page((unsigned long)page);
out_mmput:
	mmput(mm);
	if (rv > 0)
		*pos += rv;
	return rv;
Linus Torvalds's avatar
Linus Torvalds committed
362
363
}

364
365
366
367
368
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
369
370
371
372
373
#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.
 */
374
375
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
376
{
Alexey Dobriyan's avatar
Alexey Dobriyan committed
377
	unsigned long wchan;
378
	char symname[KSYM_NAME_LEN];
Linus Torvalds's avatar
Linus Torvalds committed
379

380
381
	if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
		goto print0;
Linus Torvalds's avatar
Linus Torvalds committed
382

383
384
	wchan = get_wchan(task);
	if (wchan && !lookup_symbol_name(wchan, symname)) {
385
		seq_puts(m, symname);
386
387
		return 0;
	}
388

389
390
print0:
	seq_putc(m, '0');
391
	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
392
393
394
}
#endif /* CONFIG_KALLSYMS */

395
396
397
398
399
static int lock_trace(struct task_struct *task)
{
	int err = mutex_lock_killable(&task->signal->cred_guard_mutex);
	if (err)
		return err;
400
	if (!ptrace_may_access(task, PTRACE_MODE_ATTACH_FSCREDS)) {
401
402
403
404
405
406
407
408
409
410
411
		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
412
413
414
415
416
417
418
419
420
#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;
421
	int err;
Ken Chen's avatar
Ken Chen committed
422
423
424
425
426
427
428
429
430
431
432
	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;

433
434
435
436
437
	err = lock_trace(task);
	if (!err) {
		save_stack_trace_tsk(task, &trace);

		for (i = 0; i < trace.nr_entries; i++) {
438
			seq_printf(m, "[<0>] %pB\n", (void *)entries[i]);
439
440
		}
		unlock_trace(task);
Ken Chen's avatar
Ken Chen committed
441
442
443
	}
	kfree(entries);

444
	return err;
Ken Chen's avatar
Ken Chen committed
445
446
447
}
#endif

448
#ifdef CONFIG_SCHED_INFO
Linus Torvalds's avatar
Linus Torvalds committed
449
450
451
/*
 * Provides /proc/PID/schedstat
 */
452
453
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
454
{
455
456
457
458
	if (unlikely(!sched_info_on()))
		seq_printf(m, "0 0 0\n");
	else
		seq_printf(m, "%llu %llu %lu\n",
459
460
461
462
463
		   (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
464
465
466
}
#endif

Arjan van de Ven's avatar
Arjan van de Ven committed
467
468
469
470
#ifdef CONFIG_LATENCYTOP
static int lstats_show_proc(struct seq_file *m, void *v)
{
	int i;
471
472
	struct inode *inode = m->private;
	struct task_struct *task = get_proc_task(inode);
Arjan van de Ven's avatar
Arjan van de Ven committed
473

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

	}
495
	put_task_struct(task);
Arjan van de Ven's avatar
Arjan van de Ven committed
496
497
498
499
500
	return 0;
}

static int lstats_open(struct inode *inode, struct file *file)
{
501
	return single_open(file, lstats_show_proc, inode);
502
503
}

Arjan van de Ven's avatar
Arjan van de Ven committed
504
505
506
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
507
	struct task_struct *task = get_proc_task(file_inode(file));
Arjan van de Ven's avatar
Arjan van de Ven committed
508

509
510
	if (!task)
		return -ESRCH;
Arjan van de Ven's avatar
Arjan van de Ven committed
511
	clear_all_latency_tracing(task);
512
	put_task_struct(task);
Arjan van de Ven's avatar
Arjan van de Ven committed
513
514
515
516
517
518
519
520
521

	return count;
}

static const struct file_operations proc_lstats_operations = {
	.open		= lstats_open,
	.read		= seq_read,
	.write		= lstats_write,
	.llseek		= seq_lseek,
522
	.release	= single_release,
Arjan van de Ven's avatar
Arjan van de Ven committed
523
524
525
526
};

#endif

527
528
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
529
{
530
	unsigned long totalpages = totalram_pages + total_swap_pages;
531
	unsigned long points = 0;
Linus Torvalds's avatar
Linus Torvalds committed
532

533
534
	points = oom_badness(task, NULL, NULL, totalpages) *
					1000 / totalpages;
535
536
537
	seq_printf(m, "%lu\n", points);

	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
538
539
}

540
struct limit_names {
541
542
	const char *name;
	const char *unit;
543
544
545
};

static const struct limit_names lnames[RLIM_NLIMITS] = {
546
	[RLIMIT_CPU] = {"Max cpu time", "seconds"},
547
548
549
550
551
552
553
554
555
556
557
558
559
560
	[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},
561
	[RLIMIT_RTTIME] = {"Max realtime timeout", "us"},
562
563
564
};

/* Display limits for a process */
565
566
static int proc_pid_limits(struct seq_file *m, struct pid_namespace *ns,
			   struct pid *pid, struct task_struct *task)
567
568
569
570
571
572
{
	unsigned int i;
	unsigned long flags;

	struct rlimit rlim[RLIM_NLIMITS];

573
	if (!lock_task_sighand(task, &flags))
574
575
576
577
578
579
580
		return 0;
	memcpy(rlim, task->signal->rlim, sizeof(struct rlimit) * RLIM_NLIMITS);
	unlock_task_sighand(task, &flags);

	/*
	 * print the file header
	 */
581
       seq_printf(m, "%-25s %-20s %-20s %-10s\n",
582
		  "Limit", "Soft Limit", "Hard Limit", "Units");
583
584
585

	for (i = 0; i < RLIM_NLIMITS; i++) {
		if (rlim[i].rlim_cur == RLIM_INFINITY)
586
			seq_printf(m, "%-25s %-20s ",
587
				   lnames[i].name, "unlimited");
588
		else
589
			seq_printf(m, "%-25s %-20lu ",
590
				   lnames[i].name, rlim[i].rlim_cur);
591
592

		if (rlim[i].rlim_max == RLIM_INFINITY)
593
			seq_printf(m, "%-20s ", "unlimited");
594
		else
595
			seq_printf(m, "%-20lu ", rlim[i].rlim_max);
596
597

		if (lnames[i].unit)
598
			seq_printf(m, "%-10s\n", lnames[i].unit);
599
		else
600
			seq_putc(m, '\n');
601
602
	}

603
	return 0;
604
605
}

Roland McGrath's avatar
Roland McGrath committed
606
#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
607
608
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
609
610
611
{
	long nr;
	unsigned long args[6], sp, pc;
612
613
614
	int res;

	res = lock_trace(task);
615
616
	if (res)
		return res;
Roland McGrath's avatar
Roland McGrath committed
617
618

	if (task_current_syscall(task, &nr, args, 6, &sp, &pc))
619
		seq_puts(m, "running\n");
620
	else if (nr < 0)
621
		seq_printf(m, "%ld 0x%lx 0x%lx\n", nr, sp, pc);
622
	else
623
		seq_printf(m,
Roland McGrath's avatar
Roland McGrath committed
624
625
626
627
		       "%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);
628
	unlock_trace(task);
629
630

	return 0;
Roland McGrath's avatar
Roland McGrath committed
631
632
633
}
#endif /* CONFIG_HAVE_ARCH_TRACEHOOK */

Linus Torvalds's avatar
Linus Torvalds committed
634
635
636
637
638
/************************************************************************/
/*                       Here the fs part begins                        */
/************************************************************************/

/* permission checks */
639
static int proc_fd_access_allowed(struct inode *inode)
Linus Torvalds's avatar
Linus Torvalds committed
640
{
641
642
	struct task_struct *task;
	int allowed = 0;
643
644
645
	/* 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.
646
647
	 */
	task = get_proc_task(inode);
648
	if (task) {
649
		allowed = ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS);
650
		put_task_struct(task);
651
	}
652
	return allowed;
Linus Torvalds's avatar
Linus Torvalds committed
653
654
}

655
int proc_setattr(struct dentry *dentry, struct iattr *attr)
656
657
{
	int error;
658
	struct inode *inode = d_inode(dentry);
659
660
661
662

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

663
	error = setattr_prepare(dentry, attr);
Christoph Hellwig's avatar
Christoph Hellwig committed
664
665
666
667
668
669
	if (error)
		return error;

	setattr_copy(inode, attr);
	mark_inode_dirty(inode);
	return 0;
670
671
}

672
673
674
675
676
677
678
679
680
681
682
683
/*
 * 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;
684
	return ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS);
685
686
687
688
689
}


static int proc_pid_permission(struct inode *inode, int mask)
{
690
	struct pid_namespace *pid = proc_pid_ns(inode);
691
692
693
694
	struct task_struct *task;
	bool has_perms;

	task = get_proc_task(inode);
695
696
	if (!task)
		return -ESRCH;
697
	has_perms = has_pid_permissions(pid, task, HIDEPID_NO_ACCESS);
698
699
700
	put_task_struct(task);

	if (!has_perms) {
701
		if (pid->hide_pid == HIDEPID_INVISIBLE) {
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
			/*
			 * 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);
}



718
static const struct inode_operations proc_def_inode_operations = {
719
720
721
	.setattr	= proc_setattr,
};

722
723
724
static int proc_single_show(struct seq_file *m, void *v)
{
	struct inode *inode = m->private;
725
726
	struct pid_namespace *ns = proc_pid_ns(inode);
	struct pid *pid = proc_pid(inode);
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
	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
742
	return single_open(filp, proc_single_show, inode);
743
744
745
746
747
748
749
750
751
}

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

752
753

struct mm_struct *proc_mem_open(struct inode *inode, unsigned int mode)
Linus Torvalds's avatar
Linus Torvalds committed
754
{
755
756
	struct task_struct *task = get_proc_task(inode);
	struct mm_struct *mm = ERR_PTR(-ESRCH);
757

758
	if (task) {
759
		mm = mm_access(task, mode | PTRACE_MODE_FSCREDS);
760
		put_task_struct(task);
761

762
763
		if (!IS_ERR_OR_NULL(mm)) {
			/* ensure this mm_struct can't be freed */
Vegard Nossum's avatar
Vegard Nossum committed
764
			mmgrab(mm);
765
766
767
768
769
770
771
772
773
774
775
			/* 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);
776
777
778
779
780

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

	file->private_data = mm;
Linus Torvalds's avatar
Linus Torvalds committed
781
782
783
	return 0;
}

784
785
static int mem_open(struct inode *inode, struct file *file)
{
786
787
788
789
790
791
	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;
792
793
}

794
795
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
796
{
797
	struct mm_struct *mm = file->private_data;
798
799
	unsigned long addr = *ppos;
	ssize_t copied;
Linus Torvalds's avatar
Linus Torvalds committed
800
	char *page;
801
	unsigned int flags;
Linus Torvalds's avatar
Linus Torvalds committed
802

803
804
	if (!mm)
		return 0;
805

806
	page = (char *)__get_free_page(GFP_KERNEL);
807
	if (!page)
808
		return -ENOMEM;
Linus Torvalds's avatar
Linus Torvalds committed
809

810
	copied = 0;
811
	if (!mmget_not_zero(mm))
812
813
		goto free;

814
	flags = FOLL_FORCE | (write ? FOLL_WRITE : 0);
815

Linus Torvalds's avatar
Linus Torvalds committed
816
	while (count > 0) {
817
		int this_len = min_t(int, count, PAGE_SIZE);
Linus Torvalds's avatar
Linus Torvalds committed
818

819
		if (write && copy_from_user(page, buf, this_len)) {
Linus Torvalds's avatar
Linus Torvalds committed
820
821
822
			copied = -EFAULT;
			break;
		}
823

824
		this_len = access_remote_vm(mm, addr, page, this_len, flags);
825
		if (!this_len) {
Linus Torvalds's avatar
Linus Torvalds committed
826
827
828
829
			if (!copied)
				copied = -EIO;
			break;
		}
830
831
832
833
834
835
836
837
838
839

		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
840
	}
841
	*ppos = addr;
842

843
844
	mmput(mm);
free:
845
	free_page((unsigned long) page);
Linus Torvalds's avatar
Linus Torvalds committed
846
847
848
	return copied;
}

849
850
851
852
853
854
855
856
857
858
859
860
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);
}

861
loff_t mem_lseek(struct file *file, loff_t offset, int orig)
Linus Torvalds's avatar
Linus Torvalds committed
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
{
	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;
}

877
878
879
static int mem_release(struct inode *inode, struct file *file)
{
	struct mm_struct *mm = file->private_data;
880
	if (mm)
881
		mmdrop(mm);
882
883
884
	return 0;
}

885
static const struct file_operations proc_mem_operations = {
Linus Torvalds's avatar
Linus Torvalds committed
886
887
888
889
	.llseek		= mem_lseek,
	.read		= mem_read,
	.write		= mem_write,
	.open		= mem_open,
890
	.release	= mem_release,
Linus Torvalds's avatar
Linus Torvalds committed
891
892
};

893
894
895
896
897
static int environ_open(struct inode *inode, struct file *file)
{
	return __mem_open(inode, file, PTRACE_MODE_READ);
}

898
899
900
901
902
static ssize_t environ_read(struct file *file, char __user *buf,
			size_t count, loff_t *ppos)
{
	char *page;
	unsigned long src = *ppos;
903
904
	int ret = 0;
	struct mm_struct *mm = file->private_data;
905
	unsigned long env_start, env_end;
906

907
908
	/* Ensure the process spawned far enough to have an environment. */
	if (!mm || !mm->env_end)
909
		return 0;
910

911
	page = (char *)__get_free_page(GFP_KERNEL);
912
	if (!page)
913
		return -ENOMEM;
914

Al Viro's avatar
Al Viro committed
915
	ret = 0;
916
	if (!mmget_not_zero(mm))
917
		goto free;
918

919
	spin_lock(&mm->arg_lock);
920
921
	env_start = mm->env_start;
	env_end = mm->env_end;
922
	spin_unlock(&mm->arg_lock);
923

924
	while (count > 0) {
925
926
		size_t this_len, max_len;
		int retval;
927

928
		if (src >= (env_end - env_start))
929
930
			break;

931
		this_len = env_end - (env_start + src);
932
933
934

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

936
		retval = access_remote_vm(mm, (env_start + src), page, this_len, FOLL_ANON);
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954

		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);
955
956

free:
957
958
959
960
961
	free_page((unsigned long) page);
	return ret;
}

static const struct file_operations proc_environ_operations = {
962
	.open		= environ_open,
963
	.read		= environ_read,
964
	.llseek		= generic_file_llseek,
965
	.release	= mem_release,
966
967
};

968
969
970
971
972
973
974
975
976
977
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;
978
979
980

	if (!mm)
		return 0;
981
982
983
984
985
986
987
988
989
990
991
992
993
994
	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,
};

995
996
997
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
998
	struct task_struct *task = get_proc_task(file_inode(file));
999
1000
	char buffer[PROC_NUMBUF];
	int oom_adj = OOM_ADJUST_MIN;
For faster browsing, not all history is shown. View entire blame