Skip to content

Commit 8530dec

Browse files
committed
tracing: Add tracing_check_open_get_tr()
Currently, most files in the tracefs directory test if tracing_disabled is set. If so, it should return -ENODEV. The tracing_disabled is called when tracing is found to be broken. Originally it was done in case the ring buffer was found to be corrupted, and we wanted to prevent reading it from crashing the kernel. But it's also called if a tracing selftest fails on boot. It's a one way switch. That is, once it is triggered, tracing is disabled until reboot. As most tracefs files can also be used by instances in the tracefs directory, they need to be carefully done. Each instance has a trace_array associated to it, and when the instance is removed, the trace_array is freed. But if an instance is opened with a reference to the trace_array, then it requires looking up the trace_array to get its ref counter (as there could be a race with it being deleted and the open itself). Once it is found, a reference is added to prevent the instance from being removed (and the trace_array associated with it freed). Combine the two checks (tracing_disabled and trace_array_get()) into a single helper function. This will also make it easier to add lockdown to tracefs later. Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Steven Rostedt (VMware) <[email protected]>
1 parent aa07d71 commit 8530dec

File tree

6 files changed

+81
-60
lines changed

6 files changed

+81
-60
lines changed

kernel/trace/ftrace.c

+4-3
Original file line numberDiff line numberDiff line change
@@ -3547,7 +3547,7 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag,
35473547
if (unlikely(ftrace_disabled))
35483548
return -ENODEV;
35493549

3550-
if (tr && trace_array_get(tr) < 0)
3550+
if (tracing_check_open_get_tr(tr))
35513551
return -ENODEV;
35523552

35533553
iter = kzalloc(sizeof(*iter), GFP_KERNEL);
@@ -6546,8 +6546,9 @@ ftrace_pid_open(struct inode *inode, struct file *file)
65466546
struct seq_file *m;
65476547
int ret = 0;
65486548

6549-
if (trace_array_get(tr) < 0)
6550-
return -ENODEV;
6549+
ret = tracing_check_open_get_tr(tr);
6550+
if (ret)
6551+
return ret;
65516552

65526553
if ((file->f_mode & FMODE_WRITE) &&
65536554
(file->f_flags & O_TRUNC))

kernel/trace/trace.c

+65-52
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,17 @@ void trace_array_put(struct trace_array *this_tr)
304304
mutex_unlock(&trace_types_lock);
305305
}
306306

307+
int tracing_check_open_get_tr(struct trace_array *tr)
308+
{
309+
if (tracing_disabled)
310+
return -ENODEV;
311+
312+
if (tr && trace_array_get(tr) < 0)
313+
return -ENODEV;
314+
315+
return 0;
316+
}
317+
307318
int call_filter_check_discard(struct trace_event_call *call, void *rec,
308319
struct ring_buffer *buffer,
309320
struct ring_buffer_event *event)
@@ -4140,8 +4151,11 @@ __tracing_open(struct inode *inode, struct file *file, bool snapshot)
41404151

