Blame view

fs/coredump.c 20.7 KB
10c28d937   Alex Kelly   coredump: move co...
1
2
3
  #include <linux/slab.h>
  #include <linux/file.h>
  #include <linux/fdtable.h>
70d78fe7c   Andrey Ryabinin   coredump: fix unf...
4
  #include <linux/freezer.h>
10c28d937   Alex Kelly   coredump: move co...
5
6
7
8
9
10
11
12
13
14
15
16
17
  #include <linux/mm.h>
  #include <linux/stat.h>
  #include <linux/fcntl.h>
  #include <linux/swap.h>
  #include <linux/string.h>
  #include <linux/init.h>
  #include <linux/pagemap.h>
  #include <linux/perf_event.h>
  #include <linux/highmem.h>
  #include <linux/spinlock.h>
  #include <linux/key.h>
  #include <linux/personality.h>
  #include <linux/binfmts.h>
179899fd5   Alex Kelly   coredump: update ...
18
  #include <linux/coredump.h>
10c28d937   Alex Kelly   coredump: move co...
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
  #include <linux/utsname.h>
  #include <linux/pid_namespace.h>
  #include <linux/module.h>
  #include <linux/namei.h>
  #include <linux/mount.h>
  #include <linux/security.h>
  #include <linux/syscalls.h>
  #include <linux/tsacct_kern.h>
  #include <linux/cn_proc.h>
  #include <linux/audit.h>
  #include <linux/tracehook.h>
  #include <linux/kmod.h>
  #include <linux/fsnotify.h>
  #include <linux/fs_struct.h>
  #include <linux/pipe_fs_i.h>
  #include <linux/oom.h>
  #include <linux/compat.h>
378c6520e   Jann Horn   fs/coredump: prev...
36
37
38
  #include <linux/sched.h>
  #include <linux/fs.h>
  #include <linux/path.h>
03927c8ac   Arnd Bergmann   coredump: Use 64b...
39
  #include <linux/timekeeping.h>
10c28d937   Alex Kelly   coredump: move co...
40
41
42
43
44
45
46
47
48
49
50
51
  
  #include <asm/uaccess.h>
  #include <asm/mmu_context.h>
  #include <asm/tlb.h>
  #include <asm/exec.h>
  
  #include <trace/events/task.h>
  #include "internal.h"
  
  #include <trace/events/sched.h>
  
  int core_uses_pid;
10c28d937   Alex Kelly   coredump: move co...
52
  unsigned int core_pipe_limit;
3ceadcf6d   Oleg Nesterov   coredump: kill ca...
53
54
  char core_pattern[CORENAME_MAX_SIZE] = "core";
  static int core_name_size = CORENAME_MAX_SIZE;
10c28d937   Alex Kelly   coredump: move co...
55
56
57
58
59
  
  struct core_name {
  	char *corename;
  	int used, size;
  };
10c28d937   Alex Kelly   coredump: move co...
60
61
  
  /* The maximal length of core_pattern is also specified in sysctl.c */
3ceadcf6d   Oleg Nesterov   coredump: kill ca...
62
  static int expand_corename(struct core_name *cn, int size)
10c28d937   Alex Kelly   coredump: move co...
63
  {
e7fd1549a   Oleg Nesterov   coredump: format_...
64
  	char *corename = krealloc(cn->corename, size, GFP_KERNEL);
10c28d937   Alex Kelly   coredump: move co...
65

e7fd1549a   Oleg Nesterov   coredump: format_...
66
  	if (!corename)
10c28d937   Alex Kelly   coredump: move co...
67
  		return -ENOMEM;
10c28d937   Alex Kelly   coredump: move co...
68

3ceadcf6d   Oleg Nesterov   coredump: kill ca...
69
70
71
72
  	if (size > core_name_size) /* racy but harmless */
  		core_name_size = size;
  
  	cn->size = ksize(corename);
e7fd1549a   Oleg Nesterov   coredump: format_...
73
  	cn->corename = corename;
10c28d937   Alex Kelly   coredump: move co...
74
75
  	return 0;
  }
b4176b7c1   Nicolas Iooss   coredump: add __p...
76
77
  static __printf(2, 0) int cn_vprintf(struct core_name *cn, const char *fmt,
  				     va_list arg)
10c28d937   Alex Kelly   coredump: move co...
78
  {
5fe9d8ca2   Oleg Nesterov   coredump: cn_vpri...
79
  	int free, need;
404ca80eb   Eric Dumazet   coredump: fix va_...
80
  	va_list arg_copy;
10c28d937   Alex Kelly   coredump: move co...
81

5fe9d8ca2   Oleg Nesterov   coredump: cn_vpri...
82
83
  again:
  	free = cn->size - cn->used;
404ca80eb   Eric Dumazet   coredump: fix va_...
84
85
86
87
  
  	va_copy(arg_copy, arg);
  	need = vsnprintf(cn->corename + cn->used, free, fmt, arg_copy);
  	va_end(arg_copy);
5fe9d8ca2   Oleg Nesterov   coredump: cn_vpri...
88
89
90
91
  	if (need < free) {
  		cn->used += need;
  		return 0;
  	}
10c28d937   Alex Kelly   coredump: move co...
92

3ceadcf6d   Oleg Nesterov   coredump: kill ca...
93
  	if (!expand_corename(cn, cn->size + need - free + 1))
5fe9d8ca2   Oleg Nesterov   coredump: cn_vpri...
94
  		goto again;
10c28d937   Alex Kelly   coredump: move co...
95

5fe9d8ca2   Oleg Nesterov   coredump: cn_vpri...
96
  	return -ENOMEM;
10c28d937   Alex Kelly   coredump: move co...
97
  }
