Missing, failed, or corrupted core dumps might impede crash investigations. To improve reliability of that process and consequently the programs themselves, one needs to trace the path from producing a core dumpfile to analyzing it. That path starts from the core dump file written to the disk by the kernel or to the standard input of a user mode helper program to which the kernel streams the coredump contents. There are cases where the kernel will interrupt writing the core out or produce a truncated/not-well-formed core dump without leaving a note. Add logging for the core dump collection failure paths to be able to reason what has gone wrong when the core dump is malformed or missing. Report the size of the data written to aid in diagnosing the user mode helper. Signed-off-by: Roman Kisel <romank@linux.microsoft.com> Link: https://lore.kernel.org/r/20240718182743.1959160-3-romank@linux.microsoft.com Signed-off-by: Kees Cook <kees@kernel.org>
83 lines
2.2 KiB
C
83 lines
2.2 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef _LINUX_COREDUMP_H
|
|
#define _LINUX_COREDUMP_H
|
|
|
|
#include <linux/types.h>
|
|
#include <linux/mm.h>
|
|
#include <linux/fs.h>
|
|
#include <asm/siginfo.h>
|
|
|
|
#ifdef CONFIG_COREDUMP
|
|
struct core_vma_metadata {
|
|
unsigned long start, end;
|
|
unsigned long flags;
|
|
unsigned long dump_size;
|
|
unsigned long pgoff;
|
|
struct file *file;
|
|
};
|
|
|
|
struct coredump_params {
|
|
const kernel_siginfo_t *siginfo;
|
|
struct file *file;
|
|
unsigned long limit;
|
|
unsigned long mm_flags;
|
|
int cpu;
|
|
loff_t written;
|
|
loff_t pos;
|
|
loff_t to_skip;
|
|
int vma_count;
|
|
size_t vma_data_size;
|
|
struct core_vma_metadata *vma_meta;
|
|
};
|
|
|
|
extern unsigned int core_file_note_size_limit;
|
|
|
|
/*
|
|
* These are the only things you should do on a core-file: use only these
|
|
* functions to write out all the necessary info.
|
|
*/
|
|
extern void dump_skip_to(struct coredump_params *cprm, unsigned long to);
|
|
extern void dump_skip(struct coredump_params *cprm, size_t nr);
|
|
extern int dump_emit(struct coredump_params *cprm, const void *addr, int nr);
|
|
extern int dump_align(struct coredump_params *cprm, int align);
|
|
int dump_user_range(struct coredump_params *cprm, unsigned long start,
|
|
unsigned long len);
|
|
extern int do_coredump(const kernel_siginfo_t *siginfo);
|
|
|
|
/*
|
|
* Logging for the coredump code, ratelimited.
|
|
* The TGID and comm fields are added to the message.
|
|
*/
|
|
|
|
#define __COREDUMP_PRINTK(Level, Format, ...) \
|
|
do { \
|
|
char comm[TASK_COMM_LEN]; \
|
|
\
|
|
get_task_comm(comm, current); \
|
|
printk_ratelimited(Level "coredump: %d(%*pE): " Format "\n", \
|
|
task_tgid_vnr(current), (int)strlen(comm), comm, ##__VA_ARGS__); \
|
|
} while (0) \
|
|
|
|
#define coredump_report(fmt, ...) __COREDUMP_PRINTK(KERN_INFO, fmt, ##__VA_ARGS__)
|
|
#define coredump_report_failure(fmt, ...) __COREDUMP_PRINTK(KERN_WARNING, fmt, ##__VA_ARGS__)
|
|
|
|
#else
|
|
static inline int do_coredump(const kernel_siginfo_t *siginfo)
|
|
{
|
|
/* Coredump support is not available, can't fail. */
|
|
return 0;
|
|
}
|
|
|
|
#define coredump_report(...)
|
|
#define coredump_report_failure(...)
|
|
|
|
#endif
|
|
|
|
#if defined(CONFIG_COREDUMP) && defined(CONFIG_SYSCTL)
|
|
extern void validate_coredump_safety(void);
|
|
#else
|
|
static inline void validate_coredump_safety(void) {}
|
|
#endif
|
|
|
|
#endif /* _LINUX_COREDUMP_H */
|