linux/fs/coredump.c

// SPDX-License-Identifier: GPL-2.0
#include <linux/slab.h>
#include <linux/file.h>
#include <linux/fdtable.h>
#include <linux/freezer.h>
#include <linux/mm.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
#include <linux/swap.h>
#include <linux/ctype.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>
#include <linux/coredump.h>
#include <linux/sched/coredump.h>
#include <linux/sched/signal.h>
#include <linux/sched/task_stack.h>
#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/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>
#include <linux/fs.h>
#include <linux/path.h>
#include <linux/timekeeping.h>
#include <linux/sysctl.h>
#include <linux/elf.h>

#include <linux/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>

static bool dump_vma_snapshot(struct coredump_params *cprm);
static void free_vma_snapshot(struct coredump_params *cprm);

#define CORE_FILE_NOTE_SIZE_DEFAULT
/* Define a reasonable max cap */
#define CORE_FILE_NOTE_SIZE_MAX

static int core_uses_pid;
static unsigned int core_pipe_limit;
static char core_pattern[CORENAME_MAX_SIZE] =;
static int core_name_size =;
unsigned int core_file_note_size_limit =;

struct core_name {};

static int expand_corename(struct core_name *cn, int size)
{}

static __printf(2, 0) int cn_vprintf(struct core_name *cn, const char *fmt,
				     va_list arg)
{}

static __printf(2, 3) int cn_printf(struct core_name *cn, const char *fmt, ...)
{}

static __printf(2, 3)
int cn_esc_printf(struct core_name *cn, const char *fmt, ...)
{}

static int cn_print_exe_file(struct core_name *cn, bool name_only)
{}

/* 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.
 */
static int format_corename(struct core_name *cn, struct coredump_params *cprm,
			   size_t **argv, int *argc)
{}

static int zap_process(struct signal_struct *signal, int exit_code)
{}

static int zap_threads(struct task_struct *tsk,
			struct core_state *core_state, int exit_code)
{}

static int coredump_wait(int exit_code, struct core_state *core_state)
{}

static void coredump_finish(bool core_dumped)
{}

static bool dump_interrupted(void)
{}

static void wait_for_dump_helpers(struct file *file)
{}

/*
 * 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)
{}

void do_coredump(const kernel_siginfo_t *siginfo)
{}

/*
 * 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.
 */
static int __dump_emit(struct coredump_params *cprm, const void *addr, int nr)
{}

static int __dump_skip(struct coredump_params *cprm, size_t nr)
{}

int dump_emit(struct coredump_params *cprm, const void *addr, int nr)
{}
EXPORT_SYMBOL();

void dump_skip_to(struct coredump_params *cprm, unsigned long pos)
{}
EXPORT_SYMBOL();

void dump_skip(struct coredump_params *cprm, size_t nr)
{}
EXPORT_SYMBOL();

#ifdef CONFIG_ELF_CORE
static int dump_emit_page(struct coredump_params *cprm, struct page *page)
{}

/*
 * If we might get machine checks from kernel accesses during the
 * core dump, let's get those errors early rather than during the
 * IO. This is not performance-critical enough to warrant having
 * all the machine check logic in the iovec paths.
 */
#ifdef copy_mc_to_kernel

#define dump_page_alloc()
#define dump_page_free(x)
static struct page *dump_page_copy(struct page *src, struct page *dst)
{}

#else

/* We just want to return non-NULL; it's never used. */
#define dump_page_alloc
#define dump_page_free
static inline struct page *dump_page_copy(struct page *src, struct page *dst)
{
	return src;
}
#endif

int dump_user_range(struct coredump_params *cprm, unsigned long start,
		    unsigned long len)
{}
#endif

int dump_align(struct coredump_params *cprm, int align)
{}
EXPORT_SYMBOL();

#ifdef CONFIG_SYSCTL

void validate_coredump_safety(void)
{}

static int proc_dostring_coredump(const struct ctl_table *table, int write,
		  void *buffer, size_t *lenp, loff_t *ppos)
{}

static const unsigned int core_file_note_size_min =;
static const unsigned int core_file_note_size_max =;

static struct ctl_table coredump_sysctls[] =;

static int __init init_fs_coredump_sysctls(void)
{}
fs_initcall(init_fs_coredump_sysctls);
#endif /* CONFIG_SYSCTL */

/*
 * The purpose of always_dump_vma() is to make sure that special kernel mappings
 * that are useful for post-mortem analysis are included in every core dump.
 * In that way we ensure that the core dump is fully interpretable later
 * without matching up the same kernel and hardware config to see what PC values
 * meant. These special mappings include - vDSO, vsyscall, and other
 * architecture specific mappings
 */
static bool always_dump_vma(struct vm_area_struct *vma)
{}

#define DUMP_SIZE_MAYBE_ELFHDR_PLACEHOLDER

/*
 * Decide how much of @vma's contents should be included in a core dump.
 */
static unsigned long vma_dump_size(struct vm_area_struct *vma,
				   unsigned long mm_flags)
{}

/*
 * Helper function for iterating across a vma list.  It ensures that the caller
 * will visit `gate_vma' prior to terminating the search.
 */
static struct vm_area_struct *coredump_next_vma(struct vma_iterator *vmi,
				       struct vm_area_struct *vma,
				       struct vm_area_struct *gate_vma)
{}

static void free_vma_snapshot(struct coredump_params *cprm)
{}

/*
 * Under the mmap_lock, take a snapshot of relevant information about the task's
 * VMAs.
 */
static bool dump_vma_snapshot(struct coredump_params *cprm)
{}