b4176b7c1   Nicolas Iooss   coredump: add __p...
98
  static __printf(2, 3) int cn_printf(struct core_name *cn, const char *fmt, ...)
bc03c691a   Oleg Nesterov   coredump: introdu...
99
100
101
102
103
104
105
106
107
108
  {
  	va_list arg;
  	int ret;
  
  	va_start(arg, fmt);
  	ret = cn_vprintf(cn, fmt, arg);
  	va_end(arg);
  
  	return ret;
  }
b4176b7c1   Nicolas Iooss   coredump: add __p...
109
110
  static __printf(2, 3)
  int cn_esc_printf(struct core_name *cn, const char *fmt, ...)
10c28d937   Alex Kelly   coredump: move co...
111
  {
923bed030   Oleg Nesterov   coredump: kill cn...
112
113
114
115
116
117
118
  	int cur = cn->used;
  	va_list arg;
  	int ret;
  
  	va_start(arg, fmt);
  	ret = cn_vprintf(cn, fmt, arg);
  	va_end(arg);
ac94b6e3b   Jann Horn   fs/coredump: prev...
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
  	if (ret == 0) {
  		/*
  		 * Ensure that this coredump name component can't cause the
  		 * resulting corefile path to consist of a ".." or ".".
  		 */
  		if ((cn->used - cur == 1 && cn->corename[cur] == '.') ||
  				(cn->used - cur == 2 && cn->corename[cur] == '.'
  				&& cn->corename[cur+1] == '.'))
  			cn->corename[cur] = '!';
  
  		/*
  		 * Empty names are fishy and could be used to create a "//" in a
  		 * corefile name, causing the coredump to happen one directory
  		 * level too high. Enforce that all components of the core
  		 * pattern are at least one character long.
  		 */
  		if (cn->used == cur)
  			ret = cn_printf(cn, "!");
  	}
923bed030   Oleg Nesterov   coredump: kill cn...
138
139
140
141
142
  	for (; cur < cn->used; ++cur) {
  		if (cn->corename[cur] == '/')
  			cn->corename[cur] = '!';
  	}
  	return ret;
10c28d937   Alex Kelly   coredump: move co...
143
144
145
146
147
148
149
150
151
  }
  
  static int cn_print_exe_file(struct core_name *cn)
  {
  	struct file *exe_file;
  	char *pathbuf, *path;
  	int ret;
  
  	exe_file = get_mm_exe_file(current->mm);
923bed030   Oleg Nesterov   coredump: kill cn...
152
153
  	if (!exe_file)
  		return cn_esc_printf(cn, "%s (path unknown)", current->comm);
10c28d937   Alex Kelly   coredump: move co...
154
155
156
157
158
159
  
  	pathbuf = kmalloc(PATH_MAX, GFP_TEMPORARY);
  	if (!pathbuf) {
  		ret = -ENOMEM;
  		goto put_exe_file;
  	}
9bf39ab2a   Miklos Szeredi   vfs: add file_pat...
160
  	path = file_path(exe_file, pathbuf, PATH_MAX);
10c28d937   Alex Kelly   coredump: move co...
161
162
163
164
  	if (IS_ERR(path)) {
  		ret = PTR_ERR(path);
  		goto free_buf;
  	}
923bed030   Oleg Nesterov   coredump: kill cn...
165
  	ret = cn_esc_printf(cn, "%s", path);
10c28d937   Alex Kelly   coredump: move co...
166
167
168
169
170
171
172
173
174
175
176
177
  
  free_buf:
  	kfree(pathbuf);
  put_exe_file:
  	fput(exe_file);
  	return ret;
  }
  
  /* format_corename will inspect the pattern parameter, and output a
   * name into corename, which must have space for at least
   * CORENAME_MAX_SIZE bytes plus one byte for the zero terminator.
   */
12a2b4b22   Oleg Nesterov   coredump: add sup...
178
  static int format_corename(struct core_name *cn, struct coredump_params *cprm)
