aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-10-13 17:47:10 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-10-13 17:47:10 -0400
commitd4615e5a46800d2193bf8ae98cb470206f5f635b (patch)
tree10aed48289c9917a1cf587df244b6645b2e3caf3 /kernel
parent2581efa9a47d3c9c349c6d6a2756a16bf69d3f4f (diff)
parentd303de1fcf344ff7c15ed64c3f48a991c9958775 (diff)
Merge tag 'trace-v5.4-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace
Pull tracing fixes from Steven Rostedt: "A few tracing fixes: - Remove lockdown from tracefs itself and moved it to the trace directory. Have the open functions there do the lockdown checks. - Fix a few races with opening an instance file and the instance being deleted (Discovered during the lockdown updates). Kept separate from the clean up code such that they can be backported to stable easier. - Clean up and consolidated the checks done when opening a trace file, as there were multiple checks that need to be done, and it did not make sense having them done in each open instance. - Fix a regression in the record mcount code. - Small hw_lat detector tracer fixes. - A trace_pipe read fix due to not initializing trace_seq" * tag 'trace-v5.4-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace: tracing: Initialize iter->seq after zeroing in tracing_read_pipe() tracing/hwlat: Don't ignore outer-loop duration when calculating max_latency tracing/hwlat: Report total time spent in all NMIs during the sample recordmcount: Fix nop_mcount() function tracing: Do not create tracefs files if tracefs lockdown is in effect tracing: Add locked_down checks to the open calls of files created for tracefs tracing: Add tracing_check_open_get_tr() tracing: Have trace events system open call tracing_open_generic_tr() tracing: Get trace_array reference for available_tracers files ftrace: Get a reference counter for the trace_array on filter files tracefs: Revert ccbd54ff54e8 ("tracefs: Restrict tracefs when the kernel is locked down")
Diffstat (limited to 'kernel')
-rw-r--r--kernel/trace/ftrace.c55
-rw-r--r--kernel/trace/trace.c139
-rw-r--r--kernel/trace/trace.h2
-rw-r--r--kernel/trace/trace_dynevent.c4
-rw-r--r--kernel/trace/trace_events.c35
-rw-r--r--kernel/trace/trace_events_hist.c13
-rw-r--r--kernel/trace/trace_events_trigger.c8
-rw-r--r--kernel/trace/trace_hwlat.c4
-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
13 files changed, 217 insertions, 87 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 62a50bf399d6..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;
@@ -3540,21 +3555,22 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag,
3540 struct ftrace_hash *hash; 3555 struct ftrace_hash *hash;
3541 struct list_head *mod_head; 3556 struct list_head *mod_head;
3542 struct trace_array *tr = ops->private; 3557 struct trace_array *tr = ops->private;
3543 int ret = 0; 3558 int ret = -ENOMEM;
3544 3559
3545 ftrace_ops_init(ops); 3560 ftrace_ops_init(ops);
3546 3561
3547 if (unlikely(ftrace_disabled)) 3562 if (unlikely(ftrace_disabled))
3548 return -ENODEV; 3563 return -ENODEV;
3549 3564
3565 if (tracing_check_open_get_tr(tr))
3566 return -ENODEV;
3567
3550 iter = kzalloc(sizeof(*iter), GFP_KERNEL); 3568 iter = kzalloc(sizeof(*iter), GFP_KERNEL);
3551 if (!iter) 3569 if (!iter)
3552 return -ENOMEM; 3570 goto out;
3553 3571
3554 if (trace_parser_get_init(&iter->parser, FTRACE_BUFF_MAX)) { 3572 if (trace_parser_get_init(&iter->parser, FTRACE_BUFF_MAX))
3555 kfree(iter); 3573 goto out;
3556 return -ENOMEM;
3557 }
3558 3574
3559 iter->ops = ops; 3575 iter->ops = ops;
3560 iter->flags = flag; 3576 iter->flags = flag;
@@ -3584,13 +3600,13 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag,
3584 3600
3585 if (!iter->hash) { 3601 if (!iter->hash) {
3586 trace_parser_put(&iter->parser); 3602 trace_parser_put(&iter->parser);
3587 kfree(iter);
3588 ret = -ENOMEM;
3589 goto out_unlock; 3603 goto out_unlock;
3590 } 3604 }
3591 } else 3605 } else
3592 iter->hash = hash; 3606 iter->hash = hash;
3593 3607
3608 ret = 0;
3609
3594 if (file->f_mode & FMODE_READ) { 3610 if (file->f_mode & FMODE_READ) {
3595 iter->pg = ftrace_pages_start; 3611 iter->pg = ftrace_pages_start;
3596 3612
@@ -3602,7 +3618,6 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag,
3602 /* Failed */ 3618 /* Failed */
3603 free_ftrace_hash(iter->hash); 3619 free_ftrace_hash(iter->hash);
3604 trace_parser_put(&iter->parser); 3620 trace_parser_put(&iter->parser);
3605 kfree(iter);
3606 } 3621 }
3607 } else 3622 } else
3608 file->private_data = iter; 3623 file->private_data = iter;
@@ -3610,6 +3625,13 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag,
3610 out_unlock: 3625 out_unlock:
3611 mutex_unlock(&ops->func_hash->regex_lock); 3626 mutex_unlock(&ops->func_hash->regex_lock);
3612 3627
3628 out:
3629 if (ret) {
3630 kfree(iter);
3631 if (tr)
3632 trace_array_put(tr);
3633 }
3634
3613 return ret; 3635 return ret;
3614} 3636}
3615 3637
@@ -3618,6 +3640,7 @@ ftrace_filter_open(struct inode *inode, struct file *file)
3618{ 3640{
3619 struct ftrace_ops *ops = inode->i_private; 3641 struct ftrace_ops *ops = inode->i_private;
3620 3642
3643 /* Checks for tracefs lockdown */
3621 return ftrace_regex_open(ops, 3644 return ftrace_regex_open(ops,
3622 FTRACE_ITER_FILTER | FTRACE_ITER_DO_PROBES, 3645 FTRACE_ITER_FILTER | FTRACE_ITER_DO_PROBES,
3623 inode, file); 3646 inode, file);
@@ -3628,6 +3651,7 @@ ftrace_notrace_open(struct inode *inode, struct file *file)
3628{ 3651{
3629 struct ftrace_ops *ops = inode->i_private; 3652 struct ftrace_ops *ops = inode->i_private;
3630 3653
3654 /* Checks for tracefs lockdown */
3631 return ftrace_regex_open(ops, FTRACE_ITER_NOTRACE, 3655 return ftrace_regex_open(ops, FTRACE_ITER_NOTRACE,
3632 inode, file); 3656 inode, file);
3633} 3657}
@@ -5037,6 +5061,8 @@ int ftrace_regex_release(struct inode *inode, struct file *file)
5037 5061
5038 mutex_unlock(&iter->ops->func_hash->regex_lock); 5062 mutex_unlock(&iter->ops->func_hash->regex_lock);
5039 free_ftrace_hash(iter->hash); 5063 free_ftrace_hash(iter->hash);
5064 if (iter->tr)
5065 trace_array_put(iter->tr);
5040 kfree(iter); 5066 kfree(iter);
5041 5067
5042 return 0; 5068 return 0;
@@ -5194,9 +5220,13 @@ static int
5194__ftrace_graph_open(struct inode *inode, struct file *file, 5220__ftrace_graph_open(struct inode *inode, struct file *file,
5195 struct ftrace_graph_data *fgd) 5221 struct ftrace_graph_data *fgd)
5196{ 5222{
5197 int ret = 0; 5223 int ret;
5198 struct ftrace_hash *new_hash = NULL; 5224 struct ftrace_hash *new_hash = NULL;
5199 5225
5226 ret = security_locked_down(LOCKDOWN_TRACEFS);
5227 if (ret)
5228 return ret;
5229
5200 if (file->f_mode & FMODE_WRITE) { 5230 if (file->f_mode & FMODE_WRITE) {
5201 const int size_bits = FTRACE_HASH_DEFAULT_BITS; 5231 const int size_bits = FTRACE_HASH_DEFAULT_BITS;
5202 5232
@@ -6537,8 +6567,9 @@ ftrace_pid_open(struct inode *inode, struct file *file)
6537 struct seq_file *m; 6567 struct seq_file *m;
6538 int ret = 0; 6568 int ret = 0;
6539 6569
6540 if (trace_array_get(tr) < 0) 6570 ret = tracing_check_open_get_tr(tr);
6541 return -ENODEV; 6571 if (ret)
6572 return ret;
6542 6573
6543 if ((file->f_mode & FMODE_WRITE) && 6574 if ((file->f_mode & FMODE_WRITE) &&
6544 (file->f_flags & O_TRUNC)) 6575 (file->f_flags & O_TRUNC))
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 252f79c435f8..6a0ee9178365 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>
@@ -304,6 +305,23 @@ void trace_array_put(struct trace_array *this_tr)
304 mutex_unlock(&trace_types_lock); 305 mutex_unlock(&trace_types_lock);
305} 306}
306 307
308int tracing_check_open_get_tr(struct trace_array *tr)
309{
310 int ret;
311
312 ret = security_locked_down(LOCKDOWN_TRACEFS);
313 if (ret)
314 return ret;
315
316 if (tracing_disabled)
317 return -ENODEV;
318
319 if (tr && trace_array_get(tr) < 0)
320 return -ENODEV;
321
322 return 0;
323}
324
307int call_filter_check_discard(struct trace_event_call *call, void *rec, 325int call_filter_check_discard(struct trace_event_call *call, void *rec,
308 struct ring_buffer *buffer, 326 struct ring_buffer *buffer,
309 struct ring_buffer_event *event) 327 struct ring_buffer_event *event)
@@ -4140,8 +4158,11 @@ release:
4140 4158
4141int tracing_open_generic(struct inode *inode, struct file *filp) 4159int tracing_open_generic(struct inode *inode, struct file *filp)
4142{ 4160{
4143 if (tracing_disabled) 4161 int ret;
4144 return -ENODEV; 4162
4163 ret = tracing_check_open_get_tr(NULL);
4164 if (ret)
4165 return ret;
4145 4166
4146 filp->private_data = inode->i_private; 4167 filp->private_data = inode->i_private;
4147 return 0; 4168 return 0;
@@ -4156,15 +4177,14 @@ bool tracing_is_disabled(void)
4156 * Open and update trace_array ref count. 4177 * Open and update trace_array ref count.
4157 * Must have the current trace_array passed to it. 4178 * Must have the current trace_array passed to it.
4158 */ 4179 */
4159static int tracing_open_generic_tr(struct inode *inode, struct file *filp) 4180int tracing_open_generic_tr(struct inode *inode, struct file *filp)
4160{ 4181{
4161 struct trace_array *tr = inode->i_private; 4182 struct trace_array *tr = inode->i_private;
4183 int ret;
4162 4184
4163 if (tracing_disabled) 4185 ret = tracing_check_open_get_tr(tr);
4164 return -ENODEV; 4186 if (ret)
4165 4187 return ret;
4166 if (trace_array_get(tr) < 0)
4167 return -ENODEV;
4168 4188
4169 filp->private_data = inode->i_private; 4189 filp->private_data = inode->i_private;
4170 4190
@@ -4233,10 +4253,11 @@ static int tracing_open(struct inode *inode, struct file *file)
4233{ 4253{
4234 struct trace_array *tr = inode->i_private; 4254 struct trace_array *tr = inode->i_private;
4235 struct trace_iterator *iter; 4255 struct trace_iterator *iter;
4236 int ret = 0; 4256 int ret;
4237 4257
4238 if (trace_array_get(tr) < 0) 4258 ret = tracing_check_open_get_tr(tr);
4239 return -ENODEV; 4259 if (ret)
4260 return ret;
4240 4261
4241 /* If this file was open for write, then erase contents */ 4262 /* If this file was open for write, then erase contents */
4242 if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) { 4263 if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
@@ -4352,12 +4373,15 @@ static int show_traces_open(struct inode *inode, struct file *file)
4352 struct seq_file *m; 4373 struct seq_file *m;
4353 int ret; 4374 int ret;
4354 4375
4355 if (tracing_disabled) 4376 ret = tracing_check_open_get_tr(tr);
4356 return -ENODEV; 4377 if (ret)
4378 return ret;
4357 4379
4358 ret = seq_open(file, &show_traces_seq_ops); 4380 ret = seq_open(file, &show_traces_seq_ops);
4359 if (ret) 4381 if (ret) {
4382 trace_array_put(tr);
4360 return ret; 4383 return ret;
4384 }
4361 4385
4362 m = file->private_data; 4386 m = file->private_data;
4363 m->private = tr; 4387 m->private = tr;
@@ -4365,6 +4389,14 @@ static int show_traces_open(struct inode *inode, struct file *file)
4365 return 0; 4389 return 0;
4366} 4390}
4367 4391
4392static int show_traces_release(struct inode *inode, struct file *file)
4393{
4394 struct trace_array *tr = inode->i_private;
4395
4396 trace_array_put(tr);
4397 return seq_release(inode, file);
4398}
4399
4368static ssize_t 4400static ssize_t
4369tracing_write_stub(struct file *filp, const char __user *ubuf, 4401tracing_write_stub(struct file *filp, const char __user *ubuf,
4370 size_t count, loff_t *ppos) 4402 size_t count, loff_t *ppos)
@@ -4395,8 +4427,8 @@ static const struct file_operations tracing_fops = {
4395static const struct file_operations show_traces_fops = { 4427static const struct file_operations show_traces_fops = {
4396 .open = show_traces_open, 4428 .open = show_traces_open,
4397 .read = seq_read, 4429 .read = seq_read,
4398 .release = seq_release,
4399 .llseek = seq_lseek, 4430 .llseek = seq_lseek,
4431 .release = show_traces_release,
4400}; 4432};
4401 4433
4402static ssize_t 4434static ssize_t
@@ -4697,11 +4729,9 @@ static int tracing_trace_options_open(struct inode *inode, struct file *file)
4697 struct trace_array *tr = inode->i_private; 4729 struct trace_array *tr = inode->i_private;
4698 int ret; 4730 int ret;
4699 4731
4700 if (tracing_disabled) 4732 ret = tracing_check_open_get_tr(tr);
4701 return -ENODEV; 4733 if (ret)
4702 4734 return ret;
4703 if (trace_array_get(tr) < 0)
4704 return -ENODEV;
4705 4735
4706 ret = single_open(file, tracing_trace_options_show, inode->i_private); 4736 ret = single_open(file, tracing_trace_options_show, inode->i_private);
4707 if (ret < 0) 4737 if (ret < 0)
@@ -5038,8 +5068,11 @@ static const struct seq_operations tracing_saved_tgids_seq_ops = {
5038 5068
5039static int tracing_saved_tgids_open(struct inode *inode, struct file *filp) 5069static int tracing_saved_tgids_open(struct inode *inode, struct file *filp)
5040{ 5070{
5041 if (tracing_disabled) 5071 int ret;
5042 return -ENODEV; 5072
5073 ret = tracing_check_open_get_tr(NULL);
5074 if (ret)
5075 return ret;
5043 5076
5044 return seq_open(filp, &tracing_saved_tgids_seq_ops); 5077 return seq_open(filp, &tracing_saved_tgids_seq_ops);
5045} 5078}
@@ -5115,8 +5148,11 @@ static const struct seq_operations tracing_saved_cmdlines_seq_ops = {
5115 5148
5116static int tracing_saved_cmdlines_open(struct inode *inode, struct file *filp) 5149static int tracing_saved_cmdlines_open(struct inode *inode, struct file *filp)
5117{ 5150{
5118 if (tracing_disabled) 5151 int ret;
5119 return -ENODEV; 5152
5153 ret = tracing_check_open_get_tr(NULL);
5154 if (ret)
5155 return ret;
5120 5156
5121 return seq_open(filp, &tracing_saved_cmdlines_seq_ops); 5157 return seq_open(filp, &tracing_saved_cmdlines_seq_ops);
5122} 5158}
@@ -5280,8 +5316,11 @@ static const struct seq_operations tracing_eval_map_seq_ops = {
5280 5316
5281static int tracing_eval_map_open(struct inode *inode, struct file *filp) 5317static int tracing_eval_map_open(struct inode *inode, struct file *filp)
5282{ 5318{
5283 if (tracing_disabled) 5319 int ret;
5284 return -ENODEV; 5320
5321 ret = tracing_check_open_get_tr(NULL);
5322 if (ret)
5323 return ret;
5285 5324
5286 return seq_open(filp, &tracing_eval_map_seq_ops); 5325 return seq_open(filp, &tracing_eval_map_seq_ops);
5287} 5326}
@@ -5804,13 +5843,11 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp)
5804{ 5843{
5805 struct trace_array *tr = inode->i_private; 5844 struct trace_array *tr = inode->i_private;
5806 struct trace_iterator *iter; 5845 struct trace_iterator *iter;
5807 int ret = 0; 5846 int ret;
5808
5809 if (tracing_disabled)
5810 return -ENODEV;
5811 5847
5812 if (trace_array_get(tr) < 0) 5848 ret = tracing_check_open_get_tr(tr);
5813 return -ENODEV; 5849 if (ret)
5850 return ret;
5814 5851
5815 mutex_lock(&trace_types_lock); 5852 mutex_lock(&trace_types_lock);
5816 5853
@@ -5999,6 +6036,7 @@ waitagain:
5999 sizeof(struct trace_iterator) - 6036 sizeof(struct trace_iterator) -
6000 offsetof(struct trace_iterator, seq)); 6037 offsetof(struct trace_iterator, seq));
6001 cpumask_clear(iter->started); 6038 cpumask_clear(iter->started);
6039 trace_seq_init(&iter->seq);
6002 iter->pos = -1; 6040 iter->pos = -1;
6003 6041
6004 trace_event_read_lock(); 6042 trace_event_read_lock();
@@ -6547,11 +6585,9 @@ static int tracing_clock_open(struct inode *inode, struct file *file)
6547 struct trace_array *tr = inode->i_private; 6585 struct trace_array *tr = inode->i_private;
6548 int ret; 6586 int ret;
6549 6587
6550 if (tracing_disabled) 6588 ret = tracing_check_open_get_tr(tr);
6551 return -ENODEV; 6589 if (ret)
6552 6590 return ret;
6553 if (trace_array_get(tr))
6554 return -ENODEV;
6555 6591
6556 ret = single_open(file, tracing_clock_show, inode->i_private); 6592 ret = single_open(file, tracing_clock_show, inode->i_private);
6557 if (ret < 0) 6593 if (ret < 0)
@@ -6581,11 +6617,9 @@ static int tracing_time_stamp_mode_open(struct inode *inode, struct file *file)
6581 struct trace_array *tr = inode->i_private; 6617 struct trace_array *tr = inode->i_private;
6582 int ret; 6618 int ret;
6583 6619
6584 if (tracing_disabled) 6620 ret = tracing_check_open_get_tr(tr);
6585 return -ENODEV; 6621 if (ret)
6586 6622 return ret;
6587 if (trace_array_get(tr))
6588 return -ENODEV;
6589 6623
6590 ret = single_open(file, tracing_time_stamp_mode_show, inode->i_private); 6624 ret = single_open(file, tracing_time_stamp_mode_show, inode->i_private);
6591 if (ret < 0) 6625 if (ret < 0)
@@ -6638,10 +6672,11 @@ static int tracing_snapshot_open(struct inode *inode, struct file *file)
6638 struct trace_array *tr = inode->i_private; 6672 struct trace_array *tr = inode->i_private;
6639 struct trace_iterator *iter; 6673 struct trace_iterator *iter;
6640 struct seq_file *m; 6674 struct seq_file *m;
6641 int ret = 0; 6675 int ret;
6642 6676
6643 if (trace_array_get(tr) < 0) 6677 ret = tracing_check_open_get_tr(tr);
6644 return -ENODEV; 6678 if (ret)
6679 return ret;
6645 6680
6646 if (file->f_mode & FMODE_READ) { 6681 if (file->f_mode & FMODE_READ) {
6647 iter = __tracing_open(inode, file, true); 6682 iter = __tracing_open(inode, file, true);
@@ -6786,6 +6821,7 @@ static int snapshot_raw_open(struct inode *inode, struct file *filp)
6786 struct ftrace_buffer_info *info; 6821 struct ftrace_buffer_info *info;
6787 int ret; 6822 int ret;
6788 6823
6824 /* The following checks for tracefs lockdown */
6789 ret = tracing_buffers_open(inode, filp); 6825 ret = tracing_buffers_open(inode, filp);
6790 if (ret < 0) 6826 if (ret < 0)
6791 return ret; 6827 return ret;
@@ -7105,8 +7141,9 @@ static int tracing_err_log_open(struct inode *inode, struct file *file)
7105 struct trace_array *tr = inode->i_private; 7141 struct trace_array *tr = inode->i_private;
7106 int ret = 0; 7142 int ret = 0;
7107 7143
7108 if (trace_array_get(tr) < 0) 7144 ret = tracing_check_open_get_tr(tr);
7109 return -ENODEV; 7145 if (ret)
7146 return ret;
7110 7147
7111 /* If this file was opened for write, then erase contents */ 7148 /* If this file was opened for write, then erase contents */
7112 if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) 7149 if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC))
@@ -7157,11 +7194,9 @@ static int tracing_buffers_open(struct inode *inode, struct file *filp)
7157 struct ftrace_buffer_info *info; 7194 struct ftrace_buffer_info *info;
7158 int ret; 7195 int ret;
7159 7196
7160 if (tracing_disabled) 7197 ret = tracing_check_open_get_tr(tr);
7161 return -ENODEV; 7198 if (ret)
7162 7199 return ret;
7163 if (trace_array_get(tr) < 0)
7164 return -ENODEV;
7165 7200
7166 info = kzalloc(sizeof(*info), GFP_KERNEL); 7201 info = kzalloc(sizeof(*info), GFP_KERNEL);
7167 if (!info) { 7202 if (!info) {
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index f801d154ff6a..d685c61085c0 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -338,6 +338,7 @@ extern struct mutex trace_types_lock;
338 338
339extern int trace_array_get(struct trace_array *tr); 339extern int trace_array_get(struct trace_array *tr);
340extern void trace_array_put(struct trace_array *tr); 340extern void trace_array_put(struct trace_array *tr);
341extern int tracing_check_open_get_tr(struct trace_array *tr);
341 342
342extern int tracing_set_time_stamp_abs(struct trace_array *tr, bool abs); 343extern int tracing_set_time_stamp_abs(struct trace_array *tr, bool abs);
343extern int tracing_set_clock(struct trace_array *tr, const char *clockstr); 344extern int tracing_set_clock(struct trace_array *tr, const char *clockstr);
@@ -681,6 +682,7 @@ void tracing_reset_online_cpus(struct trace_buffer *buf);
681void tracing_reset_current(int cpu); 682void tracing_reset_current(int cpu);
682void tracing_reset_all_online_cpus(void); 683void tracing_reset_all_online_cpus(void);
683int tracing_open_generic(struct inode *inode, struct file *filp); 684int tracing_open_generic(struct inode *inode, struct file *filp);
685int tracing_open_generic_tr(struct inode *inode, struct file *filp);
684bool tracing_is_disabled(void); 686bool tracing_is_disabled(void);
685bool tracer_tracing_is_on(struct trace_array *tr); 687bool tracer_tracing_is_on(struct trace_array *tr);
686void tracer_tracing_on(struct trace_array *tr); 688void tracer_tracing_on(struct trace_array *tr);
diff --git a/kernel/trace/trace_dynevent.c b/kernel/trace/trace_dynevent.c
index a41fed46c285..89779eb84a07 100644
--- a/kernel/trace/trace_dynevent.c
+++ b/kernel/trace/trace_dynevent.c
@@ -174,6 +174,10 @@ static int dyn_event_open(struct inode *inode, struct file *file)
174{ 174{
175 int ret; 175 int ret;
176 176
177 ret = tracing_check_open_get_tr(NULL);
178 if (ret)
179 return ret;
180
177 if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) { 181 if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
178 ret = dyn_events_release_all(NULL); 182 ret = dyn_events_release_all(NULL);
179 if (ret < 0) 183 if (ret < 0)
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index b89cdfe20bc1..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;
@@ -1440,28 +1443,17 @@ static int system_tr_open(struct inode *inode, struct file *filp)
1440 struct trace_array *tr = inode->i_private; 1443 struct trace_array *tr = inode->i_private;
1441 int ret; 1444 int ret;
1442 1445
1443 if (tracing_is_disabled())
1444 return -ENODEV;
1445
1446 if (trace_array_get(tr) < 0)
1447 return -ENODEV;
1448
1449 /* Make a temporary dir that has no system but points to tr */ 1446 /* Make a temporary dir that has no system but points to tr */
1450 dir = kzalloc(sizeof(*dir), GFP_KERNEL); 1447 dir = kzalloc(sizeof(*dir), GFP_KERNEL);
1451 if (!dir) { 1448 if (!dir)
1452 trace_array_put(tr);
1453 return -ENOMEM; 1449 return -ENOMEM;
1454 }
1455 1450
1456 dir->tr = tr; 1451 ret = tracing_open_generic_tr(inode, filp);
1457
1458 ret = tracing_open_generic(inode, filp);
1459 if (ret < 0) { 1452 if (ret < 0) {
1460 trace_array_put(tr);
1461 kfree(dir); 1453 kfree(dir);
1462 return ret; 1454 return ret;
1463 } 1455 }
1464 1456 dir->tr = tr;
1465 filp->private_data = dir; 1457 filp->private_data = dir;
1466 1458
1467 return 0; 1459 return 0;
@@ -1771,6 +1763,10 @@ ftrace_event_open(struct inode *inode, struct file *file,
1771 struct seq_file *m; 1763 struct seq_file *m;
1772 int ret; 1764 int ret;
1773 1765
1766 ret = security_locked_down(LOCKDOWN_TRACEFS);
1767 if (ret)
1768 return ret;
1769
1774 ret = seq_open(file, seq_ops); 1770 ret = seq_open(file, seq_ops);
1775 if (ret < 0) 1771 if (ret < 0)
1776 return ret; 1772 return ret;
@@ -1795,6 +1791,7 @@ ftrace_event_avail_open(struct inode *inode, struct file *file)
1795{ 1791{
1796 const struct seq_operations *seq_ops = &show_event_seq_ops; 1792 const struct seq_operations *seq_ops = &show_event_seq_ops;
1797 1793
1794 /* Checks for tracefs lockdown */
1798 return ftrace_event_open(inode, file, seq_ops); 1795 return ftrace_event_open(inode, file, seq_ops);
1799} 1796}
1800 1797
@@ -1805,8 +1802,9 @@ ftrace_event_set_open(struct inode *inode, struct file *file)
1805 struct trace_array *tr = inode->i_private; 1802 struct trace_array *tr = inode->i_private;
1806 int ret; 1803 int ret;
1807 1804
1808 if (trace_array_get(tr) < 0) 1805 ret = tracing_check_open_get_tr(tr);
1809 return -ENODEV; 1806 if (ret)
1807 return ret;
1810 1808
1811 if ((file->f_mode & FMODE_WRITE) && 1809 if ((file->f_mode & FMODE_WRITE) &&
1812 (file->f_flags & O_TRUNC)) 1810 (file->f_flags & O_TRUNC))
@@ -1825,8 +1823,9 @@ ftrace_event_set_pid_open(struct inode *inode, struct file *file)
1825 struct trace_array *tr = inode->i_private; 1823 struct trace_array *tr = inode->i_private;
1826 int ret; 1824 int ret;
1827 1825
1828 if (trace_array_get(tr) < 0) 1826 ret = tracing_check_open_get_tr(tr);
1829 return -ENODEV; 1827 if (ret)
1828 return ret;
1830 1829
1831 if ((file->f_mode & FMODE_WRITE) && 1830 if ((file->f_mode & FMODE_WRITE) &&
1832 (file->f_flags & O_TRUNC)) 1831 (file->f_flags & O_TRUNC))
diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
index 9468bd8d44a2..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)
@@ -1680,7 +1685,7 @@ static int save_hist_vars(struct hist_trigger_data *hist_data)
1680 if (var_data) 1685 if (var_data)
1681 return 0; 1686 return 0;
1682 1687
1683 if (trace_array_get(tr) < 0) 1688 if (tracing_check_open_get_tr(tr))
1684 return -ENODEV; 1689 return -ENODEV;
1685 1690
1686 var_data = kzalloc(sizeof(*var_data), GFP_KERNEL); 1691 var_data = kzalloc(sizeof(*var_data), GFP_KERNEL);
@@ -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_hwlat.c b/kernel/trace/trace_hwlat.c
index fa95139445b2..862f4b0139fc 100644
--- a/kernel/trace/trace_hwlat.c
+++ b/kernel/trace/trace_hwlat.c
@@ -150,7 +150,7 @@ void trace_hwlat_callback(bool enter)
150 if (enter) 150 if (enter)
151 nmi_ts_start = time_get(); 151 nmi_ts_start = time_get();
152 else 152 else
153 nmi_total_ts = time_get() - nmi_ts_start; 153 nmi_total_ts += time_get() - nmi_ts_start;
154 } 154 }
155 155
156 if (enter) 156 if (enter)
@@ -256,6 +256,8 @@ static int get_sample(void)
256 /* Keep a running maximum ever recorded hardware latency */ 256 /* Keep a running maximum ever recorded hardware latency */
257 if (sample > tr->max_latency) 257 if (sample > tr->max_latency)
258 tr->max_latency = sample; 258 tr->max_latency = sample;
259 if (outer_sample > tr->max_latency)
260 tr->max_latency = outer_sample;
259 } 261 }
260 262
261out: 263out:
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