41414152
int tracing_open_generic(struct inode *inode, struct file *filp)
41424153
{
4143-
if (tracing_disabled)
4144-
return -ENODEV;
4154+
int ret;
4155+
4156+
ret = tracing_check_open_get_tr(NULL);
4157+
if (ret)
4158+
return ret;
41454159

41464160
filp->private_data = inode->i_private;
41474161
return 0;
@@ -4159,12 +4173,11 @@ bool tracing_is_disabled(void)
41594173
int tracing_open_generic_tr(struct inode *inode, struct file *filp)
41604174
{
41614175
struct trace_array *tr = inode->i_private;
4176+
int ret;
41624177

4163-
if (tracing_disabled)
4164-
return -ENODEV;
4165-
4166-
if (trace_array_get(tr) < 0)
4167-
return -ENODEV;
4178+
ret = tracing_check_open_get_tr(tr);
4179+
if (ret)
4180+
return ret;
41684181

41694182
filp->private_data = inode->i_private;
41704183

@@ -4233,10 +4246,11 @@ static int tracing_open(struct inode *inode, struct file *file)
42334246
{
42344247
struct trace_array *tr = inode->i_private;
42354248
struct trace_iterator *iter;
4236-
int ret = 0;
4249+
int ret;
42374250

4238-
if (trace_array_get(tr) < 0)
4239-
return -ENODEV;
4251+
ret = tracing_check_open_get_tr(tr);
4252+
if (ret)
4253+
return ret;
42404254

42414255
/* If this file was open for write, then erase contents */
42424256
if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
@@ -4352,11 +4366,9 @@ static int show_traces_open(struct inode *inode, struct file *file)
43524366
struct seq_file *m;
43534367
int ret;
43544368

4355-
if (tracing_disabled)
4356-
return -ENODEV;
4357-
4358-
if (trace_array_get(tr) < 0)
4359-
return -ENODEV;
4369+
ret = tracing_check_open_get_tr(tr);
4370+
if (ret)
4371+
return ret;
43604372

43614373
ret = seq_open(file, &show_traces_seq_ops);
43624374
if (ret) {
@@ -4710,11 +4722,9 @@ static int tracing_trace_options_open(struct inode *inode, struct file *file)
47104722
struct trace_array *tr = inode->i_private;
47114723
int ret;
47124724

4713-
if (tracing_disabled)
4714-
return -ENODEV;
4715-
4716-
if (trace_array_get(tr) < 0)
4717-
return -ENODEV;
4725+
ret = tracing_check_open_get_tr(tr);
4726+
if (ret)
4727+
return ret;
47184728

47194729
ret = single_open(file, tracing_trace_options_show, inode->i_private);
47204730
if (ret < 0)
@@ -5051,8 +5061,11 @@ static const struct seq_operations tracing_saved_tgids_seq_ops = {
50515061

50525062
static int tracing_saved_tgids_open(struct inode *inode, struct file *filp)
50535063
{
5054-
if (tracing_disabled)
5055-
return -ENODEV;
5064+
int ret;
5065+
5066+
ret = tracing_check_open_get_tr(NULL);
5067+
if (ret)
5068+
return ret;
50565069

50575070
return seq_open(filp, &tracing_saved_tgids_seq_ops);
50585071
}
@@ -5128,8 +5141,11 @@ static const struct seq_operations tracing_saved_cmdlines_seq_ops = {
51285141

51295142
static int tracing_saved_cmdlines_open(struct inode *inode, struct file *filp)
51305143
{
5131-
if (tracing_disabled)
5132-
return -ENODEV;
5144+
int ret;
5145+
5146+
ret = tracing_check_open_get_tr(NULL);
5147+
if (ret)
5148+
return ret;
51335149

51345150
return seq_open(filp, &tracing_saved_cmdlines_seq_ops);
51355151
}
@@ -5293,8 +5309,11 @@ static const struct seq_operations tracing_eval_map_seq_ops = {
52935309

52945310
static int tracing_eval_map_open(struct inode *inode, struct file *filp)
52955311
{
5296-
if (tracing_disabled)
5297-
return -ENODEV;
5312+
int ret;
5313+
5314+
ret = tracing_check_open_get_tr(NULL);
5315+
if (ret)
5316+
return ret;
52985317

52995318
return seq_open(filp, &tracing_eval_map_seq_ops);
53005319
}
@@ -5817,13 +5836,11 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp)
58175836
{
58185837
struct trace_array *tr = inode->i_private;
58195838
struct trace_iterator *iter;
5820-
int ret = 0;
5821-
5822-
if (tracing_disabled)
5823-
return -ENODEV;
5839+
int ret;
58245840

5825-
if (trace_array_get(tr) < 0)
5826-
return -ENODEV;
5841+
ret = tracing_check_open_get_tr(tr);
5842+
if (ret)
5843+
return ret;
58275844

58285845
mutex_lock(&trace_types_lock);
58295846

@@ -6560,11 +6577,9 @@ static int tracing_clock_open(struct inode *inode, struct file *file)
65606577
struct trace_array *tr = inode->i_private;
65616578
int ret;
65626579

6563-
if (tracing_disabled)
6564-
return -ENODEV;
6565-
6566-
if (trace_array_get(tr))
6567-
return -ENODEV;
6580+
ret = tracing_check_open_get_tr(tr);
6581+
if (ret)
6582+
return ret;
65686583

65696584
ret = single_open(file, tracing_clock_show, inode->i_private);
65706585
if (ret < 0)
@@ -6594,11 +6609,9 @@ static int tracing_time_stamp_mode_open(struct inode *inode, struct file *file)
65946609
struct trace_array *tr = inode->i_private;
65956610
int ret;
65966611

6597-
if (tracing_disabled)
6598-
return -ENODEV;
6599-
6600-
if (trace_array_get(tr))
6601-
return -ENODEV;
6612+
ret = tracing_check_open_get_tr(tr);
6613+
if (ret)
6614+
return ret;
66026615

66036616
ret = single_open(file, tracing_time_stamp_mode_show, inode->i_private);
66046617
if (ret < 0)
@@ -6651,10 +6664,11 @@ static int tracing_snapshot_open(struct inode *inode, struct file *file)
66516664
struct trace_array *tr = inode->i_private;
66526665
struct trace_iterator *iter;
66536666
struct seq_file *m;
6654-
int ret = 0;
6667+
int ret;
66556668

6656-
if (trace_array_get(tr) < 0)
6657-
return -ENODEV;
6669+
ret = tracing_check_open_get_tr(tr);
6670+
if (ret)
6671+
return ret;
66586672

66596673
if (file->f_mode & FMODE_READ) {
66606674
iter = __tracing_open(inode, file, true);
@@ -7118,8 +7132,9 @@ static int tracing_err_log_open(struct inode *inode, struct file *file)
71187132
struct trace_array *tr = inode->i_private;
71197133
int ret = 0;
71207134

7121-
if (trace_array_get(tr) < 0)
7122-
return -ENODEV;
7135+
ret = tracing_check_open_get_tr(tr);
7136+
if (ret)
7137+
return ret;
71237138

71247139
/* If this file was opened for write, then erase contents */
71257140
if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC))
@@ -7170,11 +7185,9 @@ static int tracing_buffers_open(struct inode *inode, struct file *filp)
71707185
struct ftrace_buffer_info *info;
71717186
int ret;
71727187

7173-
if (tracing_disabled)
7174-
return -ENODEV;
7175-
7176-
if (trace_array_get(tr) < 0)
7177-
return -ENODEV;
7188+
ret = tracing_check_open_get_tr(tr);
7189+
if (ret)
7190+
return ret;
71787191

71797192
info = kzalloc(sizeof(*info), GFP_KERNEL);
71807193
if (!info) {

kernel/trace/trace.h

+1
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,7 @@ extern struct mutex trace_types_lock;
338338

339339
extern int trace_array_get(struct trace_array *tr);
340340
extern void trace_array_put(struct trace_array *tr);
341+
extern int tracing_check_open_get_tr(struct trace_array *tr);
341342

342343
extern int tracing_set_time_stamp_abs(struct trace_array *tr, bool abs);
343344
extern int tracing_set_clock(struct trace_array *tr, const char *clockstr);

kernel/trace/trace_dynevent.c

+4
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,10 @@ static int dyn_event_open(struct inode *inode, struct file *file)
174174
{
175175
int ret;
176176

177+
ret = tracing_check_open_get_tr(NULL);
178+
if (ret)
179+
return ret;
180+
177181
if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
178182
ret = dyn_events_release_all(NULL);
179183
if (ret < 0)

kernel/trace/trace_events.c

+6-4
Original file line numberDiff line numberDiff line change
@@ -1794,8 +1794,9 @@ ftrace_event_set_open(struct inode *inode, struct file *file)
17941794
struct trace_array *tr = inode->i_private;
17951795
int ret;
17961796

1797-
if (trace_array_get(tr) < 0)
1798-
return -ENODEV;
1797+
ret = tracing_check_open_get_tr(tr);
1798+
if (ret)
1799+
return ret;
17991800

18001801
if ((file->f_mode & FMODE_WRITE) &&
18011802
(file->f_flags & O_TRUNC))
@@ -1814,8 +1815,9 @@ ftrace_event_set_pid_open(struct inode *inode, struct file *file)
18141815
struct trace_array *tr = inode->i_private;
18151816
int ret;
18161817

1817-
if (trace_array_get(tr) < 0)
1818-
return -ENODEV;
1818+
ret = tracing_check_open_get_tr(tr);
1819+
if (ret)
1820+
return ret;
18191821

18201822
if ((file->f_mode & FMODE_WRITE) &&
18211823
(file->f_flags & O_TRUNC))

kernel/trace/trace_events_hist.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1680,7 +1680,7 @@ static int save_hist_vars(struct hist_trigger_data *hist_data)
16801680
if (var_data)
16811681
return 0;
16821682

1683-
if (trace_array_get(tr) < 0)
1683+
if (tracing_check_open_get_tr(tr))
16841684
return -ENODEV;
16851685

16861686
var_data = kzalloc(sizeof(*var_data), GFP_KERNEL);

0 commit comments

Comments
 (0)