10c28d937   Alex Kelly   coredump: move co...
179
180
181
182
183
184
  {
  	const struct cred *cred = current_cred();
  	const char *pat_ptr = core_pattern;
  	int ispipe = (*pat_ptr == '|');
  	int pid_in_pattern = 0;
  	int err = 0;
e7fd1549a   Oleg Nesterov   coredump: format_...
185
  	cn->used = 0;
3ceadcf6d   Oleg Nesterov   coredump: kill ca...
186
187
  	cn->corename = NULL;
  	if (expand_corename(cn, core_name_size))
10c28d937   Alex Kelly   coredump: move co...
188
  		return -ENOMEM;
888ffc592   Oleg Nesterov   coredump: '% at t...
189
190
191
192
  	cn->corename[0] = '\0';
  
  	if (ispipe)
  		++pat_ptr;
10c28d937   Alex Kelly   coredump: move co...
193
194
195
196
197
  
  	/* Repeat as long as we have more pattern to process and more output
  	   space */
  	while (*pat_ptr) {
  		if (*pat_ptr != '%') {
10c28d937   Alex Kelly   coredump: move co...
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
  			err = cn_printf(cn, "%c", *pat_ptr++);
  		} else {
  			switch (*++pat_ptr) {
  			/* single % at the end, drop that */
  			case 0:
  				goto out;
  			/* Double percent, output one percent */
  			case '%':
  				err = cn_printf(cn, "%c", '%');
  				break;
  			/* pid */
  			case 'p':
  				pid_in_pattern = 1;
  				err = cn_printf(cn, "%d",
  					      task_tgid_vnr(current));
  				break;
65aafb1e7   Stéphane Graber   coredump: add new...
214
215
216
217
218
  			/* global pid */
  			case 'P':
  				err = cn_printf(cn, "%d",
  					      task_tgid_nr(current));
  				break;
b03023ecb   Oleg Nesterov   coredump: add %i/...
219
220
221
222
223
224
225
226
  			case 'i':
  				err = cn_printf(cn, "%d",
  					      task_pid_vnr(current));
  				break;
  			case 'I':
  				err = cn_printf(cn, "%d",
  					      task_pid_nr(current));
  				break;
10c28d937   Alex Kelly   coredump: move co...
227
228
  			/* uid */
  			case 'u':
5202efe54   Nicolas Iooss   coredump: use fro...
229
230
231
  				err = cn_printf(cn, "%u",
  						from_kuid(&init_user_ns,
  							  cred->uid));
10c28d937   Alex Kelly   coredump: move co...
232
233
234
  				break;
  			/* gid */
  			case 'g':
5202efe54   Nicolas Iooss   coredump: use fro...
235
236
237
  				err = cn_printf(cn, "%u",
  						from_kgid(&init_user_ns,
  							  cred->gid));
10c28d937   Alex Kelly   coredump: move co...
238
  				break;
12a2b4b22   Oleg Nesterov   coredump: add sup...
239
240
241
242
  			case 'd':
  				err = cn_printf(cn, "%d",
  					__get_dumpable(cprm->mm_flags));
  				break;
10c28d937   Alex Kelly   coredump: move co...
243
244
  			/* signal that caused the coredump */
  			case 's':
b4176b7c1   Nicolas Iooss   coredump: add __p...
245
246
  				err = cn_printf(cn, "%d",
  						cprm->siginfo->si_signo);
10c28d937   Alex Kelly   coredump: move co...
247
248
249
  				break;
  			/* UNIX time of coredump */
  			case 't': {
03927c8ac   Arnd Bergmann   coredump: Use 64b...
250
251
252
253
  				time64_t time;
  
  				time = ktime_get_real_seconds();
  				err = cn_printf(cn, "%lld", time);
10c28d937   Alex Kelly   coredump: move co...
254
255
256
  				break;
  			}
  			/* hostname */
923bed030   Oleg Nesterov   coredump: kill cn...
257
  			case 'h':
10c28d937   Alex Kelly   coredump: move co...
258
  				down_read(&uts_sem);
923bed030   Oleg Nesterov   coredump: kill cn...
259
  				err = cn_esc_printf(cn, "%s",
10c28d937   Alex Kelly   coredump: move co...
260
261
  					      utsname()->nodename);
  				up_read(&uts_sem);
10c28d937   Alex Kelly   coredump: move co...
262
  				break;
10c28d937   Alex Kelly   coredump: move co...
263
  			/* executable */
923bed030   Oleg Nesterov   coredump: kill cn...
264
265
  			case 'e':
  				err = cn_esc_printf(cn, "%s", current->comm);
10c28d937   Alex Kelly   coredump: move co...
266
  				break;
10c28d937   Alex Kelly   coredump: move co...
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
  			case 'E':
  				err = cn_print_exe_file(cn);
  				break;
  			/* core limit size */
  			case 'c':
  				err = cn_printf(cn, "%lu",
  					      rlimit(RLIMIT_CORE));
  				break;
  			default:
  				break;
  			}
  			++pat_ptr;
  		}
  
  		if (err)
  			return err;
  	}
888ffc592   Oleg Nesterov   coredump: '% at t...
284
  out:
10c28d937   Alex Kelly   coredump: move co...
285
286
287
288
289
290
291
292
293
294
  	/* Backward compatibility with core_uses_pid:
  	 *
  	 * If core_pattern does not include a %p (as is the default)
  	 * and core_uses_pid is set, then .%pid will be appended to
  	 * the filename. Do not do this for piped commands. */
  	if (!ispipe && !pid_in_pattern && core_uses_pid) {
  		err = cn_printf(cn, ".%d", task_tgid_vnr(current));
  		if (err)
  			return err;
  	}
10c28d937   Alex Kelly   coredump: move co...
295
296
  	return ispipe;
  }
5fa534c98   Oleg Nesterov   coredump: ensure ...
297
  static int zap_process(struct task_struct *start, int exit_code, int flags)
10c28d937   Alex Kelly   coredump: move co...
298
299
300
  {
  	struct task_struct *t;
  	int nr = 0;
5fa534c98   Oleg Nesterov   coredump: ensure ...
301
302
  	/* ignore all signals except SIGKILL, see prepare_signal() */
  	start->signal->flags = SIGNAL_GROUP_COREDUMP | flags;
10c28d937   Alex Kelly   coredump: move co...
303
304
  	start->signal->group_exit_code = exit_code;
  	start->signal->group_stop_count = 0;
d61ba5895   Oleg Nesterov   coredump: change ...
305
  	for_each_thread(start, t) {
10c28d937   Alex Kelly   coredump: move co...
306
307
308
309
310
311
  		task_clear_jobctl_pending(t, JOBCTL_PENDING_MASK);
  		if (t != current && t->mm) {
  			sigaddset(&t->pending.signal, SIGKILL);
  			signal_wake_up(t, 1);
  			nr++;
  		}
d61ba5895   Oleg Nesterov   coredump: change ...
312
  	}
10c28d937   Alex Kelly   coredump: move co...
313
314
315
  
  	return nr;
  }
