^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <linux/file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/fdtable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/freezer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/swap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/pagemap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/perf_event.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/highmem.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/key.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/personality.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/binfmts.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/coredump.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/sched/coredump.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/sched/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/sched/task_stack.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/utsname.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/pid_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/namei.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/mount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/security.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/syscalls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/tsacct_kern.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/cn_proc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/audit.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/tracehook.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/kmod.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/fsnotify.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/fs_struct.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/pipe_fs_i.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/oom.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/compat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/path.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/timekeeping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/elf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <asm/mmu_context.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <asm/tlb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <asm/exec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <trace/events/task.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #include <trace/events/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) int core_uses_pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) unsigned int core_pipe_limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) char core_pattern[CORENAME_MAX_SIZE] = "core";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static int core_name_size = CORENAME_MAX_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct core_name {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) char *corename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) int used, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* The maximal length of core_pattern is also specified in sysctl.c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static int expand_corename(struct core_name *cn, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) char *corename = krealloc(cn->corename, size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (!corename)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (size > core_name_size) /* racy but harmless */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) core_name_size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) cn->size = ksize(corename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) cn->corename = corename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static __printf(2, 0) int cn_vprintf(struct core_name *cn, const char *fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) va_list arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) int free, need;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) va_list arg_copy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) free = cn->size - cn->used;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) va_copy(arg_copy, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) need = vsnprintf(cn->corename + cn->used, free, fmt, arg_copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) va_end(arg_copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) if (need < free) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) cn->used += need;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (!expand_corename(cn, cn->size + need - free + 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static __printf(2, 3) int cn_printf(struct core_name *cn, const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) va_list arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) va_start(arg, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) ret = cn_vprintf(cn, fmt, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) va_end(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static __printf(2, 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) int cn_esc_printf(struct core_name *cn, const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) int cur = cn->used;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) va_list arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) va_start(arg, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) ret = cn_vprintf(cn, fmt, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) va_end(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (ret == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * Ensure that this coredump name component can't cause the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * resulting corefile path to consist of a ".." or ".".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if ((cn->used - cur == 1 && cn->corename[cur] == '.') ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) (cn->used - cur == 2 && cn->corename[cur] == '.'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) && cn->corename[cur+1] == '.'))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) cn->corename[cur] = '!';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * Empty names are fishy and could be used to create a "//" in a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * corefile name, causing the coredump to happen one directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * level too high. Enforce that all components of the core
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * pattern are at least one character long.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (cn->used == cur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) ret = cn_printf(cn, "!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) for (; cur < cn->used; ++cur) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (cn->corename[cur] == '/')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) cn->corename[cur] = '!';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static int cn_print_exe_file(struct core_name *cn, bool name_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct file *exe_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) char *pathbuf, *path, *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) exe_file = get_mm_exe_file(current->mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (!exe_file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return cn_esc_printf(cn, "%s (path unknown)", current->comm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) pathbuf = kmalloc(PATH_MAX, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (!pathbuf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) goto put_exe_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) path = file_path(exe_file, pathbuf, PATH_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (IS_ERR(path)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) ret = PTR_ERR(path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) goto free_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (name_only) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) ptr = strrchr(path, '/');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) path = ptr + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) ret = cn_esc_printf(cn, "%s", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) free_buf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) kfree(pathbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) put_exe_file:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) fput(exe_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) /* format_corename will inspect the pattern parameter, and output a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * name into corename, which must have space for at least
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * CORENAME_MAX_SIZE bytes plus one byte for the zero terminator.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) static int format_corename(struct core_name *cn, struct coredump_params *cprm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) size_t **argv, int *argc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) const struct cred *cred = current_cred();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) const char *pat_ptr = core_pattern;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) int ispipe = (*pat_ptr == '|');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) bool was_space = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) int pid_in_pattern = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) cn->used = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) cn->corename = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if (expand_corename(cn, core_name_size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) cn->corename[0] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (ispipe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) int argvs = sizeof(core_pattern) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) (*argv) = kmalloc_array(argvs, sizeof(**argv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (!(*argv))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) (*argv)[(*argc)++] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) ++pat_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (!(*pat_ptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /* Repeat as long as we have more pattern to process and more output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) while (*pat_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * Split on spaces before doing template expansion so that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * %e and %E don't get split if they have spaces in them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (ispipe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (isspace(*pat_ptr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if (cn->used != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) was_space = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) pat_ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) } else if (was_space) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) was_space = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) err = cn_printf(cn, "%c", '\0');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) (*argv)[(*argc)++] = cn->used;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (*pat_ptr != '%') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) err = cn_printf(cn, "%c", *pat_ptr++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) switch (*++pat_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) /* single % at the end, drop that */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) /* Double percent, output one percent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) case '%':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) err = cn_printf(cn, "%c", '%');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) /* pid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) case 'p':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) pid_in_pattern = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) err = cn_printf(cn, "%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) task_tgid_vnr(current));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) /* global pid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) case 'P':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) err = cn_printf(cn, "%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) task_tgid_nr(current));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) case 'i':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) err = cn_printf(cn, "%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) task_pid_vnr(current));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) case 'I':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) err = cn_printf(cn, "%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) task_pid_nr(current));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) /* uid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) case 'u':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) err = cn_printf(cn, "%u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) from_kuid(&init_user_ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) cred->uid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /* gid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) case 'g':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) err = cn_printf(cn, "%u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) from_kgid(&init_user_ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) cred->gid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) case 'd':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) err = cn_printf(cn, "%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) __get_dumpable(cprm->mm_flags));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) /* signal that caused the coredump */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) case 's':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) err = cn_printf(cn, "%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) cprm->siginfo->si_signo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) /* UNIX time of coredump */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) case 't': {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) time64_t time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) time = ktime_get_real_seconds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) err = cn_printf(cn, "%lld", time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) /* hostname */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) case 'h':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) down_read(&uts_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) err = cn_esc_printf(cn, "%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) utsname()->nodename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) up_read(&uts_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /* executable, could be changed by prctl PR_SET_NAME etc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) case 'e':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) err = cn_esc_printf(cn, "%s", current->comm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) /* file name of executable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) case 'f':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) err = cn_print_exe_file(cn, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) case 'E':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) err = cn_print_exe_file(cn, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) /* core limit size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) case 'c':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) err = cn_printf(cn, "%lu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) rlimit(RLIMIT_CORE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) ++pat_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) /* Backward compatibility with core_uses_pid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) * If core_pattern does not include a %p (as is the default)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) * and core_uses_pid is set, then .%pid will be appended to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) * the filename. Do not do this for piped commands. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (!ispipe && !pid_in_pattern && core_uses_pid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) err = cn_printf(cn, ".%d", task_tgid_vnr(current));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) return ispipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) static int zap_process(struct task_struct *start, int exit_code, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) struct task_struct *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) int nr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) /* ignore all signals except SIGKILL, see prepare_signal() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) start->signal->flags = SIGNAL_GROUP_COREDUMP | flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) start->signal->group_exit_code = exit_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) start->signal->group_stop_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) for_each_thread(start, t) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) task_clear_jobctl_pending(t, JOBCTL_PENDING_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (t != current && t->mm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) sigaddset(&t->pending.signal, SIGKILL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) signal_wake_up(t, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) nr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) static int zap_threads(struct task_struct *tsk, struct mm_struct *mm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) struct core_state *core_state, int exit_code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) struct task_struct *g, *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) int nr = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) spin_lock_irq(&tsk->sighand->siglock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (!signal_group_exit(tsk->signal)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) mm->core_state = core_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) tsk->signal->group_exit_task = tsk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) nr = zap_process(tsk, exit_code, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) clear_tsk_thread_flag(tsk, TIF_SIGPENDING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) spin_unlock_irq(&tsk->sighand->siglock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (unlikely(nr < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) return nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) tsk->flags |= PF_DUMPCORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (atomic_read(&mm->mm_users) == nr + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) * We should find and kill all tasks which use this mm, and we should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * count them correctly into ->nr_threads. We don't take tasklist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * lock, but this is safe wrt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * fork:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) * None of sub-threads can fork after zap_process(leader). All
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) * processes which were created before this point should be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) * visible to zap_threads() because copy_process() adds the new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * process to the tail of init_task.tasks list, and lock/unlock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) * of ->siglock provides a memory barrier.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) * do_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) * The caller holds mm->mmap_lock. This means that the task which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) * uses this mm can't pass exit_mm(), so it can't exit or clear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) * its ->mm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) * de_thread:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) * It does list_replace_rcu(&leader->tasks, ¤t->tasks),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) * we must see either old or new leader, this does not matter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) * However, it can change p->sighand, so lock_task_sighand(p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) * must be used. Since p->mm != NULL and we hold ->mmap_lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) * it can't fail.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) * Note also that "g" can be the old leader with ->mm == NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) * and already unhashed and thus removed from ->thread_group.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) * This is OK, __unhash_process()->list_del_rcu() does not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) * clear the ->next pointer, we will find the new leader via
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) * next_thread().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) for_each_process(g) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (g == tsk->group_leader)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (g->flags & PF_KTHREAD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) for_each_thread(g, p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (unlikely(!p->mm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (unlikely(p->mm == mm)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) lock_task_sighand(p, &flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) nr += zap_process(p, exit_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) SIGNAL_GROUP_EXIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) unlock_task_sighand(p, &flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) atomic_set(&core_state->nr_threads, nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) return nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) static int coredump_wait(int exit_code, struct core_state *core_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) struct task_struct *tsk = current;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) struct mm_struct *mm = tsk->mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) int core_waiters = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) init_completion(&core_state->startup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) core_state->dumper.task = tsk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) core_state->dumper.next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (mmap_write_lock_killable(mm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) return -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (!mm->core_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) core_waiters = zap_threads(tsk, mm, core_state, exit_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) mmap_write_unlock(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (core_waiters > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) struct core_thread *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) freezer_do_not_count();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) wait_for_completion(&core_state->startup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) freezer_count();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) * Wait for all the threads to become inactive, so that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) * all the thread context (extended register state, like
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) * fpu etc) gets copied to the memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) ptr = core_state->dumper.next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) while (ptr != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) wait_task_inactive(ptr->task, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) ptr = ptr->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) return core_waiters;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) static void coredump_finish(struct mm_struct *mm, bool core_dumped)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) struct core_thread *curr, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) struct task_struct *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) spin_lock_irq(¤t->sighand->siglock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (core_dumped && !__fatal_signal_pending(current))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) current->signal->group_exit_code |= 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) current->signal->group_exit_task = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) current->signal->flags = SIGNAL_GROUP_EXIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) spin_unlock_irq(¤t->sighand->siglock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) next = mm->core_state->dumper.next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) while ((curr = next) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) next = curr->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) task = curr->task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) * see exit_mm(), curr->task must not see
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) * ->task == NULL before we read ->next.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) smp_mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) curr->task = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) wake_up_process(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) mm->core_state = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) static bool dump_interrupted(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) * SIGKILL or freezing() interrupt the coredumping. Perhaps we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) * can do try_to_freeze() and check __fatal_signal_pending(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) * but then we need to teach dump_write() to restart and clear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) * TIF_SIGPENDING.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) return signal_pending(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) static void wait_for_dump_helpers(struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) struct pipe_inode_info *pipe = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) pipe_lock(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) pipe->readers++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) pipe->writers--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) wake_up_interruptible_sync(&pipe->rd_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) pipe_unlock(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) * We actually want wait_event_freezable() but then we need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) * to clear TIF_SIGPENDING and improve dump_interrupted().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) wait_event_interruptible(pipe->rd_wait, pipe->readers == 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) pipe_lock(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) pipe->readers--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) pipe->writers++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) pipe_unlock(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) * umh_pipe_setup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) * helper function to customize the process used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) * to collect the core in userspace. Specifically
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) * it sets up a pipe and installs it as fd 0 (stdin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) * for the process. Returns 0 on success, or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) * PTR_ERR on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) * Note that it also sets the core limit to 1. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) * is a special value that we use to trap recursive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) * core dumps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) static int umh_pipe_setup(struct subprocess_info *info, struct cred *new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) struct file *files[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) struct coredump_params *cp = (struct coredump_params *)info->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) int err = create_pipe_files(files, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) cp->file = files[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) err = replace_fd(0, files[0], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) fput(files[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) /* and disallow core files too */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) current->signal->rlim[RLIMIT_CORE] = (struct rlimit){1, 1};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) void do_coredump(const kernel_siginfo_t *siginfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) struct core_state core_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) struct core_name cn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) struct mm_struct *mm = current->mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) struct linux_binfmt * binfmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) const struct cred *old_cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) struct cred *cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) int ispipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) size_t *argv = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) int argc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) struct files_struct *displaced;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) /* require nonrelative corefile path and be extra careful */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) bool need_suid_safe = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) bool core_dumped = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) static atomic_t core_dump_count = ATOMIC_INIT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) struct coredump_params cprm = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) .siginfo = siginfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) .regs = signal_pt_regs(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) .limit = rlimit(RLIMIT_CORE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) * We must use the same mm->flags while dumping core to avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) * inconsistency of bit flags, since this flag is not protected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) * by any locks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) .mm_flags = mm->flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) audit_core_dumps(siginfo->si_signo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) binfmt = mm->binfmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) if (!binfmt || !binfmt->core_dump)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) if (!__get_dumpable(cprm.mm_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) cred = prepare_creds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) if (!cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) * We cannot trust fsuid as being the "true" uid of the process
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) * nor do we know its entire history. We only know it was tainted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) * so we dump it as root in mode 2, and only into a controlled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) * environment (pipe handler or fully qualified path).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) if (__get_dumpable(cprm.mm_flags) == SUID_DUMP_ROOT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) /* Setuid core dump mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) cred->fsuid = GLOBAL_ROOT_UID; /* Dump root private */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) need_suid_safe = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) retval = coredump_wait(siginfo->si_signo, &core_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) goto fail_creds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) old_cred = override_creds(cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) ispipe = format_corename(&cn, &cprm, &argv, &argc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) if (ispipe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) int argi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) int dump_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) char **helper_argv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) struct subprocess_info *sub_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) if (ispipe < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) printk(KERN_WARNING "format_corename failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) printk(KERN_WARNING "Aborting core\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) goto fail_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) if (cprm.limit == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) /* See umh_pipe_setup() which sets RLIMIT_CORE = 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) * Normally core limits are irrelevant to pipes, since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) * we're not writing to the file system, but we use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) * cprm.limit of 1 here as a special value, this is a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) * consistent way to catch recursive crashes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) * We can still crash if the core_pattern binary sets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) * RLIM_CORE = !1, but it runs as root, and can do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) * lots of stupid things.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) * Note that we use task_tgid_vnr here to grab the pid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) * of the process group leader. That way we get the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) * right pid if a thread in a multi-threaded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) * core_pattern process dies.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) "Process %d(%s) has RLIMIT_CORE set to 1\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) task_tgid_vnr(current), current->comm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) printk(KERN_WARNING "Aborting core\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) goto fail_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) cprm.limit = RLIM_INFINITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) dump_count = atomic_inc_return(&core_dump_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) if (core_pipe_limit && (core_pipe_limit < dump_count)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) printk(KERN_WARNING "Pid %d(%s) over core_pipe_limit\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) task_tgid_vnr(current), current->comm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) printk(KERN_WARNING "Skipping core dump\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) goto fail_dropcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) helper_argv = kmalloc_array(argc + 1, sizeof(*helper_argv),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) if (!helper_argv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) printk(KERN_WARNING "%s failed to allocate memory\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) goto fail_dropcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) for (argi = 0; argi < argc; argi++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) helper_argv[argi] = cn.corename + argv[argi];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) helper_argv[argi] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) retval = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) sub_info = call_usermodehelper_setup(helper_argv[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) helper_argv, NULL, GFP_KERNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) umh_pipe_setup, NULL, &cprm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) if (sub_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) retval = call_usermodehelper_exec(sub_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) UMH_WAIT_EXEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) kfree(helper_argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) printk(KERN_INFO "Core dump to |%s pipe failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) cn.corename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) goto close_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) int open_flags = O_CREAT | O_RDWR | O_NOFOLLOW |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) O_LARGEFILE | O_EXCL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (cprm.limit < binfmt->min_coredump)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) goto fail_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) if (need_suid_safe && cn.corename[0] != '/') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) printk(KERN_WARNING "Pid %d(%s) can only dump core "\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) "to fully qualified path!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) task_tgid_vnr(current), current->comm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) printk(KERN_WARNING "Skipping core dump\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) goto fail_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) * Unlink the file if it exists unless this is a SUID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) * binary - in that case, we're running around with root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) * privs and don't want to unlink another user's coredump.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) if (!need_suid_safe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) * If it doesn't exist, that's fine. If there's some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) * other problem, we'll catch it at the filp_open().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) do_unlinkat(AT_FDCWD, getname_kernel(cn.corename));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) * There is a race between unlinking and creating the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) * file, but if that causes an EEXIST here, that's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) * fine - another process raced with us while creating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) * the corefile, and the other process won. To userspace,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) * what matters is that at least one of the two processes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) * writes its coredump successfully, not which one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) if (need_suid_safe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) * Using user namespaces, normal user tasks can change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) * their current->fs->root to point to arbitrary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) * directories. Since the intention of the "only dump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) * with a fully qualified path" rule is to control where
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) * coredumps may be placed using root privileges,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) * current->fs->root must not be used. Instead, use the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) * root directory of init_task.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) struct path root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) task_lock(&init_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) get_fs_root(init_task.fs, &root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) task_unlock(&init_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) cprm.file = file_open_root(root.dentry, root.mnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) cn.corename, open_flags, 0600);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) path_put(&root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) cprm.file = filp_open(cn.corename, open_flags, 0600);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (IS_ERR(cprm.file))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) goto fail_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) inode = file_inode(cprm.file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if (inode->i_nlink > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) goto close_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) if (d_unhashed(cprm.file->f_path.dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) goto close_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) * AK: actually i see no reason to not allow this for named
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) * pipes etc, but keep the previous behaviour for now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) if (!S_ISREG(inode->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) goto close_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) * Don't dump core if the filesystem changed owner or mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) * of the file during file creation. This is an issue when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) * a process dumps core while its cwd is e.g. on a vfat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) * filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (!uid_eq(inode->i_uid, current_fsuid()))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) goto close_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) if ((inode->i_mode & 0677) != 0600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) goto close_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) if (!(cprm.file->f_mode & FMODE_CAN_WRITE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) goto close_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) if (do_truncate(cprm.file->f_path.dentry, 0, 0, cprm.file))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) goto close_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) /* get us an unshared descriptor table; almost always a no-op */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) retval = unshare_files(&displaced);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) goto close_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) if (displaced)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) put_files_struct(displaced);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (!dump_interrupted()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) * umh disabled with CONFIG_STATIC_USERMODEHELPER_PATH="" would
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) * have this set to NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (!cprm.file) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) pr_info("Core dump to |%s disabled\n", cn.corename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) goto close_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) file_start_write(cprm.file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) core_dumped = binfmt->core_dump(&cprm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) file_end_write(cprm.file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) if (ispipe && core_pipe_limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) wait_for_dump_helpers(cprm.file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) close_fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) if (cprm.file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) filp_close(cprm.file, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) fail_dropcount:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) if (ispipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) atomic_dec(&core_dump_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) fail_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) kfree(argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) kfree(cn.corename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) coredump_finish(mm, core_dumped);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) revert_creds(old_cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) fail_creds:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) put_cred(cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) * Core dumping helper functions. These are the only things you should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) * do on a core-file: use only these functions to write out all the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) * necessary info.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) int dump_emit(struct coredump_params *cprm, const void *addr, int nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) struct file *file = cprm->file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) loff_t pos = file->f_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) ssize_t n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) if (cprm->written + nr > cprm->limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) if (dump_interrupted())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) n = __kernel_write(file, addr, nr, &pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) if (n != nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) file->f_pos = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) cprm->written += n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) cprm->pos += n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) EXPORT_SYMBOL(dump_emit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) int dump_skip(struct coredump_params *cprm, size_t nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) static char zeroes[PAGE_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) struct file *file = cprm->file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) if (file->f_op->llseek && file->f_op->llseek != no_llseek) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) if (dump_interrupted() ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) file->f_op->llseek(file, nr, SEEK_CUR) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) cprm->pos += nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) while (nr > PAGE_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) if (!dump_emit(cprm, zeroes, PAGE_SIZE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) nr -= PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) return dump_emit(cprm, zeroes, nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) EXPORT_SYMBOL(dump_skip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) #ifdef CONFIG_ELF_CORE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) int dump_user_range(struct coredump_params *cprm, unsigned long start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) unsigned long len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) unsigned long addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) for (addr = start; addr < start + len; addr += PAGE_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) struct page *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) int stop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) * To avoid having to allocate page tables for virtual address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) * ranges that have never been used yet, and also to make it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) * easy to generate sparse core files, use a helper that returns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) * NULL when encountering an empty page table entry that would
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) * otherwise have been filled with the zero page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) page = get_dump_page(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) if (page) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) void *kaddr = kmap(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) stop = !dump_emit(cprm, kaddr, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) kunmap(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) put_user_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) stop = !dump_skip(cprm, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (stop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) int dump_align(struct coredump_params *cprm, int align)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) unsigned mod = cprm->pos & (align - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) if (align & (align - 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) return mod ? dump_skip(cprm, align - mod) : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) EXPORT_SYMBOL(dump_align);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) * Ensures that file size is big enough to contain the current file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) * postion. This prevents gdb from complaining about a truncated file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) * if the last "write" to the file was dump_skip.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) void dump_truncate(struct coredump_params *cprm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) struct file *file = cprm->file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) loff_t offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) if (file->f_op->llseek && file->f_op->llseek != no_llseek) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) offset = file->f_op->llseek(file, 0, SEEK_CUR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (i_size_read(file->f_mapping->host) < offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) do_truncate(file->f_path.dentry, offset, 0, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) EXPORT_SYMBOL(dump_truncate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) * The purpose of always_dump_vma() is to make sure that special kernel mappings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) * that are useful for post-mortem analysis are included in every core dump.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) * In that way we ensure that the core dump is fully interpretable later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) * without matching up the same kernel and hardware config to see what PC values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) * meant. These special mappings include - vDSO, vsyscall, and other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) * architecture specific mappings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) static bool always_dump_vma(struct vm_area_struct *vma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) /* Any vsyscall mappings? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) if (vma == get_gate_vma(vma->vm_mm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) * Assume that all vmas with a .name op should always be dumped.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) * If this changes, a new vm_ops field can easily be added.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) if (vma->vm_ops && vma->vm_ops->name && vma->vm_ops->name(vma))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) * arch_vma_name() returns non-NULL for special architecture mappings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) * such as vDSO sections.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) if (arch_vma_name(vma))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) #define DUMP_SIZE_MAYBE_ELFHDR_PLACEHOLDER 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) * Decide how much of @vma's contents should be included in a core dump.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) static unsigned long vma_dump_size(struct vm_area_struct *vma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) unsigned long mm_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) #define FILTER(type) (mm_flags & (1UL << MMF_DUMP_##type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) /* always dump the vdso and vsyscall sections */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) if (always_dump_vma(vma))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) goto whole;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) if (vma->vm_flags & VM_DONTDUMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) /* support for DAX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) if (vma_is_dax(vma)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) if ((vma->vm_flags & VM_SHARED) && FILTER(DAX_SHARED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) goto whole;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) if (!(vma->vm_flags & VM_SHARED) && FILTER(DAX_PRIVATE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) goto whole;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) /* Hugetlb memory check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) if (is_vm_hugetlb_page(vma)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) if ((vma->vm_flags & VM_SHARED) && FILTER(HUGETLB_SHARED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) goto whole;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) if (!(vma->vm_flags & VM_SHARED) && FILTER(HUGETLB_PRIVATE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) goto whole;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) /* Do not dump I/O mapped devices or special mappings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) if (vma->vm_flags & VM_IO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) /* By default, dump shared memory if mapped from an anonymous file. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) if (vma->vm_flags & VM_SHARED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) if (file_inode(vma->vm_file)->i_nlink == 0 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) FILTER(ANON_SHARED) : FILTER(MAPPED_SHARED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) goto whole;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) /* Dump segments that have been written to. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) if ((!IS_ENABLED(CONFIG_MMU) || vma->anon_vma) && FILTER(ANON_PRIVATE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) goto whole;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) if (vma->vm_file == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) if (FILTER(MAPPED_PRIVATE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) goto whole;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) * If this is the beginning of an executable file mapping,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) * dump the first page to aid in determining what was mapped here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) if (FILTER(ELF_HEADERS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) vma->vm_pgoff == 0 && (vma->vm_flags & VM_READ)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) if ((READ_ONCE(file_inode(vma->vm_file)->i_mode) & 0111) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) return PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) * ELF libraries aren't always executable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) * We'll want to check whether the mapping starts with the ELF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) * magic, but not now - we're holding the mmap lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) * so copy_from_user() doesn't work here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) * Use a placeholder instead, and fix it up later in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) * dump_vma_snapshot().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) return DUMP_SIZE_MAYBE_ELFHDR_PLACEHOLDER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) #undef FILTER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) whole:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) return vma->vm_end - vma->vm_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) static struct vm_area_struct *first_vma(struct task_struct *tsk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) struct vm_area_struct *gate_vma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) struct vm_area_struct *ret = tsk->mm->mmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) return gate_vma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) * Helper function for iterating across a vma list. It ensures that the caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) * will visit `gate_vma' prior to terminating the search.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) static struct vm_area_struct *next_vma(struct vm_area_struct *this_vma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) struct vm_area_struct *gate_vma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) struct vm_area_struct *ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) ret = this_vma->vm_next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) if (this_vma == gate_vma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) return gate_vma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) * Under the mmap_lock, take a snapshot of relevant information about the task's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) * VMAs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) int dump_vma_snapshot(struct coredump_params *cprm, int *vma_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) struct core_vma_metadata **vma_meta,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) size_t *vma_data_size_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) struct vm_area_struct *vma, *gate_vma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) struct mm_struct *mm = current->mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) size_t vma_data_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) * Once the stack expansion code is fixed to not change VMA bounds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) * under mmap_lock in read mode, this can be changed to take the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) * mmap_lock in read mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) if (mmap_write_lock_killable(mm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) return -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) gate_vma = get_gate_vma(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) *vma_count = mm->map_count + (gate_vma ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) *vma_meta = kvmalloc_array(*vma_count, sizeof(**vma_meta), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) if (!*vma_meta) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) mmap_write_unlock(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) for (i = 0, vma = first_vma(current, gate_vma); vma != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) vma = next_vma(vma, gate_vma), i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) struct core_vma_metadata *m = (*vma_meta) + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) m->start = vma->vm_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) m->end = vma->vm_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) m->flags = vma->vm_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) m->dump_size = vma_dump_size(vma, cprm->mm_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) mmap_write_unlock(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) if (WARN_ON(i != *vma_count)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) kvfree(*vma_meta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) for (i = 0; i < *vma_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) struct core_vma_metadata *m = (*vma_meta) + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) if (m->dump_size == DUMP_SIZE_MAYBE_ELFHDR_PLACEHOLDER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) char elfmag[SELFMAG];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) if (copy_from_user(elfmag, (void __user *)m->start, SELFMAG) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) memcmp(elfmag, ELFMAG, SELFMAG) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) m->dump_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) m->dump_size = PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) vma_data_size += m->dump_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) *vma_data_size_ptr = vma_data_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) }