Skip to content

Commit

Permalink
Merge tag 'trace-v5.4-rc2' of git://git.kernel.org/pub/scm/linux/kern…
Browse files Browse the repository at this point in the history
…el/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")
  • Loading branch information
torvalds committed Oct 13, 2019
2 parents 2581efa + d303de1 commit d4615e5
Show file tree
Hide file tree
Showing 15 changed files with 223 additions and 132 deletions.
46 changes: 5 additions & 41 deletions fs/tracefs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,37 +16,18 @@
#include <linux/namei.h>
#include <linux/tracefs.h>
#include <linux/fsnotify.h>
#include <linux/security.h>
#include <linux/seq_file.h>
#include <linux/parser.h>
#include <linux/magic.h>
#include <linux/slab.h>
#include <linux/security.h>

#define TRACEFS_DEFAULT_MODE 0700

static struct vfsmount *tracefs_mount;
static int tracefs_mount_count;
static bool tracefs_registered;

static int default_open_file(struct inode *inode, struct file *filp)
{
struct dentry *dentry = filp->f_path.dentry;
struct file_operations *real_fops;
int ret;

if (!dentry)
return -EINVAL;

ret = security_locked_down(LOCKDOWN_TRACEFS);
if (ret)
return ret;

real_fops = dentry->d_fsdata;
if (!real_fops->open)
return 0;
return real_fops->open(inode, filp);
}

static ssize_t default_read_file(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
Expand Down Expand Up @@ -241,12 +222,6 @@ static int tracefs_apply_options(struct super_block *sb)
return 0;
}

static void tracefs_destroy_inode(struct inode *inode)
{
if (S_ISREG(inode->i_mode))
kfree(inode->i_fop);
}

