Skip to content

Commit d4615e5

Browse files
committed
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 ccbd54f ("tracefs: Restrict tracefs when the kernel is locked down")
2 parents 2581efa + d303de1 commit d4615e5

15 files changed

+223
-132
lines changed

fs/tracefs/inode.c

Lines changed: 5 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -16,37 +16,18 @@
1616
#include <linux/namei.h>
1717
#include <linux/tracefs.h>
1818
#include <linux/fsnotify.h>
19+
#include <linux/security.h>
1920
#include <linux/seq_file.h>
2021
#include <linux/parser.h>
2122
#include <linux/magic.h>
2223
#include <linux/slab.h>
23-
#include <linux/security.h>
2424

2525
#define TRACEFS_DEFAULT_MODE 0700
2626

2727
static struct vfsmount *tracefs_mount;
2828
static int tracefs_mount_count;
2929
static bool tracefs_registered;
3030

31-
static int default_open_file(struct inode *inode, struct file *filp)
32-
{
33-
struct dentry *dentry = filp->f_path.dentry;
34-
struct file_operations *real_fops;
35-
int ret;
36-
37-
if (!dentry)
38-
return -EINVAL;
39-
40-
ret = security_locked_down(LOCKDOWN_TRACEFS);
41-
if (ret)
42-
return ret;
43-
44-
real_fops = dentry->d_fsdata;
45-
if (!real_fops->open)
46-
return 0;
47-
return real_fops->open(inode, filp);
48-
}
49-
5031
static ssize_t default_read_file(struct file *file, char __user *buf,
5132
size_t count, loff_t *ppos)
5233
{
@@ -241,12 +222,6 @@ static int tracefs_apply_options(struct super_block *sb)
241222
return 0;
242223
}
243224

