Skip to content

Commit 9ef1669

Browse files
committed
ftrace: Get a reference counter for the trace_array on filter files
The ftrace set_ftrace_filter and set_ftrace_notrace files are specific for an instance now. They need to take a reference to the instance otherwise there could be a race between accessing the files and deleting the instance. It wasn't until the :mod: caching where these file operations started referencing the trace_array directly. Cc: [email protected] Fixes: 673feb9 ("ftrace: Add :mod: caching infrastructure to trace_array") Signed-off-by: Steven Rostedt (VMware) <[email protected]>
1 parent 3ed270b commit 9ef1669

File tree

1 file changed

+18
-9
lines changed

1 file changed

+18
-9
lines changed

kernel/trace/ftrace.c

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3540,21 +3540,22 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag,
35403540
struct ftrace_hash *hash;
35413541
struct list_head *mod_head;
35423542
struct trace_array *tr = ops->private;
3543-
int ret = 0;
3543+
int ret = -ENOMEM;
35443544

35453545
ftrace_ops_init(ops);
35463546

35473547
if (unlikely(ftrace_disabled))
35483548
return -ENODEV;
35493549

3550+
if (tr && trace_array_get(tr) < 0)
3551+
return -ENODEV;
3552+
35503553
iter = kzalloc(sizeof(*iter), GFP_KERNEL);
35513554
if (!iter)
3552-
return -ENOMEM;
3555+
goto out;
35533556

3554-
if (trace_parser_get_init(&iter->parser, FTRACE_BUFF_MAX)) {
3555-
kfree(iter);
3556-
return -ENOMEM;
3557-
}
3557+
if (trace_parser_get_init(&iter->parser, FTRACE_BUFF_MAX))
3558+
goto out;
35583559

35593560
iter->ops = ops;
35603561
iter->flags = flag;
@@ -3584,13 +3585,13 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag,
35843585

35853586
if (!iter->hash) {
35863587
trace_parser_put(&iter->parser);
3587-
kfree(iter);
3588-
ret = -ENOMEM;
35893588
goto out_unlock;
35903589
}
35913590
} else
35923591
iter->hash = hash;
35933592

3593+
ret = 0;
3594+
35943595
if (file->f_mode & FMODE_READ) {
35953596
iter->pg = ftrace_pages_start;
35963597

@@ -3602,14 +3603,20 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag,
36023603
/* Failed */
36033604
free_ftrace_hash(iter->hash);
36043605
trace_parser_put(&iter->parser);
3605-
kfree(iter);
36063606
}
36073607
} else
36083608
file->private_data = iter;
36093609

36103610
out_unlock:
36113611
mutex_unlock(&ops->func_hash->regex_lock);
36123612

3613+
out:
3614+
if (ret) {
3615+
kfree(iter);
3616+
if (tr)
3617+
trace_array_put(tr);
3618+
}
3619+
36133620
return ret;
36143621
}
36153622

@@ -5037,6 +5044,8 @@ int ftrace_regex_release(struct inode *inode, struct file *file)
50375044

50385045
mutex_unlock(&iter->ops->func_hash->regex_lock);
50395046
free_ftrace_hash(iter->hash);
5047+
if (iter->tr)
5048+
trace_array_put(iter->tr);
50405049
kfree(iter);
50415050

50425051
return 0;

0 commit comments

Comments
 (0)