[Devel] [PATCH RHEL7 COMMIT] ve/coredump: virtualize kernel.core_pattern sysctl
Konstantin Khorenko
khorenko at virtuozzo.com
Wed Feb 3 07:05:24 PST 2016
The commit is pushed to "branch-rh7-3.10.0-327.3.1-vz7.10.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-327.3.1.vz7.10.9
------>
commit ebb9ccc798cce53881de630e5c0c9ab67e2c3175
Author: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
Date: Wed Feb 3 19:05:24 2016 +0400
ve/coredump: virtualize kernel.core_pattern sysctl
1) put core_pattern on ve_struct and add virtualized proc_handler
using macro sysctl_virtual()
2) use in-container khelper kthread for collecting cores
We need support of pipe'ing coredump in CT. If process crashes
in CT and kernel.core_pattern begins with "|" we get error:
CT:
CT-101-bash-4.2# sysctl kernel.core_pattern
kernel.core_pattern = |/root/core_test %p UID=%u GID=%g sig=%s
CT-101-bash-4.2# sleep 100 &
[1] 445
CT-101-bash-4.2# kill -11 445
CT-101-bash-4.2#
[1]+ Segmentation fault sleep 100
CT-101-bash-4.2# ll /root
total 8
rwxr-xr-x 1 root root 7424 Jan 27 17:28 core_test
Host:
[root at s143 ~]# less /var/log/messages
Jan 28 10:40:42 s143 kernel: [87698.969582] Core dump to
|/root/core_test 445 UID=0 GID=0 sig=11 pipe failed
Also docker is going to use pipe'ing in coredumps functionality:
https://github.com/docker/docker/issues/19289
https://jira.sw.ru/browse/PSBM-43596
v2: split sysctl_virtual in separate patch
Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
Reviewed-by: Andrey Ryabinin <aryabinin at virtuozzo.com>
---
fs/coredump.c | 14 +++++---------
include/linux/ve.h | 4 ++++
kernel/sysctl.c | 14 +++++++++-----
kernel/ve/ve.c | 4 ++++
4 files changed, 22 insertions(+), 14 deletions(-)
diff --git a/fs/coredump.c b/fs/coredump.c
index 8118760..e3fdee2 100644
--- a/fs/coredump.c
+++ b/fs/coredump.c
@@ -32,6 +32,7 @@
#include <linux/pipe_fs_i.h>
#include <linux/oom.h>
#include <linux/compat.h>
+#include <linux/ve.h>
#include <asm/uaccess.h>
#include <asm/mmu_context.h>
@@ -45,7 +46,6 @@
#include <trace/events/sched.h>
int core_uses_pid;
-char core_pattern[CORENAME_MAX_SIZE] = "core";
unsigned int core_pipe_limit;
struct core_name {
@@ -152,7 +152,7 @@ put_exe_file:
static int format_corename(struct core_name *cn, struct coredump_params *cprm)
{
const struct cred *cred = current_cred();
- const char *pat_ptr = core_pattern;
+ const char *pat_ptr = get_exec_env()->core_pattern;
int ispipe = (*pat_ptr == '|');
int pid_in_pattern = 0;
int err = 0;
@@ -560,7 +560,6 @@ void do_coredump(siginfo_t *siginfo)
if (ispipe) {
int dump_count;
char **helper_argv;
- struct subprocess_info *sub_info;
if (ispipe < 0) {
printk(KERN_WARNING "format_corename failed\n");
@@ -608,12 +607,9 @@ void do_coredump(siginfo_t *siginfo)
}
retval = -ENOMEM;
- sub_info = call_usermodehelper_setup(helper_argv[0],
- helper_argv, NULL, GFP_KERNEL,
- umh_pipe_setup, NULL, &cprm);
- if (sub_info)
- retval = call_usermodehelper_exec(sub_info,
- UMH_WAIT_EXEC);
+ retval = call_usermodehelper_fns_ve(get_exec_env(), helper_argv[0],
+ helper_argv, NULL, UMH_WAIT_EXEC,
+ umh_pipe_setup, NULL, &cprm);
argv_free(helper_argv);
if (retval) {
diff --git a/include/linux/ve.h b/include/linux/ve.h
index d81fa36..5d3b5aa 100644
--- a/include/linux/ve.h
+++ b/include/linux/ve.h
@@ -25,6 +25,7 @@
#include <net/inet_frag.h>
#include <linux/cgroup.h>
#include <linux/kmapset.h>
+#include <linux/binfmts.h>
struct tty_driver;
struct file_system_type;
@@ -126,6 +127,9 @@ struct ve_struct {
* and the VE unmounts it. This is acceptable.
*/
int mnt_nr;
+#ifdef CONFIG_COREDUMP
+ char core_pattern[CORENAME_MAX_SIZE];
+#endif
};
struct ve_devmnt {
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index c2dbbf7..867eb5a 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -102,7 +102,6 @@ extern int max_threads;
extern int suid_dumpable;
#ifdef CONFIG_COREDUMP
extern int core_uses_pid;
-extern char core_pattern[];
extern unsigned int core_pipe_limit;
#endif
extern int pid_max_min, pid_max_max;
@@ -296,6 +295,10 @@ static int proc_dointvec_pidmax(struct ctl_table *table, int write,
return proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
}
+#ifdef CONFIG_COREDUMP
+sysctl_virtual(proc_dostring_coredump);
+#endif
+
static struct ctl_table kern_table[] = {
{
.procname = "sched_child_runs_first",
@@ -524,10 +527,10 @@ static struct ctl_table kern_table[] = {
},
{
.procname = "core_pattern",
- .data = core_pattern,
+ .data = ve0.core_pattern,
.maxlen = CORENAME_MAX_SIZE,
- .mode = 0644,
- .proc_handler = proc_dostring_coredump,
+ .mode = 0644 | S_ISVTX,
+ .proc_handler = proc_dostring_coredump_virtual,
},
{
.procname = "core_pipe_limit",
@@ -2265,9 +2268,10 @@ int proc_dointvec_minmax(struct ctl_table *table, int write,
static void validate_coredump_safety(void)
{
+ struct ve_struct *ve = get_exec_env();
#ifdef CONFIG_COREDUMP
if (suid_dumpable == SUID_DUMP_ROOT &&
- core_pattern[0] != '/' && core_pattern[0] != '|') {
+ ve->core_pattern[0] != '/' && ve->core_pattern[0] != '|') {
printk(KERN_WARNING "Unsafe core_pattern used with "\
"suid_dumpable=2. Pipe handler or fully qualified "\
"core dump path required.\n");
diff --git a/kernel/ve/ve.c b/kernel/ve/ve.c
index 4d2b3a8..2408c3e 100644
--- a/kernel/ve/ve.c
+++ b/kernel/ve/ve.c
@@ -653,6 +653,10 @@ do_init:
#endif
ve->mnt_nr = 0;
+#ifdef CONFIG_COREDUMP
+ strcpy(ve->core_pattern, "core");
+#endif
+
return &ve->css;
err_log:
More information about the Devel
mailing list