base.c 85.6 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
242
243
244
245
246
247
248
249
250
251
252
253
254
	if (!page) {
		rv = -ENOMEM;
		goto out_mmput;
	}

	down_read(&mm->mmap_sem);
	arg_start = mm->arg_start;
	arg_end = mm->arg_end;
	env_start = mm->env_start;
	env_end = mm->env_end;
	up_read(&mm->mmap_sem);

	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
	rv = access_remote_vm(mm, arg_end - 1, &c, 1, 0);
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
	if (rv <= 0)
		goto out_free_page;

	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) {
			unsigned int _count;
			int nr_read;

			_count = min3(count, len, PAGE_SIZE);
282
			nr_read = access_remote_vm(mm, p, page, _count, 0);
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
			if (nr_read < 0)
				rv = nr_read;
			if (nr_read <= 0)
				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.
		 */
304
305
306
307
308
309
310
311
312
313
314
315
316
317
		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++;
318
		}
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
		while (i < 2) {
			p = cmdline[i].p + pos1;
			len = cmdline[i].len - pos1;
			while (count > 0 && len > 0) {
				unsigned int _count, l;
				int nr_read;
				bool final;

				_count = min3(count, len, PAGE_SIZE);
				nr_read = access_remote_vm(mm, p, page, _count, 0);
				if (nr_read < 0)
					rv = nr_read;
				if (nr_read <= 0)
					goto out_free_page;

				/*
				 * Command line can be shorter than whole ARGV
				 * even if last "marker" byte says it is not.
				 */
				final = false;
				l = strnlen(page, nr_read);
				if (l < nr_read) {
					nr_read = l;
					final = true;
				}

				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;

				if (final)
					goto out_free_page;
358
359
			}

360
361
362
			/* Only first chunk can be read partially. */
			pos1 = 0;
			i++;
363
364
365
366
367
368
369
370
371
372
		}
	}

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
373
374
}

375
376
377
378
379
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
380
381
382
383
384
#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.
 */
385
386
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
387
{
Alexey Dobriyan's avatar
Alexey Dobriyan committed
388
	unsigned long wchan;
389
	char symname[KSYM_NAME_LEN];
Linus Torvalds's avatar
Linus Torvalds committed
390

391
392
	if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
		goto print0;
Linus Torvalds's avatar
Linus Torvalds committed
393

394
395
	wchan = get_wchan(task);
	if (wchan && !lookup_symbol_name(wchan, symname)) {
396
		seq_printf(m, "%s", symname);
397
398
		return 0;
	}
399

400
401
print0:
	seq_putc(m, '0');
402
	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
403
404
405
}
#endif /* CONFIG_KALLSYMS */

