diff options
author | Kees Cook <keescook@chromium.org> | 2012-07-30 17:39:18 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-30 20:25:11 -0400 |
commit | 54b501992dd2a839e94e76aa392c392b55080ce8 (patch) | |
tree | 6d174fb95516f01e385d31d5ef87a248d8740fd2 /kernel/sysctl.c | |
parent | 9520628e8ceb69fa9a4aee6b57f22675d9e1b709 (diff) |
coredump: warn about unsafe suid_dumpable / core_pattern combo
When suid_dumpable=2, detect unsafe core_pattern settings and warn when
they are seen.
Signed-off-by: Kees Cook <keescook@chromium.org>
Suggested-by: Andrew Morton <akpm@linux-foundation.org>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Alan Cox <alan@linux.intel.com>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Doug Ledford <dledford@redhat.com>
Cc: Serge Hallyn <serge.hallyn@canonical.com>
Cc: James Morris <james.l.morris@oracle.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/sysctl.c')
-rw-r--r-- | kernel/sysctl.c | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 4ab11879aeb4..b46f496405e4 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -174,6 +174,11 @@ static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write, | |||
174 | void __user *buffer, size_t *lenp, loff_t *ppos); | 174 | void __user *buffer, size_t *lenp, loff_t *ppos); |
175 | #endif | 175 | #endif |
176 | 176 | ||
177 | static int proc_dointvec_minmax_coredump(struct ctl_table *table, int write, | ||
178 | void __user *buffer, size_t *lenp, loff_t *ppos); | ||
179 | static int proc_dostring_coredump(struct ctl_table *table, int write, | ||
180 | void __user *buffer, size_t *lenp, loff_t *ppos); | ||
181 | |||
177 | #ifdef CONFIG_MAGIC_SYSRQ | 182 | #ifdef CONFIG_MAGIC_SYSRQ |
178 | /* Note: sysrq code uses it's own private copy */ | 183 | /* Note: sysrq code uses it's own private copy */ |
179 | static int __sysrq_enabled = SYSRQ_DEFAULT_ENABLE; | 184 | static int __sysrq_enabled = SYSRQ_DEFAULT_ENABLE; |
@@ -410,7 +415,7 @@ static struct ctl_table kern_table[] = { | |||
410 | .data = core_pattern, | 415 | .data = core_pattern, |
411 | .maxlen = CORENAME_MAX_SIZE, | 416 | .maxlen = CORENAME_MAX_SIZE, |
412 | .mode = 0644, | 417 | .mode = 0644, |
413 | .proc_handler = proc_dostring, | 418 | .proc_handler = proc_dostring_coredump, |
414 | }, | 419 | }, |
415 | { | 420 | { |
416 | .procname = "core_pipe_limit", | 421 | .procname = "core_pipe_limit", |
@@ -1498,7 +1503,7 @@ static struct ctl_table fs_table[] = { | |||
1498 | .data = &suid_dumpable, | 1503 | .data = &suid_dumpable, |
1499 | .maxlen = sizeof(int), | 1504 | .maxlen = sizeof(int), |
1500 | .mode = 0644, | 1505 | .mode = 0644, |
1501 | .proc_handler = proc_dointvec_minmax, | 1506 | .proc_handler = proc_dointvec_minmax_coredump, |
1502 | .extra1 = &zero, | 1507 | .extra1 = &zero, |
1503 | .extra2 = &two, | 1508 | .extra2 = &two, |
1504 | }, | 1509 | }, |
@@ -2009,6 +2014,34 @@ int proc_dointvec_minmax(struct ctl_table *table, int write, | |||
2009 | do_proc_dointvec_minmax_conv, ¶m); | 2014 | do_proc_dointvec_minmax_conv, ¶m); |
2010 | } | 2015 | } |
2011 | 2016 | ||
2017 | static void validate_coredump_safety(void) | ||
2018 | { | ||
2019 | if (suid_dumpable == SUID_DUMPABLE_SAFE && | ||
2020 | core_pattern[0] != '/' && core_pattern[0] != '|') { | ||
2021 | printk(KERN_WARNING "Unsafe core_pattern used with "\ | ||
2022 | "suid_dumpable=2. Pipe handler or fully qualified "\ | ||
2023 | "core dump path required.\n"); | ||
2024 | } | ||
2025 | } | ||
2026 | |||
2027 | static int proc_dointvec_minmax_coredump(struct ctl_table *table, int write, | ||
2028 | void __user *buffer, size_t *lenp, loff_t *ppos) | ||
2029 | { | ||
2030 | int error = proc_dointvec_minmax(table, write, buffer, lenp, ppos); | ||
2031 | if (!error) | ||
2032 | validate_coredump_safety(); | ||
2033 | return error; | ||
2034 | } | ||
2035 | |||
2036 | static int proc_dostring_coredump(struct ctl_table *table, int write, | ||
2037 | void __user *buffer, size_t *lenp, loff_t *ppos) | ||
2038 | { | ||
2039 | int error = proc_dostring(table, write, buffer, lenp, ppos); | ||
2040 | if (!error) | ||
2041 | validate_coredump_safety(); | ||
2042 | return error; | ||
2043 | } | ||
2044 | |||
2012 | static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int write, | 2045 | static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int write, |
2013 | void __user *buffer, | 2046 | void __user *buffer, |
2014 | size_t *lenp, loff_t *ppos, | 2047 | size_t *lenp, loff_t *ppos, |