403bad72b   Oleg Nesterov   coredump: only SI...
316
317
  static int zap_threads(struct task_struct *tsk, struct mm_struct *mm,
  			struct core_state *core_state, int exit_code)
10c28d937   Alex Kelly   coredump: move co...
318
319
320
321
322
323
324
325
  {
  	struct task_struct *g, *p;
  	unsigned long flags;
  	int nr = -EAGAIN;
  
  	spin_lock_irq(&tsk->sighand->siglock);
  	if (!signal_group_exit(tsk->signal)) {
  		mm->core_state = core_state;
6cd8f0aca   Oleg Nesterov   coredump: ensure ...
326
  		tsk->signal->group_exit_task = tsk;
5fa534c98   Oleg Nesterov   coredump: ensure ...
327
  		nr = zap_process(tsk, exit_code, 0);
403bad72b   Oleg Nesterov   coredump: only SI...
328
  		clear_tsk_thread_flag(tsk, TIF_SIGPENDING);
10c28d937   Alex Kelly   coredump: move co...
329
330
331
332
  	}
  	spin_unlock_irq(&tsk->sighand->siglock);
  	if (unlikely(nr < 0))
  		return nr;
aed8adb76   Silesh C V   coredump: fix the...
333
  	tsk->flags |= PF_DUMPCORE;
10c28d937   Alex Kelly   coredump: move co...
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
  	if (atomic_read(&mm->mm_users) == nr + 1)
  		goto done;
  	/*
  	 * We should find and kill all tasks which use this mm, and we should
  	 * count them correctly into ->nr_threads. We don't take tasklist
  	 * lock, but this is safe wrt:
  	 *
  	 * fork:
  	 *	None of sub-threads can fork after zap_process(leader). All
  	 *	processes which were created before this point should be
  	 *	visible to zap_threads() because copy_process() adds the new
  	 *	process to the tail of init_task.tasks list, and lock/unlock
  	 *	of ->siglock provides a memory barrier.
  	 *
  	 * do_exit:
  	 *	The caller holds mm->mmap_sem. This means that the task which
  	 *	uses this mm can't pass exit_mm(), so it can't exit or clear
  	 *	its ->mm.
  	 *
  	 * de_thread:
  	 *	It does list_replace_rcu(&leader->tasks, &current->tasks),
  	 *	we must see either old or new leader, this does not matter.
  	 *	However, it can change p->sighand, so lock_task_sighand(p)
  	 *	must be used. Since p->mm != NULL and we hold ->mmap_sem
  	 *	it can't fail.
  	 *
  	 *	Note also that "g" can be the old leader with ->mm == NULL
  	 *	and already unhashed and thus removed from ->thread_group.
  	 *	This is OK, __unhash_process()->list_del_rcu() does not
  	 *	clear the ->next pointer, we will find the new leader via
  	 *	next_thread().
  	 */
  	rcu_read_lock();
  	for_each_process(g) {
  		if (g == tsk->group_leader)
  			continue;
  		if (g->flags & PF_KTHREAD)
  			continue;
d61ba5895   Oleg Nesterov   coredump: change ...
372
373
374
375
376
377
378
379
380
  
  		for_each_thread(g, p) {
  			if (unlikely(!p->mm))
  				continue;
  			if (unlikely(p->mm == mm)) {
  				lock_task_sighand(p, &flags);
  				nr += zap_process(p, exit_code,
  							SIGNAL_GROUP_EXIT);
  				unlock_task_sighand(p, &flags);
10c28d937   Alex Kelly   coredump: move co...
381
  			}
d61ba5895   Oleg Nesterov   coredump: change ...
382
383
  			break;
  		}
10c28d937   Alex Kelly   coredump: move co...
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
  	}
  	rcu_read_unlock();
  done:
  	atomic_set(&core_state->nr_threads, nr);
  	return nr;
  }
  
  static int coredump_wait(int exit_code, struct core_state *core_state)
  {
  	struct task_struct *tsk = current;
  	struct mm_struct *mm = tsk->mm;
  	int core_waiters = -EBUSY;
  
  	init_completion(&core_state->startup);
  	core_state->dumper.task = tsk;
  	core_state->dumper.next = NULL;
4136c26b6   Michal Hocko   coredump: make co...
400
401
  	if (down_write_killable(&mm->mmap_sem))
  		return -EINTR;
10c28d937   Alex Kelly   coredump: move co...
402
403
404
405
406
407
  	if (!mm->core_state)
  		core_waiters = zap_threads(tsk, mm, core_state, exit_code);
  	up_write(&mm->mmap_sem);
  
  	if (core_waiters > 0) {
  		struct core_thread *ptr;
70d78fe7c   Andrey Ryabinin   coredump: fix unf...
408
  		freezer_do_not_count();
10c28d937   Alex Kelly   coredump: move co...
409
  		wait_for_completion(&core_state->startup);
70d78fe7c   Andrey Ryabinin   coredump: fix unf...
410
  		freezer_count();
10c28d937   Alex Kelly   coredump: move co...
411
412
413
414
415
416
417
418
419
420
421
422
423
424
  		/*
  		 * Wait for all the threads to become inactive, so that
  		 * all the thread context (extended register state, like
  		 * fpu etc) gets copied to the memory.
  		 */
  		ptr = core_state->dumper.next;
  		while (ptr != NULL) {
  			wait_task_inactive(ptr->task, 0);
  			ptr = ptr->next;
  		}
  	}
  
  	return core_waiters;
  }
