aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorSteven Rostedt (VMware) <rostedt@goodmis.org>2019-10-11 17:22:50 -0400
committerSteven Rostedt (VMware) <rostedt@goodmis.org>2019-10-12 20:48:06 -0400
commit17911ff38aa58d3c95c07589dbf5d3564c4cf3c5 (patch)
tree0437649533f3c50b4207fd9368bf47ae06bcfe95 /kernel
parent8530dec63e7b486e3761cc3d74a22de301845ff5 (diff)
tracing: Add locked_down checks to the open calls of files created for tracefs
Added various checks on open tracefs calls to see if tracefs is in lockdown mode, and if so, to return -EPERM. Note, the event format files (which are basically standard on all machines) as well as the enabled_functions file (which shows what is currently being traced) are not lockde down. Perhaps they should be, but it seems counter intuitive to lockdown information to help you know if the system has been modified. Link: http://lkml.kernel.org/r/CAHk-=wj7fGPKUspr579Cii-w_y60PtRaiDgKuxVtBAMK0VNNkA@mail.gmail.com Suggested-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/trace/ftrace.c23
-rw-r--r--kernel/trace/trace.c8
-rw-r--r--kernel/trace/trace_events.c8
-rw-r--r--kernel/trace/trace_events_hist.c11
-rw-r--r--kernel/trace/trace_events_trigger.c8
-rw-r--r--kernel/trace/trace_kprobe.c12
-rw-r--r--kernel/trace/trace_printk.c7
-rw-r--r--kernel/trace/trace_stack.c8
-rw-r--r--kernel/trace/trace_stat.c6
-rw-r--r--kernel/trace/trace_uprobe.c11
10 files changed, 98 insertions, 4 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 8b765a55e01c..f296d89be757 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -18,6 +18,7 @@
18#include <linux/clocksource.h> 18#include <linux/clocksource.h>
19#include <linux/sched/task.h> 19#include <linux/sched/task.h>
20#include <linux/kallsyms.h> 20#include <linux/kallsyms.h>
21#include <linux/security.h>
21#include <linux/seq_file.h> 22#include <linux/seq_file.h>
22#include <linux/tracefs.h> 23#include <linux/tracefs.h>
23#include <linux/hardirq.h> 24#include <linux/hardirq.h>
@@ -3486,6 +3487,11 @@ static int
3486ftrace_avail_open(struct inode *inode, struct file *file) 3487ftrace_avail_open(struct inode *inode, struct file *file)
3487{ 3488{
3488 struct ftrace_iterator *iter; 3489 struct ftrace_iterator *iter;
3490 int ret;
3491
3492 ret = security_locked_down(LOCKDOWN_TRACEFS);
3493 if (ret)
3494 return ret;
3489 3495
3490 if (unlikely(ftrace_disabled)) 3496 if (unlikely(ftrace_disabled))
3491 return -ENODEV; 3497 return -ENODEV;
@@ -3505,6 +3511,15 @@ ftrace_enabled_open(struct inode *inode, struct file *file)
3505{ 3511{
3506 struct ftrace_iterator *iter; 3512 struct ftrace_iterator *iter;
3507 3513
3514 /*
3515 * This shows us what functions are currently being
3516 * traced and by what. Not sure if we want lockdown
3517 * to hide such critical information for an admin.
3518 * Although, perhaps it can show information we don't
3519 * want people to see, but if something is tracing
3520 * something, we probably want to know about it.
3521 */
3522
3508 iter = __seq_open_private(file, &show_ftrace_seq_ops, sizeof(*iter)); 3523 iter = __seq_open_private(file, &show_ftrace_seq_ops, sizeof(*iter));
3509 if (!iter) 3524 if (!iter)
3510 return -ENOMEM; 3525 return -ENOMEM;
@@ -3625,6 +3640,7 @@ ftrace_filter_open(struct inode *inode, struct file *file)
3625{ 3640{
3626 struct ftrace_ops *ops = inode->i_private; 3641 struct ftrace_ops *ops = inode->i_private;
3627 3642
3643 /* Checks for tracefs lockdown */
3628 return ftrace_regex_open(ops, 3644 return ftrace_regex_open(ops,
3629 FTRACE_ITER_FILTER | FTRACE_ITER_DO_PROBES, 3645 FTRACE_ITER_FILTER | FTRACE_ITER_DO_PROBES,
3630 inode, file); 3646 inode, file);
@@ -3635,6 +3651,7 @@ ftrace_notrace_open(struct inode *inode, struct file *file)
3635{ 3651{
3636 struct ftrace_ops *ops = inode->i_private; 3652 struct ftrace_ops *ops = inode->i_private;
3637 3653
3654 /* Checks for tracefs lockdown */
3638 return ftrace_regex_open(ops, FTRACE_ITER_NOTRACE, 3655 return ftrace_regex_open(ops, FTRACE_ITER_NOTRACE,
3639 inode, file); 3656 inode, file);
3640} 3657}
@@ -5203,9 +5220,13 @@ static int
5203__ftrace_graph_open(struct inode *inode, struct file *file, 5220__ftrace_graph_open(struct inode *inode, struct file *file,
5204 struct ftrace_graph_data *fgd) 5221 struct ftrace_graph_data *fgd)
5205{ 5222{
5206 int ret = 0; 5223 int ret;
5207 struct ftrace_hash *new_hash = NULL; 5224 struct ftrace_hash *new_hash = NULL;
5208 5225
5226 ret = security_locked_down(LOCKDOWN_TRACEFS);
5227 if (ret)
5228 return ret;
5229
5209 if (file->f_mode & FMODE_WRITE) { 5230 if (file->f_mode & FMODE_WRITE) {
5210 const int size_bits = FTRACE_HASH_DEFAULT_BITS; 5231 const int size_bits = FTRACE_HASH_DEFAULT_BITS;
5211 5232
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 26ee280f852b..2b4eff383505 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -17,6 +17,7 @@
17#include <linux/stacktrace.h> 17#include <linux/stacktrace.h>
18#include <linux/writeback.h> 18#include <linux/writeback.h>
19#include <linux/kallsyms.h> 19#include <linux/kallsyms.h>
20#include <linux/security.h>
20#include <linux/seq_file.h> 21#include <linux/seq_file.h>
21#include <linux/notifier.h> 22#include <linux/notifier.h>
22#include <linux/irqflags.h> 23#include <linux/irqflags.h>
@@ -306,6 +307,12 @@ void trace_array_put(struct trace_array *this_tr)
306 307
307int tracing_check_open_get_tr(struct trace_array *tr) 308int tracing_check_open_get_tr(struct trace_array *tr)
308{ 309{
310 int ret;
311
312 ret = security_locked_down(LOCKDOWN_TRACEFS);
313 if (ret)
314 return ret;
315
309 if (tracing_disabled) 316 if (tracing_disabled)
310 return -ENODEV; 317 return -ENODEV;
311 318
@@ -6813,6 +6820,7 @@ static int snapshot_raw_open(struct inode *inode, struct file *filp)
6813 struct ftrace_buffer_info *info; 6820 struct ftrace_buffer_info *info;
6814 int ret; 6821 int ret;
6815 6822
6823 /* The following checks for tracefs lockdown */
6816 ret = tracing_buffers_open(inode, filp); 6824 ret = tracing_buffers_open(inode, filp);
6817 if (ret < 0) 6825 if (ret < 0)
6818 return ret; 6826 return ret;
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 71ab0a3660f4..fba87d10f0c1 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -12,6 +12,7 @@
12#define pr_fmt(fmt) fmt 12#define pr_fmt(fmt) fmt
13 13
14#include <linux/workqueue.h> 14#include <linux/workqueue.h>
15#include <linux/security.h>
15#include <linux/spinlock.h> 16#include <linux/spinlock.h>
16#include <linux/kthread.h> 17#include <linux/kthread.h>
17#include <linux/tracefs.h> 18#include <linux/tracefs.h>
@@ -1294,6 +1295,8 @@ static int trace_format_open(struct inode *inode, struct file *file)
1294 struct seq_file *m; 1295 struct seq_file *m;
1295 int ret; 1296 int ret;
1296 1297
1298 /* Do we want to hide event format files on tracefs lockdown? */
1299
1297 ret = seq_open(file, &trace_format_seq_ops); 1300 ret = seq_open(file, &trace_format_seq_ops);
1298 if (ret < 0) 1301 if (ret < 0)
1299 return ret; 1302 return ret;
@@ -1760,6 +1763,10 @@ ftrace_event_open(struct inode *inode, struct file *file,
1760 struct seq_file *m; 1763 struct seq_file *m;
1761 int ret; 1764 int ret;
1762 1765
1766 ret = security_locked_down(LOCKDOWN_TRACEFS);
1767 if (ret)
1768 return ret;
1769
1763 ret = seq_open(file, seq_ops); 1770 ret = seq_open(file, seq_ops);
1764 if (ret < 0) 1771 if (ret < 0)
1765 return ret; 1772 return ret;
@@ -1784,6 +1791,7 @@ ftrace_event_avail_open(struct inode *inode, struct file *file)
1784{ 1791{
1785 const struct seq_operations *seq_ops = &show_event_seq_ops; 1792 const struct seq_operations *seq_ops = &show_event_seq_ops;
1786 1793
1794 /* Checks for tracefs lockdown */
1787 return ftrace_event_open(inode, file, seq_ops); 1795 return ftrace_event_open(inode, file, seq_ops);
1788} 1796}
1789 1797
diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
index dd18d76bf1bd..57648c5aa679 100644
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -7,6 +7,7 @@
7 7
8#include <linux/module.h> 8#include <linux/module.h>
9#include <linux/kallsyms.h> 9#include <linux/kallsyms.h>
10#include <linux/security.h>
10#include <linux/mutex.h> 11#include <linux/mutex.h>
11#include <linux/slab.h> 12#include <linux/slab.h>
12#include <linux/stacktrace.h> 13#include <linux/stacktrace.h>
@@ -1448,6 +1449,10 @@ static int synth_events_open(struct inode *inode, struct file *file)
1448{ 1449{
1449 int ret; 1450 int ret;
1450 1451
1452 ret = security_locked_down(LOCKDOWN_TRACEFS);
1453 if (ret)
1454 return ret;
1455
1451 if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) { 1456 if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
1452 ret = dyn_events_release_all(&synth_event_ops); 1457 ret = dyn_events_release_all(&synth_event_ops);
1453 if (ret < 0) 1458 if (ret < 0)
@@ -5515,6 +5520,12 @@ static int hist_show(struct seq_file *m, void *v)
5515 5520
5516static int event_hist_open(struct inode *inode, struct file *file) 5521static int event_hist_open(struct inode *inode, struct file *file)
5517{ 5522{
5523 int ret;
5524
5525 ret = security_locked_down(LOCKDOWN_TRACEFS);
5526 if (ret)
5527 return ret;
5528
5518 return single_open(file, hist_show, file); 5529 return single_open(file, hist_show, file);
5519} 5530}
5520 5531
diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c
index 2a2912cb4533..2cd53ca21b51 100644
--- a/kernel/trace/trace_events_trigger.c
+++ b/kernel/trace/trace_events_trigger.c
@@ -5,6 +5,7 @@
5 * Copyright (C) 2013 Tom Zanussi <tom.zanussi@linux.intel.com> 5 * Copyright (C) 2013 Tom Zanussi <tom.zanussi@linux.intel.com>
6 */ 6 */
7 7
8#include <linux/security.h>
8#include <linux/module.h> 9#include <linux/module.h>
9#include <linux/ctype.h> 10#include <linux/ctype.h>
10#include <linux/mutex.h> 11#include <linux/mutex.h>
@@ -173,7 +174,11 @@ static const struct seq_operations event_triggers_seq_ops = {
173 174
174static int event_trigger_regex_open(struct inode *inode, struct file *file) 175static int event_trigger_regex_open(struct inode *inode, struct file *file)
175{ 176{
176 int ret = 0; 177 int ret;
178
179 ret = security_locked_down(LOCKDOWN_TRACEFS);
180 if (ret)
181 return ret;
177 182
178 mutex_lock(&event_mutex); 183 mutex_lock(&event_mutex);
179 184
@@ -292,6 +297,7 @@ event_trigger_write(struct file *filp, const char __user *ubuf,
292static int 297static int
293event_trigger_open(struct inode *inode, struct file *filp) 298event_trigger_open(struct inode *inode, struct file *filp)
294{ 299{
300 /* Checks for tracefs lockdown */
295 return event_trigger_regex_open(inode, filp); 301 return event_trigger_regex_open(inode, filp);
296} 302}
297 303
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index 324ffbea3556..1552a95c743b 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -7,11 +7,11 @@
7 */ 7 */
8#define pr_fmt(fmt) "trace_kprobe: " fmt 8#define pr_fmt(fmt) "trace_kprobe: " fmt
9 9
10#include <linux/security.h>
10#include <linux/module.h> 11#include <linux/module.h>
11#include <linux/uaccess.h> 12#include <linux/uaccess.h>
12#include <linux/rculist.h> 13#include <linux/rculist.h>
13#include <linux/error-injection.h> 14#include <linux/error-injection.h>
14#include <linux/security.h>
15 15
16#include <asm/setup.h> /* for COMMAND_LINE_SIZE */ 16#include <asm/setup.h> /* for COMMAND_LINE_SIZE */
17 17
@@ -936,6 +936,10 @@ static int probes_open(struct inode *inode, struct file *file)
936{ 936{
937 int ret; 937 int ret;
938 938
939 ret = security_locked_down(LOCKDOWN_TRACEFS);
940 if (ret)
941 return ret;
942
939 if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) { 943 if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
940 ret = dyn_events_release_all(&trace_kprobe_ops); 944 ret = dyn_events_release_all(&trace_kprobe_ops);
941 if (ret < 0) 945 if (ret < 0)
@@ -988,6 +992,12 @@ static const struct seq_operations profile_seq_op = {
988 992
989static int profile_open(struct inode *inode, struct file *file) 993static int profile_open(struct inode *inode, struct file *file)
990{ 994{
995 int ret;
996
997 ret = security_locked_down(LOCKDOWN_TRACEFS);
998 if (ret)
999 return ret;
1000
991 return seq_open(file, &profile_seq_op); 1001 return seq_open(file, &profile_seq_op);
992} 1002}
993 1003
diff --git a/kernel/trace/trace_printk.c b/kernel/trace/trace_printk.c
index c3fd849d4a8f..d4e31e969206 100644
--- a/kernel/trace/trace_printk.c
+++ b/kernel/trace/trace_printk.c
@@ -6,6 +6,7 @@
6 * 6 *
7 */ 7 */
8#include <linux/seq_file.h> 8#include <linux/seq_file.h>
9#include <linux/security.h>
9#include <linux/uaccess.h> 10#include <linux/uaccess.h>
10#include <linux/kernel.h> 11#include <linux/kernel.h>
11#include <linux/ftrace.h> 12#include <linux/ftrace.h>
@@ -348,6 +349,12 @@ static const struct seq_operations show_format_seq_ops = {
348static int 349static int
349ftrace_formats_open(struct inode *inode, struct file *file) 350ftrace_formats_open(struct inode *inode, struct file *file)
350{ 351{
352 int ret;
353
354 ret = security_locked_down(LOCKDOWN_TRACEFS);
355 if (ret)
356 return ret;
357
351 return seq_open(file, &show_format_seq_ops); 358 return seq_open(file, &show_format_seq_ops);
352} 359}
353 360
diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c
index ec9a34a97129..4df9a209f7ca 100644
--- a/kernel/trace/trace_stack.c
+++ b/kernel/trace/trace_stack.c
@@ -5,6 +5,7 @@
5 */ 5 */
6#include <linux/sched/task_stack.h> 6#include <linux/sched/task_stack.h>
7#include <linux/stacktrace.h> 7#include <linux/stacktrace.h>
8#include <linux/security.h>
8#include <linux/kallsyms.h> 9#include <linux/kallsyms.h>
9#include <linux/seq_file.h> 10#include <linux/seq_file.h>
10#include <linux/spinlock.h> 11#include <linux/spinlock.h>
@@ -470,6 +471,12 @@ static const struct seq_operations stack_trace_seq_ops = {
470 471
471static int stack_trace_open(struct inode *inode, struct file *file) 472static int stack_trace_open(struct inode *inode, struct file *file)
472{ 473{
474 int ret;
475
476 ret = security_locked_down(LOCKDOWN_TRACEFS);
477 if (ret)
478 return ret;
479
473 return seq_open(file, &stack_trace_seq_ops); 480 return seq_open(file, &stack_trace_seq_ops);
474} 481}
475 482
@@ -487,6 +494,7 @@ stack_trace_filter_open(struct inode *inode, struct file *file)
487{ 494{
488 struct ftrace_ops *ops = inode->i_private; 495 struct ftrace_ops *ops = inode->i_private;
489 496
497 /* Checks for tracefs lockdown */
490 return ftrace_regex_open(ops, FTRACE_ITER_FILTER, 498 return ftrace_regex_open(ops, FTRACE_ITER_FILTER,
491 inode, file); 499 inode, file);
492} 500}
diff --git a/kernel/trace/trace_stat.c b/kernel/trace/trace_stat.c
index 75bf1bcb4a8a..9ab0a1a7ad5e 100644
--- a/kernel/trace/trace_stat.c
+++ b/kernel/trace/trace_stat.c
@@ -9,7 +9,7 @@
9 * 9 *
10 */ 10 */
11 11
12 12#include <linux/security.h>
13#include <linux/list.h> 13#include <linux/list.h>
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include <linux/rbtree.h> 15#include <linux/rbtree.h>
@@ -238,6 +238,10 @@ static int tracing_stat_open(struct inode *inode, struct file *file)
238 struct seq_file *m; 238 struct seq_file *m;
239 struct stat_session *session = inode->i_private; 239 struct stat_session *session = inode->i_private;
240 240
241 ret = security_locked_down(LOCKDOWN_TRACEFS);
242 if (ret)
243 return ret;
244
241 ret = stat_seq_init(session); 245 ret = stat_seq_init(session);
242 if (ret) 246 if (ret)
243 return ret; 247 return ret;
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
index dd884341f5c5..352073d36585 100644
--- a/kernel/trace/trace_uprobe.c
+++ b/kernel/trace/trace_uprobe.c
@@ -7,6 +7,7 @@
7 */ 7 */
8#define pr_fmt(fmt) "trace_uprobe: " fmt 8#define pr_fmt(fmt) "trace_uprobe: " fmt
9 9
10#include <linux/security.h>
10#include <linux/ctype.h> 11#include <linux/ctype.h>
11#include <linux/module.h> 12#include <linux/module.h>
12#include <linux/uaccess.h> 13#include <linux/uaccess.h>
@@ -769,6 +770,10 @@ static int probes_open(struct inode *inode, struct file *file)
769{ 770{
770 int ret; 771 int ret;
771 772
773 ret = security_locked_down(LOCKDOWN_TRACEFS);
774 if (ret)
775 return ret;
776
772 if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) { 777 if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
773 ret = dyn_events_release_all(&trace_uprobe_ops); 778 ret = dyn_events_release_all(&trace_uprobe_ops);
774 if (ret) 779 if (ret)
@@ -818,6 +823,12 @@ static const struct seq_operations profile_seq_op = {
818 823
819static int profile_open(struct inode *inode, struct file *file) 824static int profile_open(struct inode *inode, struct file *file)
820{ 825{
826 int ret;
827
828 ret = security_locked_down(LOCKDOWN_TRACEFS);
829 if (ret)
830 return ret;
831
821 return seq_open(file, &profile_seq_op); 832 return seq_open(file, &profile_seq_op);
822} 833}
823 834