406
407
408
409
410
static int lock_trace(struct task_struct *task)
{
	int err = mutex_lock_killable(&task->signal->cred_guard_mutex);
	if (err)
		return err;
411
	if (!ptrace_may_access(task, PTRACE_MODE_ATTACH_FSCREDS)) {
412
413
414
415
416
417
418
419
420
421
422
		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
423
424
425
426
427
428
429
430
431
#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;
432
	int err;
Ken Chen's avatar
Ken Chen committed
433
434
435
436
437
438
439
440
441
442
443
	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;

444
445
446
447
448
	err = lock_trace(task);
	if (!err) {
		save_stack_trace_tsk(task, &trace);

		for (i = 0; i < trace.nr_entries; i++) {
449
			seq_printf(m, "[<0>] %pB\n", (void *)entries[i]);
450
451
		}
		unlock_trace(task);
Ken Chen's avatar
Ken Chen committed
452
453
454
	}
	kfree(entries);

455
	return err;
Ken Chen's avatar
Ken Chen committed
456
457
458
}
#endif

459
#ifdef CONFIG_SCHED_INFO
Linus Torvalds's avatar
Linus Torvalds committed
460
461
462
/*
 * Provides /proc/PID/schedstat
 */
463
464
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
465
{
466
467
468
469
	if (unlikely(!sched_info_on()))
		seq_printf(m, "0 0 0\n");
	else
		seq_printf(m, "%llu %llu %lu\n",
470
471
472
473
474
		   (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
475
476
477
}
#endif

Arjan van de Ven's avatar
Arjan van de Ven committed
478
479
480
481
#ifdef CONFIG_LATENCYTOP
static int lstats_show_proc(struct seq_file *m, void *v)
{
	int i;
482
483
	struct inode *inode = m->private;
	struct task_struct *task = get_proc_task(inode);
Arjan van de Ven's avatar
Arjan van de Ven committed
484

485
486
487
	if (!task)
		return -ESRCH;
	seq_puts(m, "Latency Top version : v0.1\n");
Arjan van de Ven's avatar
Arjan van de Ven committed
488
	for (i = 0; i < 32; i++) {
489
490
		struct latency_record *lr = &task->latency_record[i];
		if (lr->backtrace[0]) {
Arjan van de Ven's avatar
Arjan van de Ven committed
491
			int q;
492
493
			seq_printf(m, "%i %li %li",
				   lr->count, lr->time, lr->max);
Arjan van de Ven's avatar
Arjan van de Ven committed
494
			for (q = 0; q < LT_BACKTRACEDEPTH; q++) {
495
496
				unsigned long bt = lr->backtrace[q];
				if (!bt)
Arjan van de Ven's avatar
Arjan van de Ven committed
497
					break;
498
				if (bt == ULONG_MAX)
Arjan van de Ven's avatar
Arjan van de Ven committed
499
					break;
500
				seq_printf(m, " %ps", (void *)bt);
Arjan van de Ven's avatar
Arjan van de Ven committed
501
			}
502
			seq_putc(m, '\n');
Arjan van de Ven's avatar
Arjan van de Ven committed
503
504
505
		}

	}
506
	put_task_struct(task);
Arjan van de Ven's avatar
Arjan van de Ven committed
507
508
509
510
511
	return 0;
}

static int lstats_open(struct inode *inode, struct file *file)
{
512
	return single_open(file, lstats_show_proc, inode);
513
514
}

Arjan van de Ven's avatar
Arjan van de Ven committed
515
516
517
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
518
	struct task_struct *task = get_proc_task(file_inode(file));
Arjan van de Ven's avatar
Arjan van de Ven committed
519

520
521
	if (!task)
		return -ESRCH;
Arjan van de Ven's avatar
Arjan van de Ven committed
522
	clear_all_latency_tracing(task);
523
	put_task_struct(task);
Arjan van de Ven's avatar
Arjan van de Ven committed
524
525
526
527
528
529
530
531
532

	return count;
}

static const struct file_operations proc_lstats_operations = {
	.open		= lstats_open,
	.read		= seq_read,
	.write		= lstats_write,
	.llseek		= seq_lseek,
533
	.release	= single_release,
Arjan van de Ven's avatar
Arjan van de Ven committed
534
535
536
537
};

#endif

538
539
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
540
{
541
	unsigned long totalpages = totalram_pages + total_swap_pages;
542
	unsigned long points = 0;
Linus Torvalds's avatar
Linus Torvalds committed
543

544
545
	points = oom_badness(task, NULL, NULL, totalpages) *
					1000 / totalpages;
546
547
548
	seq_printf(m, "%lu\n", points);

	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
549
550
}

551
struct limit_names {
552
553
	const char *name;
	const char *unit;
554
555
556
};

static const struct limit_names lnames[RLIM_NLIMITS] = {
557
	[RLIMIT_CPU] = {"Max cpu time", "seconds"},
558
559
560
561
562
563
564
565
566
567
568
569
570
571
	[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},
572
	[RLIMIT_RTTIME] = {"Max realtime timeout", "us"},
573
574
575
};

/* Display limits for a process */
576
577
static int proc_pid_limits(struct seq_file *m, struct pid_namespace *ns,
			   struct pid *pid, struct task_struct *task)
578
579
580
581
582
583
{
	unsigned int i;
	unsigned long flags;

	struct rlimit rlim[RLIM_NLIMITS];

584
	if (!lock_task_sighand(task, &flags))
585
586
587
588
589
590
591
		return 0;
	memcpy(rlim, task->signal->rlim, sizeof(struct rlimit) * RLIM_NLIMITS);
	unlock_task_sighand(task, &flags);

	/*
	 * print the file header
	 */
592
       seq_printf(m, "%-25s %-20s %-20s %-10s\n",
593
		  "Limit", "Soft Limit", "Hard Limit", "Units");
594
595
596

	for (i = 0; i < RLIM_NLIMITS; i++) {
		if (rlim[i].rlim_cur == RLIM_INFINITY)
597
			seq_printf(m, "%-25s %-20s ",
598
				   lnames[i].name, "unlimited");
599
		else
600
			seq_printf(m, "%-25s %-20lu ",
601
				   lnames[i].name, rlim[i].rlim_cur);
602
603

		if (rlim[i].rlim_max == RLIM_INFINITY)
604
			seq_printf(m, "%-20s ", "unlimited");
605
		else
606
			seq_printf(m, "%-20lu ", rlim[i].rlim_max);
607
608

		if (lnames[i].unit)
609
			seq_printf(m, "%-10s\n", lnames[i].unit);
610
		else
611
			seq_putc(m, '\n');
612
613
	}

614
	return 0;
615
616
}

Roland McGrath's avatar
Roland McGrath committed
617
#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
618
619
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
620
621
622
{
	long nr;
	unsigned long args[6], sp, pc;
623
624
625
	int res;

	res = lock_trace(task);
626
627
	if (res)
		return res;
Roland McGrath's avatar
Roland McGrath committed
628
629

	if (task_current_syscall(task, &nr, args, 6, &sp, &pc))
630
		seq_puts(m, "running\n");
631
	else if (nr < 0)
632
		seq_printf(m, "%ld 0x%lx 0x%lx\n", nr, sp, pc);
633
	else
634
		seq_printf(m,
Roland McGrath's avatar
Roland McGrath committed
635
636
637
638
		       "%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);
639
	unlock_trace(task);
640
641

	return 0;
Roland McGrath's avatar
Roland McGrath committed
642
643
644
}
#endif /* CONFIG_HAVE_ARCH_TRACEHOOK */

Linus Torvalds's avatar
Linus Torvalds committed
645
646
647
648
649
/************************************************************************/
/*                       Here the fs part begins                        */
/************************************************************************/

/* permission checks */
650
static int proc_fd_access_allowed(struct inode *inode)
Linus Torvalds's avatar
Linus Torvalds committed
651
{
652
653
	struct task_struct *task;
	int allowed = 0;
654
655
656
	/* 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.
657
658
	 */
	task = get_proc_task(inode);
659
	if (task) {
660
		allowed = ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS);
661
		put_task_struct(task);
662
	}
663
	return allowed;
Linus Torvalds's avatar
Linus Torvalds committed
664
665
}

666
int proc_setattr(struct dentry *dentry, struct iattr *attr)
667
668
{
	int error;
669
	struct inode *inode = d_inode(dentry);
670
671
672
673

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

674
	error = setattr_prepare(dentry, attr);
Christoph Hellwig's avatar
Christoph Hellwig committed
675
676
677
678
679
680
	if (error)
		return error;

	setattr_copy(inode, attr);
	mark_inode_dirty(inode);
	return 0;
681
682
}

683
684
685
686
687
688
689
690
691
692
693
694
/*
 * 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;
695
	return ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS);
696
697
698
699
700
701
702
703
704
705
}


static int proc_pid_permission(struct inode *inode, int mask)
{
	struct pid_namespace *pid = inode->i_sb->s_fs_info;
	struct task_struct *task;
	bool has_perms;

	task = get_proc_task(inode);
706
707
	if (!task)
		return -ESRCH;
708
	has_perms = has_pid_permissions(pid, task, HIDEPID_NO_ACCESS);
709
710
711
	put_task_struct(task);

	if (!has_perms) {
712
		if (pid->hide_pid == HIDEPID_INVISIBLE) {
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
			/*
			 * 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);
}



729
static const struct inode_operations proc_def_inode_operations = {
730
731
732
	.setattr	= proc_setattr,
};

733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
static int proc_single_show(struct seq_file *m, void *v)
{
	struct inode *inode = m->private;
	struct pid_namespace *ns;
	struct pid *pid;
	struct task_struct *task;
	int ret;

	ns = inode->i_sb->s_fs_info;
	pid = proc_pid(inode);
	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
755
	return single_open(filp, proc_single_show, inode);
756
757
758
759
760
761
762
763
764
}

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

765
766

struct mm_struct *proc_mem_open(struct inode *inode, unsigned int mode)
Linus Torvalds's avatar
Linus Torvalds committed
767
{
768
769
	struct task_struct *task = get_proc_task(inode);
	struct mm_struct *mm = ERR_PTR(-ESRCH);
770

771
	if (task) {
772
		mm = mm_access(task, mode | PTRACE_MODE_FSCREDS);
773
		put_task_struct(task);
774

775
776
		if (!IS_ERR_OR_NULL(mm)) {
			/* ensure this mm_struct can't be freed */
Vegard Nossum's avatar
Vegard Nossum committed
777
			mmgrab(mm);
778
779
780
781
782
783
784
785
786
787
788
			/* 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);
789
790
791
792
793

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

	file->private_data = mm;
Linus Torvalds's avatar
Linus Torvalds committed
794
795
796
	return 0;
}

797
798
static int mem_open(struct inode *inode, struct file *file)
{
799
800
801
802
803
804
	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;
805
806
}

807
808
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
809
{
810
	struct mm_struct *mm = file->private_data;
811
812
	unsigned long addr = *ppos;
	ssize_t copied;
Linus Torvalds's avatar
Linus Torvalds committed
813
	char *page;
814
	unsigned int flags;
Linus Torvalds's avatar
Linus Torvalds committed
815

816
817
	if (!mm)
		return 0;
818

819
	page = (char *)__get_free_page(GFP_KERNEL);
820
	if (!page)
821
		return -ENOMEM;
Linus Torvalds's avatar
Linus Torvalds committed
822

823
	copied = 0;
824
	if (!mmget_not_zero(mm))
825
826
		goto free;

827
	flags = FOLL_FORCE | (write ? FOLL_WRITE : 0);
828

Linus Torvalds's avatar
Linus Torvalds committed
829
	while (count > 0) {
830
		int this_len = min_t(int, count, PAGE_SIZE);
Linus Torvalds's avatar
Linus Torvalds committed
831

832
		if (write && copy_from_user(page, buf, this_len)) {
Linus Torvalds's avatar
Linus Torvalds committed
833
834
835
			copied = -EFAULT;
			break;
		}
836

837
		this_len = access_remote_vm(mm, addr, page, this_len, flags);
838
		if (!this_len) {
Linus Torvalds's avatar
Linus Torvalds committed
839
840
841
842
			if (!copied)
				copied = -EIO;
			break;
		}
843
844
845
846
847
848
849
850
851
852

		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
853
	}
854
	*ppos = addr;
855

856
857
	mmput(mm);
free:
858
	free_page((unsigned long) page);
Linus Torvalds's avatar
Linus Torvalds committed
859
860
861
	return copied;
}

862
863
864
865
866
867
868
869
870
871
872
873
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);
}

874
loff_t mem_lseek(struct file *file, loff_t offset, int orig)
Linus Torvalds's avatar
Linus Torvalds committed
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
{
	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;
}

890
891
892
static int mem_release(struct inode *inode, struct file *file)
{
	struct mm_struct *mm = file->private_data;
893
	if (mm)
894
		mmdrop(mm);
895
896
897
	return 0;
}

898
static const struct file_operations proc_mem_operations = {
Linus Torvalds's avatar
Linus Torvalds committed
899
900
901
902
	.llseek		= mem_lseek,
	.read		= mem_read,
	.write		= mem_write,
	.open		= mem_open,
903
	.release	= mem_release,
Linus Torvalds's avatar
Linus Torvalds committed
904
905
};

906
907
908
909
910
static int environ_open(struct inode *inode, struct file *file)
{
	return __mem_open(inode, file, PTRACE_MODE_READ);
}

911
912
913
914
915
static ssize_t environ_read(struct file *file, char __user *buf,
			size_t count, loff_t *ppos)
{
	char *page;
	unsigned long src = *ppos;
916
917
	int ret = 0;
	struct mm_struct *mm = file->private_data;
918
	unsigned long env_start, env_end;
919

920
921
	/* Ensure the process spawned far enough to have an environment. */
	if (!mm || !mm->env_end)
922
		return 0;
923

924
	page = (char *)__get_free_page(GFP_KERNEL);
925
	if (!page)
926
		return -ENOMEM;
927

Al Viro's avatar
Al Viro committed
928
	ret = 0;
929
	if (!mmget_not_zero(mm))
930
		goto free;
931
932
933
934
935
936

	down_read(&mm->mmap_sem);
	env_start = mm->env_start;
	env_end = mm->env_end;
	up_read(&mm->mmap_sem);

937
	while (count > 0) {
938
939
		size_t this_len, max_len;
		int retval;
940

941
		if (src >= (env_end - env_start))
942
943
			break;

944
		this_len = env_end - (env_start + src);
945
946
947

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

949
		retval = access_remote_vm(mm, (env_start + src), page, this_len, 0);
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967

		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);
968
969

free:
970
971
972
973
974
	free_page((unsigned long) page);
	return ret;
}

static const struct file_operations proc_environ_operations = {
975
	.open		= environ_open,
976
	.read		= environ_read,
977
	.llseek		= generic_file_llseek,
978
	.release	= mem_release,
979
980
};

981
982
983
984
985
986
987
988
989
990
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;
991
992
993

	if (!mm)
		return 0;
994
995
996
997
998
999
1000
	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]));
}

For faster browsing, not all history is shown. View entire blame