244-
static void tracefs_destroy_inode(struct inode *inode)
245-
{
246-
if (S_ISREG(inode->i_mode))
247-
kfree(inode->i_fop);
248-
}
249-
250225
static int tracefs_remount(struct super_block *sb, int *flags, char *data)
251226
{
252227
int err;
@@ -283,7 +258,6 @@ static int tracefs_show_options(struct seq_file *m, struct dentry *root)
283258
static const struct super_operations tracefs_super_operations = {
284259
.statfs = simple_statfs,
285260
.remount_fs = tracefs_remount,
286-
.destroy_inode = tracefs_destroy_inode,
287261
.show_options = tracefs_show_options,
288262
};
289263

@@ -414,10 +388,12 @@ struct dentry *tracefs_create_file(const char *name, umode_t mode,
414388
struct dentry *parent, void *data,
415389
const struct file_operations *fops)
416390
{
417-
struct file_operations *proxy_fops;
418391
struct dentry *dentry;
419392
struct inode *inode;
420393

394+
if (security_locked_down(LOCKDOWN_TRACEFS))
395+
return NULL;
396+
421397
if (!(mode & S_IFMT))
422398
mode |= S_IFREG;
423399
BUG_ON(!S_ISREG(mode));
@@ -430,20 +406,8 @@ struct dentry *tracefs_create_file(const char *name, umode_t mode,
430406
if (unlikely(!inode))
431407
return failed_creating(dentry);
432408

433-
proxy_fops = kzalloc(sizeof(struct file_operations), GFP_KERNEL);
434-
if (unlikely(!proxy_fops)) {
435-
iput(inode);
436-
return failed_creating(dentry);
437-
}
438-
439-
if (!fops)
440-
fops = &tracefs_file_operations;
441-
442-
dentry->d_fsdata = (void *)fops;
443-
memcpy(proxy_fops, fops, sizeof(*proxy_fops));
444-
proxy_fops->open = default_open_file;
445409
inode->i_mode = mode;
446-
inode->i_fop = proxy_fops;
410+
inode->i_fop = fops ? fops : &tracefs_file_operations;
447411
inode->i_private = data;
448412
d_instantiate(dentry, inode);
449413
fsnotify_create(dentry->d_parent->d_inode, dentry);

kernel/trace/ftrace.c

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <linux/clocksource.h>
1919
#include <linux/sched/task.h>
2020
#include <linux/kallsyms.h>
21+
#include <linux/security.h>
2122
#include <linux/seq_file.h>
2223
#include <linux/tracefs.h>
2324
#include <linux/hardirq.h>
@@ -3486,6 +3487,11 @@ static int
34863487
ftrace_avail_open(struct inode *inode, struct file *file)
34873488
{
34883489
struct ftrace_iterator *iter;
3490+
int ret;
3491+
3492+
ret = security_locked_down(LOCKDOWN_TRACEFS);
3493+
if (ret)
3494+
return ret;
34893495

34903496
if (unlikely(ftrace_disabled))
34913497
return -ENODEV;
@@ -3505,6 +3511,15 @@ ftrace_enabled_open(struct inode *inode, struct file *file)
35053511
{
35063512
struct ftrace_iterator *iter;
35073513

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+
35083523
iter = __seq_open_private(file, &show_ftrace_seq_ops, sizeof(*iter));
35093524
if (!iter)
35103525
return -ENOMEM;
@@ -3540,21 +3555,22 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag,
35403555
struct ftrace_hash *hash;
35413556
struct list_head *mod_head;
35423557
struct trace_array *tr = ops->private;
3543-
int ret = 0;
3558+
int ret = -ENOMEM;
35443559

35453560
ftrace_ops_init(ops);
35463561

35473562
if (unlikely(ftrace_disabled))
35483563
return -ENODEV;
35493564

3565+
if (tracing_check_open_get_tr(tr))
3566+
return -ENODEV;
3567+
35503568
iter = kzalloc(sizeof(*iter), GFP_KERNEL);
35513569
if (!iter)
3552-
return -ENOMEM;
3570+
goto out;
35533571

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

35593575
iter->ops = ops;
35603576
iter->flags = flag;
@@ -3584,13 +3600,13 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag,
35843600

35853601
if (!iter->hash) {
35863602
trace_parser_put(&iter->parser);
3587-
kfree(iter);
3588-
ret = -ENOMEM;
35893603
goto out_unlock;
35903604
}
35913605
} else
35923606
iter->hash = hash;
35933607

3608+
ret = 0;
3609+
35943610
if (file->f_mode & FMODE_READ) {
35953611
iter->pg = ftrace_pages_start;
35963612

@@ -3602,14 +3618,20 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag,
36023618
/* Failed */
36033619
free_ftrace_hash(iter->hash);
36043620
trace_parser_put(&iter->parser);
3605-
kfree(iter);
36063621
}
36073622
} else
36083623
file->private_data = iter;
36093624

36103625
out_unlock:
36113626
mutex_unlock(&ops->func_hash->regex_lock);
36123627

3628+
out:
3629+
if (ret) {
3630+
kfree(iter);
3631+
if (tr)
3632+
trace_array_put(tr);
3633+
}
3634+
36133635
return ret;
36143636
}
36153637

@@ -3618,6 +3640,7 @@ ftrace_filter_open(struct inode *inode, struct file *file)
36183640
{
36193641
struct ftrace_ops *ops = inode->i_private;
36203642

3643+
/* Checks for tracefs lockdown */
36213644
return ftrace_regex_open(ops,
36223645
FTRACE_ITER_FILTER | FTRACE_ITER_DO_PROBES,
36233646
inode, file);
@@ -3628,6 +3651,7 @@ ftrace_notrace_open(struct inode *inode, struct file *file)
36283651
{
36293652
struct ftrace_ops *ops = inode->i_private;
36303653

3654+
/* Checks for tracefs lockdown */
36313655
return ftrace_regex_open(ops, FTRACE_ITER_NOTRACE,
36323656
inode, file);
36333657
}
@@ -5037,6 +5061,8 @@ int ftrace_regex_release(struct inode *inode, struct file *file)
50375061

50385062
mutex_unlock(&iter->ops->func_hash->regex_lock);
50395063
free_ftrace_hash(iter->hash);
5064+
if (iter->tr)
5065+
trace_array_put(iter->tr);
50405066
kfree(iter);
50415067

50425068
return 0;
@@ -5194,9 +5220,13 @@ static int
51945220
__ftrace_graph_open(struct inode *inode, struct file *file,
51955221
struct ftrace_graph_data *fgd)
51965222
{
5197-
int ret = 0;
5223+
int ret;
51985224
struct ftrace_hash *new_hash = NULL;
51995225

5226+
ret = security_locked_down(LOCKDOWN_TRACEFS);
5227+
if (ret)
5228+
return ret;
5229+
52005230
if (file->f_mode & FMODE_WRITE) {
52015231
const int size_bits = FTRACE_HASH_DEFAULT_BITS;
52025232

@@ -6537,8 +6567,9 @@ ftrace_pid_open(struct inode *inode, struct file *file)
65376567
struct seq_file *m;
65386568
int ret = 0;
65396569

6540-
if (trace_array_get(tr) < 0)
6541-
return -ENODEV;
6570+
ret = tracing_check_open_get_tr(tr);
6571+
if (ret)
6572+
return ret;
65426573

65436574
if ((file->f_mode & FMODE_WRITE) &&
65446575
(file->f_flags & O_TRUNC))

0 commit comments

Comments
 (0)