static int tracefs_remount(struct super_block *sb, int *flags, char *data)
{
int err;
Expand Down Expand Up @@ -283,7 +258,6 @@ static int tracefs_show_options(struct seq_file *m, struct dentry *root)
static const struct super_operations tracefs_super_operations = {
.statfs = simple_statfs,
.remount_fs = tracefs_remount,
.destroy_inode = tracefs_destroy_inode,
.show_options = tracefs_show_options,
};

Expand Down Expand Up @@ -414,10 +388,12 @@ struct dentry *tracefs_create_file(const char *name, umode_t mode,
struct dentry *parent, void *data,
const struct file_operations *fops)
{
struct file_operations *proxy_fops;
struct dentry *dentry;
struct inode *inode;

if (security_locked_down(LOCKDOWN_TRACEFS))
return NULL;

if (!(mode & S_IFMT))
mode |= S_IFREG;
BUG_ON(!S_ISREG(mode));
Expand All @@ -430,20 +406,8 @@ struct dentry *tracefs_create_file(const char *name, umode_t mode,
if (unlikely(!inode))
return failed_creating(dentry);

proxy_fops = kzalloc(sizeof(struct file_operations), GFP_KERNEL);
if (unlikely(!proxy_fops)) {
iput(inode);
return failed_creating(dentry);
}

if (!fops)
fops = &tracefs_file_operations;

dentry->d_fsdata = (void *)fops;
memcpy(proxy_fops, fops, sizeof(*proxy_fops));
proxy_fops->open = default_open_file;
inode->i_mode = mode;
inode->i_fop = proxy_fops;
inode->i_fop = fops ? fops : &tracefs_file_operations;
inode->i_private = data;
d_instantiate(dentry, inode);
fsnotify_create(dentry->d_parent->d_inode, dentry);
Expand Down
55 changes: 43 additions & 12 deletions kernel/trace/ftrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <linux/clocksource.h>
#include <linux/sched/task.h>
#include <linux/kallsyms.h>
#include <linux/security.h>
#include <linux/seq_file.h>
#include <linux/tracefs.h>
#include <linux/hardirq.h>
Expand Down Expand Up @@ -3486,6 +3487,11 @@ static int
ftrace_avail_open(struct inode *inode, struct file *file)
{
struct ftrace_iterator *iter;
int ret;

ret = security_locked_down(LOCKDOWN_TRACEFS);
if (ret)
return ret;

if (unlikely(ftrace_disabled))
return -ENODEV;
Expand All @@ -3505,6 +3511,15 @@ ftrace_enabled_open(struct inode *inode, struct file *file)
{
struct ftrace_iterator *iter;

/*
* This shows us what functions are currently being
* traced and by what. Not sure if we want lockdown
* to hide such critical information for an admin.
* Although, perhaps it can show information we don't
* want people to see, but if something is tracing
* something, we probably want to know about it.
*/

iter = __seq_open_private(file, &show_ftrace_seq_ops, sizeof(*iter));
if (!iter)
return -ENOMEM;
Expand Down Expand Up @@ -3540,21 +3555,22 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag,
struct ftrace_hash *hash;
struct list_head *mod_head;
struct trace_array *tr = ops->private;
int ret = 0;
int ret = -ENOMEM;

ftrace_ops_init(ops);

if (unlikely(ftrace_disabled))
return -ENODEV;

if (tracing_check_open_get_tr(tr))
return -ENODEV;

iter = kzalloc(sizeof(*iter), GFP_KERNEL);
if (!iter)
return -ENOMEM;
goto out;

if (trace_parser_get_init(&iter->parser, FTRACE_BUFF_MAX)) {
kfree(iter);
return -ENOMEM;
}
if (trace_parser_get_init(&iter->parser, FTRACE_BUFF_MAX))
goto out;

iter->ops = ops;
iter->flags = flag;
Expand Down Expand Up @@ -3584,13 +3600,13 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag,

if (!iter->hash) {
trace_parser_put(&iter->parser);
kfree(iter);
ret = -ENOMEM;
goto out_unlock;
}
} else
iter->hash = hash;

ret = 0;

if (file->f_mode & FMODE_READ) {
iter->pg = ftrace_pages_start;

Expand All @@ -3602,14 +3618,20 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag,
/* Failed */
free_ftrace_hash(iter->hash);
trace_parser_put(&iter->parser);
kfree(iter);
}
} else
file->private_data = iter;

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

out:
if (ret) {
kfree(iter);
if (tr)
trace_array_put(tr);
}

return ret;
}

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

/* Checks for tracefs lockdown */
return ftrace_regex_open(ops,
FTRACE_ITER_FILTER | FTRACE_ITER_DO_PROBES,
inode, file);
Expand All @@ -3628,6 +3651,7 @@ ftrace_notrace_open(struct inode *inode, struct file *file)
{
struct ftrace_ops *ops = inode->i_private;

/* Checks for tracefs lockdown */
return ftrace_regex_open(ops, FTRACE_ITER_NOTRACE,
inode, file);
}
Expand Down Expand Up @@ -5037,6 +5061,8 @@ int ftrace_regex_release(struct inode *inode, struct file *file)

mutex_unlock(&iter->ops->func_hash->regex_lock);
free_ftrace_hash(iter->hash);
if (iter->tr)
trace_array_put(iter->tr);
kfree(iter);

return 0;
Expand Down Expand Up @@ -5194,9 +5220,13 @@ static int
__ftrace_graph_open(struct inode *inode, struct file *file,
struct ftrace_graph_data *fgd)
{
int ret = 0;
int ret;
struct ftrace_hash *new_hash = NULL;

ret = security_locked_down(LOCKDOWN_TRACEFS);
if (ret)
return ret;

if (file->f_mode & FMODE_WRITE) {
const int size_bits = FTRACE_HASH_DEFAULT_BITS;

Expand Down Expand Up @@ -6537,8 +6567,9 @@ ftrace_pid_open(struct inode *inode, struct file *file)
struct seq_file *m;
int ret = 0;

if (trace_array_get(tr) < 0)
return -ENODEV;
ret = tracing_check_open_get_tr(tr);
if (ret)
return ret;

if ((file->f_mode & FMODE_WRITE) &&
(file->f_flags & O_TRUNC))
Expand Down
Loading

0 comments on commit d4615e5

Please sign in to comment.