acdedd99b   Oleg Nesterov   coredump: sanitiz...
425
  static void coredump_finish(struct mm_struct *mm, bool core_dumped)
10c28d937   Alex Kelly   coredump: move co...
426
427
428
  {
  	struct core_thread *curr, *next;
  	struct task_struct *task;
6cd8f0aca   Oleg Nesterov   coredump: ensure ...
429
  	spin_lock_irq(&current->sighand->siglock);
acdedd99b   Oleg Nesterov   coredump: sanitiz...
430
431
  	if (core_dumped && !__fatal_signal_pending(current))
  		current->signal->group_exit_code |= 0x80;
6cd8f0aca   Oleg Nesterov   coredump: ensure ...
432
433
434
  	current->signal->group_exit_task = NULL;
  	current->signal->flags = SIGNAL_GROUP_EXIT;
  	spin_unlock_irq(&current->sighand->siglock);
10c28d937   Alex Kelly   coredump: move co...
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
  	next = mm->core_state->dumper.next;
  	while ((curr = next) != NULL) {
  		next = curr->next;
  		task = curr->task;
  		/*
  		 * see exit_mm(), curr->task must not see
  		 * ->task == NULL before we read ->next.
  		 */
  		smp_mb();
  		curr->task = NULL;
  		wake_up_process(task);
  	}
  
  	mm->core_state = NULL;
  }
528f827ee   Oleg Nesterov   coredump: introdu...
450
451
452
453
454
455
456
457
458
459
  static bool dump_interrupted(void)
  {
  	/*
  	 * SIGKILL or freezing() interrupt the coredumping. Perhaps we
  	 * can do try_to_freeze() and check __fatal_signal_pending(),
  	 * but then we need to teach dump_write() to restart and clear
  	 * TIF_SIGPENDING.
  	 */
  	return signal_pending(current);
  }
10c28d937   Alex Kelly   coredump: move co...
460
461
  static void wait_for_dump_helpers(struct file *file)
  {
de32ec4cf   Al Viro   pipe: set file->p...
462
  	struct pipe_inode_info *pipe = file->private_data;
10c28d937   Alex Kelly   coredump: move co...
463
464
465
466
  
  	pipe_lock(pipe);
  	pipe->readers++;
  	pipe->writers--;
dc7ee2aac   Oleg Nesterov   coredump: change ...
467
468
469
  	wake_up_interruptible_sync(&pipe->wait);
  	kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
  	pipe_unlock(pipe);
10c28d937   Alex Kelly   coredump: move co...
470

dc7ee2aac   Oleg Nesterov   coredump: change ...
471
472
473
474
475
  	/*
  	 * We actually want wait_event_freezable() but then we need
  	 * to clear TIF_SIGPENDING and improve dump_interrupted().
  	 */
  	wait_event_interruptible(pipe->wait, pipe->readers == 1);
10c28d937   Alex Kelly   coredump: move co...
476

dc7ee2aac   Oleg Nesterov   coredump: change ...
477
  	pipe_lock(pipe);
10c28d937   Alex Kelly   coredump: move co...
478
479
480
  	pipe->readers--;
  	pipe->writers++;
  	pipe_unlock(pipe);
10c28d937   Alex Kelly   coredump: move co...
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
  }
  
  /*
   * umh_pipe_setup
   * helper function to customize the process used
   * to collect the core in userspace.  Specifically
   * it sets up a pipe and installs it as fd 0 (stdin)
   * for the process.  Returns 0 on success, or
   * PTR_ERR on failure.
   * Note that it also sets the core limit to 1.  This
   * is a special value that we use to trap recursive
   * core dumps
   */
  static int umh_pipe_setup(struct subprocess_info *info, struct cred *new)
  {
  	struct file *files[2];
  	struct coredump_params *cp = (struct coredump_params *)info->data;
  	int err = create_pipe_files(files, 0);
  	if (err)
  		return err;
  
  	cp->file = files[1];
45525b26a   Al Viro   fix a leak in rep...
503
504
  	err = replace_fd(0, files[0], 0);
  	fput(files[0]);
10c28d937   Alex Kelly   coredump: move co...
505
506
  	/* and disallow core files too */
  	current->signal->rlim[RLIMIT_CORE] = (struct rlimit){1, 1};
45525b26a   Al Viro   fix a leak in rep...
507
  	return err;
10c28d937   Alex Kelly   coredump: move co...
508
  }
ec57941e0   Al Viro   constify do_cored...
509
  void do_coredump(const siginfo_t *siginfo)
