From 447df53837ad4be87ffc0cfa922446bab2055ed8 Mon Sep 17 00:00:00 2001 From: zhaoxiaoqiang11 Date: Mon, 31 Jul 2023 14:35:02 +0800 Subject: [PATCH 1/3] coredump: make core_pattern container aware jingdong inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I7NJIW ---------------------------------------------------- Userspace coredump file is generated on the basis of /proc/sys/kernel/core_pattern and this is a global configuration. In the container environment, the need for configuration may varies for different containers. By switching the configuration from global to mount namespace basis, container users can set it to desired values and do not interfere with each other. Signed-off-by: zhaoxiaoqiang11 Reviewed-by: zhangwei123171 --- fs/Kconfig | 8 ++++++++ fs/coredump.c | 12 +++++++++++- fs/mount.h | 6 ++++++ fs/namespace.c | 6 ++++++ kernel/sysctl.c | 39 ++++++++++++++++++++++++++++++++++----- 5 files changed, 65 insertions(+), 6 deletions(-) diff --git a/fs/Kconfig b/fs/Kconfig index 385602ba0d99..f9985671c6a3 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -395,3 +395,11 @@ config RESCTRL help Memory Partitioning and Monitoring. More exactly Memory system performance resource Partitioning and Monitoring + +config CORE_PATTERN_ISOLATION + bool "Core pattern isolation per mount namespace" + depends on COREDUMP + default n + help + Userspace coredump file is generated according to the per mount + namespace core_pattern string instead of the global one. diff --git a/fs/coredump.c b/fs/coredump.c index 6c0d0a42fda9..c641c28b2e23 100644 --- a/fs/coredump.c +++ b/fs/coredump.c @@ -52,13 +52,18 @@ #include "internal.h" #include +#ifdef CONFIG_CORE_PATTERN_ISOLATION +#include "mount.h" +#endif static bool dump_vma_snapshot(struct coredump_params *cprm); static void free_vma_snapshot(struct coredump_params *cprm); int core_uses_pid; unsigned int core_pipe_limit; +#ifndef CONFIG_CORE_PATTERN_ISOLATION char core_pattern[CORENAME_MAX_SIZE] = "core"; +#endif static int core_name_size = CORENAME_MAX_SIZE; struct core_name { @@ -201,7 +206,12 @@ static int format_corename(struct core_name *cn, struct coredump_params *cprm, size_t **argv, int *argc) { const struct cred *cred = current_cred(); +#ifdef CONFIG_CORE_PATTERN_ISOLATION + const char *pat_ptr = current->nsproxy->mnt_ns->core_pattern; +#else const char *pat_ptr = core_pattern; +#endif + int ispipe = (*pat_ptr == '|'); bool was_space = false; int pid_in_pattern = 0; @@ -214,7 +224,7 @@ static int format_corename(struct core_name *cn, struct coredump_params *cprm, cn->corename[0] = '\0'; if (ispipe) { - int argvs = sizeof(core_pattern) / 2; + int argvs = CORENAME_MAX_SIZE / 2; (*argv) = kmalloc_array(argvs, sizeof(**argv), GFP_KERNEL); if (!(*argv)) return -ENOMEM; diff --git a/fs/mount.h b/fs/mount.h index c7abb7b394d8..a778099a7aaf 100644 --- a/fs/mount.h +++ b/fs/mount.h @@ -4,6 +4,9 @@ #include #include #include +#ifdef CONFIG_CORE_PATTERN_ISOLATION +#include +#endif struct mnt_namespace { atomic_t count; @@ -23,6 +26,9 @@ struct mnt_namespace { u64 event; unsigned int mounts; /* # of mounts in the namespace */ unsigned int pending_mounts; +#ifdef CONFIG_CORE_PATTERN_ISOLATION + char core_pattern[CORENAME_MAX_SIZE]; +#endif } __randomize_layout; struct mnt_pcp { diff --git a/fs/namespace.c b/fs/namespace.c index 6e76f2a72cfc..739cf0c2fc7b 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -3305,6 +3305,9 @@ static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns, bool a spin_lock_init(&new_ns->ns_lock); new_ns->user_ns = get_user_ns(user_ns); new_ns->ucounts = ucounts; +#ifdef CONFIG_CORE_PATTERN_ISOLATION + strncpy(new_ns->core_pattern, "core", CORENAME_MAX_SIZE); +#endif return new_ns; } @@ -3333,6 +3336,9 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns, return new_ns; namespace_lock(); +#ifdef CONFIG_CORE_PATTERN_ISOLATION + strncpy(new_ns->core_pattern, ns->core_pattern, CORENAME_MAX_SIZE); +#endif /* First pass: copy the tree topology */ copy_flags = CL_COPY_UNBINDABLE | CL_EXPIRE; if (user_ns != ns->user_ns) diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 078bbe07becd..c8e2f16fbacf 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -71,6 +71,9 @@ #include #include #include +#ifdef CONFIG_CORE_PATTERN_ISOLATION +#include "../fs/mount.h" +#endif #include "../lib/kstrtox.h" @@ -1096,14 +1099,24 @@ static int proc_dopipe_max_size(struct ctl_table *table, int write, static void validate_coredump_safety(void) { #ifdef CONFIG_COREDUMP +#ifdef CONFIG_CORE_PATTERN_ISOLATION + char *core_pattern = current->nsproxy->mnt_ns->core_pattern; +#endif if (suid_dumpable == SUID_DUMP_ROOT && core_pattern[0] != '/' && core_pattern[0] != '|') { - printk(KERN_WARNING -"Unsafe core_pattern used with fs.suid_dumpable=2.\n" -"Pipe handler or fully qualified core dump path required.\n" -"Set kernel.core_pattern before fs.suid_dumpable.\n" + pr_warn("Unsafe core_pattern used with fs.suid_dumpable=2.\n" + "Pipe handler or fully qualified core dump path required.\n" + "Set kernel.core_pattern before fs.suid_dumpable.\n" ); } + +#ifdef CONFIG_CORE_PATTERN_ISOLATION + if (current->nsproxy->mnt_ns != init_task.nsproxy->mnt_ns + && core_pattern[0] == '|') { + pr_warn("core_pattern with pipe is setted in container environment.\n" + "Pipe handler will be lookup in init mnt ns.\n"); + } +#endif #endif } @@ -1120,9 +1133,21 @@ static int proc_dointvec_minmax_coredump(struct ctl_table *table, int write, static int proc_dostring_coredump(struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos) { - int error = proc_dostring(table, write, buffer, lenp, ppos); + int error; +#ifdef CONFIG_CORE_PATTERN_ISOLATION + struct mnt_namespace *mnt = current->nsproxy->mnt_ns; + + if (write) + proc_first_pos_non_zero_ignore(ppos, table); + + error = _proc_do_string((char *)(mnt->core_pattern), + table->maxlen, write, (char __user *)buffer, lenp, ppos); +#else + error = proc_dostring(table, write, buffer, lenp, ppos); +#endif if (!error) validate_coredump_safety(); + return error; } #endif @@ -1925,7 +1950,11 @@ static struct ctl_table kern_table[] = { }, { .procname = "core_pattern", +#ifdef CONFIG_CORE_PATTERN_ISOLATION + .data = NULL, +#else .data = core_pattern, +#endif .maxlen = CORENAME_MAX_SIZE, .mode = 0644, .proc_handler = proc_dostring_coredump, -- Gitee From 2021055584a5fb555cce529ab8b310529521b10c Mon Sep 17 00:00:00 2001 From: zhaoxiaoqiang11 Date: Thu, 10 Aug 2023 12:16:24 +0800 Subject: [PATCH 2/3] coredump: fix kabi breakage jingdong inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I7NJIW ---------------------------------------------------- fix kabi breakage by previous commit 94167e694284: coredump: make core_pattern container aware Suggested by @x56Jason Signed-off-by: zhaoxiaoqiang11 Reviewed-by: zhangwei123171 --- fs/mount.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/mount.h b/fs/mount.h index a778099a7aaf..1d7052257567 100644 --- a/fs/mount.h +++ b/fs/mount.h @@ -5,8 +5,10 @@ #include #include #ifdef CONFIG_CORE_PATTERN_ISOLATION +#ifndef __GENKSYMS__ #include #endif +#endif struct mnt_namespace { atomic_t count; @@ -27,7 +29,7 @@ struct mnt_namespace { unsigned int mounts; /* # of mounts in the namespace */ unsigned int pending_mounts; #ifdef CONFIG_CORE_PATTERN_ISOLATION - char core_pattern[CORENAME_MAX_SIZE]; + KABI_EXTEND(char core_pattern[CORENAME_MAX_SIZE]) #endif } __randomize_layout; -- Gitee From 267042a79e38ea7cf5cb3695327ec5bf26d69c68 Mon Sep 17 00:00:00 2001 From: zhaoxiaoqiang11 Date: Mon, 7 Aug 2023 17:23:26 +0800 Subject: [PATCH 3/3] coredump: enable core pattern isolation by default jingdong inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I7NJIW ---------------------------------------------------- enable CONFIG_CORE_PATTERN_ISOLATION option Signed-off-by: zhaoxiaoqiang11 Reviewed-by: zhangwei123171 --- arch/arm64/configs/openeuler_defconfig | 1 + arch/x86/configs/openeuler_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig index f055d8e93bc4..0f0c027d0d7e 100644 --- a/arch/arm64/configs/openeuler_defconfig +++ b/arch/arm64/configs/openeuler_defconfig @@ -7334,3 +7334,4 @@ CONFIG_ARCH_HAS_KCOV=y # CONFIG_MEMTEST is not set # end of Kernel Testing and Coverage # end of Kernel hacking +CONFIG_CORE_PATTERN_ISOLATION=y diff --git a/arch/x86/configs/openeuler_defconfig b/arch/x86/configs/openeuler_defconfig index 9adedd9d615a..15765da384c3 100644 --- a/arch/x86/configs/openeuler_defconfig +++ b/arch/x86/configs/openeuler_defconfig @@ -8433,3 +8433,4 @@ CONFIG_ARCH_HAS_KCOV=y # CONFIG_HYPERV_TESTING is not set # end of Kernel Testing and Coverage # end of Kernel hacking +CONFIG_CORE_PATTERN_ISOLATION=y -- Gitee