10c28d937   Alex Kelly   coredump: move co...
510
511
512
513
514
515
516
517
  {
  	struct core_state core_state;
  	struct core_name cn;
  	struct mm_struct *mm = current->mm;
  	struct linux_binfmt * binfmt;
  	const struct cred *old_cred;
  	struct cred *cred;
  	int retval = 0;
10c28d937   Alex Kelly   coredump: move co...
518
519
  	int ispipe;
  	struct files_struct *displaced;
fbb181694   Jann Horn   fs: if a coredump...
520
521
  	/* require nonrelative corefile path and be extra careful */
  	bool need_suid_safe = false;
acdedd99b   Oleg Nesterov   coredump: sanitiz...
522
  	bool core_dumped = false;
10c28d937   Alex Kelly   coredump: move co...
523
524
  	static atomic_t core_dump_count = ATOMIC_INIT(0);
  	struct coredump_params cprm = {
5ab1c309b   Denys Vlasenko   coredump: pass si...
525
  		.siginfo = siginfo,
541880d9a   Al Viro   do_coredump(): ge...
526
  		.regs = signal_pt_regs(),
10c28d937   Alex Kelly   coredump: move co...
527
528
529
530
531
532
533
534
  		.limit = rlimit(RLIMIT_CORE),
  		/*
  		 * We must use the same mm->flags while dumping core to avoid
  		 * inconsistency of bit flags, since this flag is not protected
  		 * by any locks.
  		 */
  		.mm_flags = mm->flags,
  	};
5ab1c309b   Denys Vlasenko   coredump: pass si...
535
  	audit_core_dumps(siginfo->si_signo);
10c28d937   Alex Kelly   coredump: move co...
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
  
  	binfmt = mm->binfmt;
  	if (!binfmt || !binfmt->core_dump)
  		goto fail;
  	if (!__get_dumpable(cprm.mm_flags))
  		goto fail;
  
  	cred = prepare_creds();
  	if (!cred)
  		goto fail;
  	/*
  	 * We cannot trust fsuid as being the "true" uid of the process
  	 * nor do we know its entire history. We only know it was tainted
  	 * so we dump it as root in mode 2, and only into a controlled
  	 * environment (pipe handler or fully qualified path).
  	 */
e579d2c25   Kees Cook   coredump: remove ...
552
  	if (__get_dumpable(cprm.mm_flags) == SUID_DUMP_ROOT) {
10c28d937   Alex Kelly   coredump: move co...
553
  		/* Setuid core dump mode */
10c28d937   Alex Kelly   coredump: move co...
554
  		cred->fsuid = GLOBAL_ROOT_UID;	/* Dump root private */
fbb181694   Jann Horn   fs: if a coredump...
555
  		need_suid_safe = true;
10c28d937   Alex Kelly   coredump: move co...
556
  	}
5ab1c309b   Denys Vlasenko   coredump: pass si...
557
  	retval = coredump_wait(siginfo->si_signo, &core_state);
10c28d937   Alex Kelly   coredump: move co...
558
559
560
561
  	if (retval < 0)
  		goto fail_creds;
  
  	old_cred = override_creds(cred);
12a2b4b22   Oleg Nesterov   coredump: add sup...
562
  	ispipe = format_corename(&cn, &cprm);
10c28d937   Alex Kelly   coredump: move co...
563

fb96c475f   Lucas De Marchi   coredump: remove ...
564
  	if (ispipe) {
10c28d937   Alex Kelly   coredump: move co...
565
566
  		int dump_count;
  		char **helper_argv;
907ed1328   Lucas De Marchi   usermodehelper: s...
567
  		struct subprocess_info *sub_info;
10c28d937   Alex Kelly   coredump: move co...
568
569
570
571
572
573
  
  		if (ispipe < 0) {
  			printk(KERN_WARNING "format_corename failed
  ");
  			printk(KERN_WARNING "Aborting core
  ");
e7fd1549a   Oleg Nesterov   coredump: format_...
574
  			goto fail_unlock;
10c28d937   Alex Kelly   coredump: move co...
575
576
577
578
579
580
581
  		}
  
  		if (cprm.limit == 1) {
  			/* See umh_pipe_setup() which sets RLIMIT_CORE = 1.
  			 *
  			 * Normally core limits are irrelevant to pipes, since
  			 * we're not writing to the file system, but we use
fcbc32bc6   Bastien Nocera   coredump: Fix typ...
582
  			 * cprm.limit of 1 here as a special value, this is a
10c28d937   Alex Kelly   coredump: move co...
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
  			 * consistent way to catch recursive crashes.
  			 * We can still crash if the core_pattern binary sets
  			 * RLIM_CORE = !1, but it runs as root, and can do
  			 * lots of stupid things.
  			 *
  			 * Note that we use task_tgid_vnr here to grab the pid
  			 * of the process group leader.  That way we get the
  			 * right pid if a thread in a multi-threaded
  			 * core_pattern process dies.
  			 */
  			printk(KERN_WARNING
  				"Process %d(%s) has RLIMIT_CORE set to 1
  ",
  				task_tgid_vnr(current), current->comm);
  			printk(KERN_WARNING "Aborting core
  ");
  			goto fail_unlock;
  		}
  		cprm.limit = RLIM_INFINITY;
  
  		dump_count = atomic_inc_return(&core_dump_count);
  		if (core_pipe_limit && (core_pipe_limit < dump_count)) {
  			printk(KERN_WARNING "Pid %d(%s) over core_pipe_limit
  ",
  			       task_tgid_vnr(current), current->comm);
  			printk(KERN_WARNING "Skipping core dump
  ");
  			goto fail_dropcount;
  		}
888ffc592   Oleg Nesterov   coredump: '% at t...
612
  		helper_argv = argv_split(GFP_KERNEL, cn.corename, NULL);
10c28d937   Alex Kelly   coredump: move co...
613
614
615
616
617
618
  		if (!helper_argv) {
  			printk(KERN_WARNING "%s failed to allocate memory
  ",
  			       __func__);
  			goto fail_dropcount;
  		}
907ed1328   Lucas De Marchi   usermodehelper: s...
619
620
621
622
623
624
625
  		retval = -ENOMEM;
  		sub_info = call_usermodehelper_setup(helper_argv[0],
  						helper_argv, NULL, GFP_KERNEL,
  						umh_pipe_setup, NULL, &cprm);
  		if (sub_info)
  			retval = call_usermodehelper_exec(sub_info,
  							  UMH_WAIT_EXEC);
10c28d937   Alex Kelly   coredump: move co...
626
627
  		argv_free(helper_argv);
  		if (retval) {
888ffc592   Oleg Nesterov   coredump: '% at t...
628
629
  			printk(KERN_INFO "Core dump to |%s pipe failed
  ",
10c28d937   Alex Kelly   coredump: move co...
630
631
  			       cn.corename);
  			goto close_fail;
fb96c475f   Lucas De Marchi   coredump: remove ...
632
  		}
10c28d937   Alex Kelly   coredump: move co...
633
634
  	} else {
  		struct inode *inode;
378c6520e   Jann Horn   fs/coredump: prev...
635
636
  		int open_flags = O_CREAT | O_RDWR | O_NOFOLLOW |
  				 O_LARGEFILE | O_EXCL;
10c28d937   Alex Kelly   coredump: move co...
637
638
639
  
  		if (cprm.limit < binfmt->min_coredump)
  			goto fail_unlock;
fbb181694   Jann Horn   fs: if a coredump...
640
  		if (need_suid_safe && cn.corename[0] != '/') {
10c28d937   Alex Kelly   coredump: move co...
641
642
643
644
645
646
647
648
  			printk(KERN_WARNING "Pid %d(%s) can only dump core "\
  				"to fully qualified path!
  ",
  				task_tgid_vnr(current), current->comm);
  			printk(KERN_WARNING "Skipping core dump
  ");
  			goto fail_unlock;
  		}
fbb181694   Jann Horn   fs: if a coredump...
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
  		/*
  		 * Unlink the file if it exists unless this is a SUID
  		 * binary - in that case, we're running around with root
  		 * privs and don't want to unlink another user's coredump.
  		 */
  		if (!need_suid_safe) {
  			mm_segment_t old_fs;
  
  			old_fs = get_fs();
  			set_fs(KERNEL_DS);
  			/*
  			 * If it doesn't exist, that's fine. If there's some
  			 * other problem, we'll catch it at the filp_open().
  			 */
  			(void) sys_unlink((const char __user *)cn.corename);
  			set_fs(old_fs);
  		}
  
  		/*
  		 * There is a race between unlinking and creating the
  		 * file, but if that causes an EEXIST here, that's
  		 * fine - another process raced with us while creating
  		 * the corefile, and the other process won. To userspace,
  		 * what matters is that at least one of the two processes
  		 * writes its coredump successfully, not which one.
  		 */
378c6520e   Jann Horn   fs/coredump: prev...
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
  		if (need_suid_safe) {
  			/*
  			 * Using user namespaces, normal user tasks can change
  			 * their current->fs->root to point to arbitrary
  			 * directories. Since the intention of the "only dump
  			 * with a fully qualified path" rule is to control where
  			 * coredumps may be placed using root privileges,
  			 * current->fs->root must not be used. Instead, use the
  			 * root directory of init_task.
  			 */
  			struct path root;
  
  			task_lock(&init_task);
  			get_fs_root(init_task.fs, &root);
  			task_unlock(&init_task);
  			cprm.file = file_open_root(root.dentry, root.mnt,
  				cn.corename, open_flags, 0600);
  			path_put(&root);
  		} else {
  			cprm.file = filp_open(cn.corename, open_flags, 0600);
  		}
10c28d937   Alex Kelly   coredump: move co...
696
697
  		if (IS_ERR(cprm.file))
  			goto fail_unlock;
496ad9aa8   Al Viro   new helper: file_...
698
  		inode = file_inode(cprm.file);
10c28d937   Alex Kelly   coredump: move co...
699
700
701
702
703
704
705
706
707
708
709
  		if (inode->i_nlink > 1)
  			goto close_fail;
  		if (d_unhashed(cprm.file->f_path.dentry))
  			goto close_fail;
  		/*
  		 * AK: actually i see no reason to not allow this for named
  		 * pipes etc, but keep the previous behaviour for now.
  		 */
  		if (!S_ISREG(inode->i_mode))
  			goto close_fail;
  		/*
40f705a73   Jann Horn   fs: Don't dump co...
710
711
712
713
  		 * Don't dump core if the filesystem changed owner or mode
  		 * of the file during file creation. This is an issue when
  		 * a process dumps core while its cwd is e.g. on a vfat
  		 * filesystem.
10c28d937   Alex Kelly   coredump: move co...
714
715
716
  		 */
  		if (!uid_eq(inode->i_uid, current_fsuid()))
  			goto close_fail;
40f705a73   Jann Horn   fs: Don't dump co...
717
718
  		if ((inode->i_mode & 0677) != 0600)
  			goto close_fail;
86cc05840   Al Viro   coredump: accept ...
719
  		if (!(cprm.file->f_mode & FMODE_CAN_WRITE))
10c28d937   Alex Kelly   coredump: move co...
720
721
722
723
724
725
726
727
728
729
730
  			goto close_fail;
  		if (do_truncate(cprm.file->f_path.dentry, 0, 0, cprm.file))
  			goto close_fail;
  	}
  
  	/* get us an unshared descriptor table; almost always a no-op */
  	retval = unshare_files(&displaced);
  	if (retval)
  		goto close_fail;
  	if (displaced)
  		put_files_struct(displaced);
e86d35c38   Al Viro   do_coredump(): do...
731
732
733
734
735
  	if (!dump_interrupted()) {
  		file_start_write(cprm.file);
  		core_dumped = binfmt->core_dump(&cprm);
  		file_end_write(cprm.file);
  	}
10c28d937   Alex Kelly   coredump: move co...
736
737
738
739
740
741
742
743
744
745
  	if (ispipe && core_pipe_limit)
  		wait_for_dump_helpers(cprm.file);
  close_fail:
  	if (cprm.file)
  		filp_close(cprm.file, NULL);
  fail_dropcount:
  	if (ispipe)
  		atomic_dec(&core_dump_count);
  fail_unlock:
  	kfree(cn.corename);
acdedd99b   Oleg Nesterov   coredump: sanitiz...
746
  	coredump_finish(mm, core_dumped);
10c28d937   Alex Kelly   coredump: move co...
747
748
749
750
751
752
753
754
755
756
757
758
  	revert_creds(old_cred);
  fail_creds:
  	put_cred(cred);
  fail:
  	return;
  }
  
  /*
   * Core dumping helper functions.  These are the only things you should
   * do on a core-file: use only these functions to write out all the
   * necessary info.
   */
ecc8c7725   Al Viro   new helper: dump_...
759
760
761
  int dump_emit(struct coredump_params *cprm, const void *addr, int nr)
  {
  	struct file *file = cprm->file;
2507a4fbd   Al Viro   make dump_emit() ...
762
763
  	loff_t pos = file->f_pos;
  	ssize_t n;
2c4cb0430   Omar Sandoval   coredump: only ch...
764
  	if (cprm->written + nr > cprm->limit)
ecc8c7725   Al Viro   new helper: dump_...
765
  		return 0;
2507a4fbd   Al Viro   make dump_emit() ...
766
767
768
  	while (nr) {
  		if (dump_interrupted())
  			return 0;
52da40ae6   Al Viro   dump_emit(): use ...
769
  		n = __kernel_write(file, addr, nr, &pos);
2507a4fbd   Al Viro   make dump_emit() ...
770
771
772
  		if (n <= 0)
  			return 0;
  		file->f_pos = pos;
2c4cb0430   Omar Sandoval   coredump: only ch...
773
  		cprm->written += n;
1607f09c2   Mateusz Guzik   coredump: fix dum...
774
  		cprm->pos += n;
2507a4fbd   Al Viro   make dump_emit() ...
775
776
  		nr -= n;
  	}
ecc8c7725   Al Viro   new helper: dump_...
777
778
779
  	return 1;
  }
  EXPORT_SYMBOL(dump_emit);
9b56d5438   Al Viro   dump_skip(): dump...
780
  int dump_skip(struct coredump_params *cprm, size_t nr)
10c28d937   Alex Kelly   coredump: move co...
781
  {
9b56d5438   Al Viro   dump_skip(): dump...
782
783
  	static char zeroes[PAGE_SIZE];
  	struct file *file = cprm->file;
10c28d937   Alex Kelly   coredump: move co...
784
  	if (file->f_op->llseek && file->f_op->llseek != no_llseek) {
528f827ee   Oleg Nesterov   coredump: introdu...
785
  		if (dump_interrupted() ||
9b56d5438   Al Viro   dump_skip(): dump...
786
  		    file->f_op->llseek(file, nr, SEEK_CUR) < 0)
10c28d937   Alex Kelly   coredump: move co...
787
  			return 0;
1607f09c2   Mateusz Guzik   coredump: fix dum...
788
  		cprm->pos += nr;
9b56d5438   Al Viro   dump_skip(): dump...
789
  		return 1;
10c28d937   Alex Kelly   coredump: move co...
790
  	} else {
9b56d5438   Al Viro   dump_skip(): dump...
791
792
793
794
  		while (nr > PAGE_SIZE) {
  			if (!dump_emit(cprm, zeroes, PAGE_SIZE))
  				return 0;
  			nr -= PAGE_SIZE;
10c28d937   Alex Kelly   coredump: move co...
795
  		}
9b56d5438   Al Viro   dump_skip(): dump...
796
  		return dump_emit(cprm, zeroes, nr);
10c28d937   Alex Kelly   coredump: move co...
797
  	}
10c28d937   Alex Kelly   coredump: move co...
798
  }
9b56d5438   Al Viro   dump_skip(): dump...
799
  EXPORT_SYMBOL(dump_skip);
22a8cb824   Al Viro   new helper: dump_...
800
801
802
  
  int dump_align(struct coredump_params *cprm, int align)
  {
1607f09c2   Mateusz Guzik   coredump: fix dum...
803
  	unsigned mod = cprm->pos & (align - 1);
22a8cb824   Al Viro   new helper: dump_...
804
  	if (align & (align - 1))
db51242d8   Al Viro   dump_align(): fix...
805
806
  		return 0;
  	return mod ? dump_skip(cprm, align - mod) : 1;
22a8cb824   Al Viro   new helper: dump_...
807
808
  }
  EXPORT_SYMBOL(dump_align);