tracing: Add locked_down checks to the open calls of files created for tracefs
Added various checks on open tracefs calls to see if tracefs is in lockdown mode, and if so, to return -EPERM. Note, the event format files (which are basically standard on all machines) as well as the enabled_functions file (which shows what is currently being traced) are not lockde down. Perhaps they should be, but it seems counter intuitive to lockdown information to help you know if the system has been modified. Link: http://lkml.kernel.org/r/CAHk-=wj7fGPKUspr579Cii-w_y60PtRaiDgKuxVtBAMK0VNNkA@mail.gmail.com Suggested-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
This commit is contained in:
Родитель
8530dec63e
Коммит
17911ff38a
|
@ -18,6 +18,7 @@
|
||||||
#include <linux/clocksource.h>
|
#include <linux/clocksource.h>
|
||||||
#include <linux/sched/task.h>
|
#include <linux/sched/task.h>
|
||||||
#include <linux/kallsyms.h>
|
#include <linux/kallsyms.h>
|
||||||
|
#include <linux/security.h>
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
#include <linux/tracefs.h>
|
#include <linux/tracefs.h>
|
||||||
#include <linux/hardirq.h>
|
#include <linux/hardirq.h>
|
||||||
|
@ -3486,6 +3487,11 @@ static int
|
||||||
ftrace_avail_open(struct inode *inode, struct file *file)
|
ftrace_avail_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
struct ftrace_iterator *iter;
|
struct ftrace_iterator *iter;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = security_locked_down(LOCKDOWN_TRACEFS);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
if (unlikely(ftrace_disabled))
|
if (unlikely(ftrace_disabled))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
@ -3505,6 +3511,15 @@ ftrace_enabled_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
struct ftrace_iterator *iter;
|
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));
|
iter = __seq_open_private(file, &show_ftrace_seq_ops, sizeof(*iter));
|
||||||
if (!iter)
|
if (!iter)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -3625,6 +3640,7 @@ ftrace_filter_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
struct ftrace_ops *ops = inode->i_private;
|
struct ftrace_ops *ops = inode->i_private;
|
||||||
|
|
||||||
|
/* Checks for tracefs lockdown */
|
||||||
return ftrace_regex_open(ops,
|
return ftrace_regex_open(ops,
|
||||||
FTRACE_ITER_FILTER | FTRACE_ITER_DO_PROBES,
|
FTRACE_ITER_FILTER | FTRACE_ITER_DO_PROBES,
|
||||||
inode, file);
|
inode, file);
|
||||||
|
@ -3635,6 +3651,7 @@ ftrace_notrace_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
struct ftrace_ops *ops = inode->i_private;
|
struct ftrace_ops *ops = inode->i_private;
|
||||||
|
|
||||||
|
/* Checks for tracefs lockdown */
|
||||||
return ftrace_regex_open(ops, FTRACE_ITER_NOTRACE,
|
return ftrace_regex_open(ops, FTRACE_ITER_NOTRACE,
|
||||||
inode, file);
|
inode, file);
|
||||||
}
|
}
|
||||||
|
@ -5203,9 +5220,13 @@ static int
|
||||||
__ftrace_graph_open(struct inode *inode, struct file *file,
|
__ftrace_graph_open(struct inode *inode, struct file *file,
|
||||||
struct ftrace_graph_data *fgd)
|
struct ftrace_graph_data *fgd)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret;
|
||||||
struct ftrace_hash *new_hash = NULL;
|
struct ftrace_hash *new_hash = NULL;
|
||||||
|
|
||||||
|
ret = security_locked_down(LOCKDOWN_TRACEFS);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
if (file->f_mode & FMODE_WRITE) {
|
if (file->f_mode & FMODE_WRITE) {
|
||||||
const int size_bits = FTRACE_HASH_DEFAULT_BITS;
|
const int size_bits = FTRACE_HASH_DEFAULT_BITS;
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <linux/stacktrace.h>
|
#include <linux/stacktrace.h>
|
||||||
#include <linux/writeback.h>
|
#include <linux/writeback.h>
|
||||||
#include <linux/kallsyms.h>
|
#include <linux/kallsyms.h>
|
||||||
|
#include <linux/security.h>
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
#include <linux/notifier.h>
|
#include <linux/notifier.h>
|
||||||
#include <linux/irqflags.h>
|
#include <linux/irqflags.h>
|
||||||
|
@ -306,6 +307,12 @@ void trace_array_put(struct trace_array *this_tr)
|
||||||
|
|
||||||
int tracing_check_open_get_tr(struct trace_array *tr)
|
int tracing_check_open_get_tr(struct trace_array *tr)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = security_locked_down(LOCKDOWN_TRACEFS);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
if (tracing_disabled)
|
if (tracing_disabled)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
|
@ -6813,6 +6820,7 @@ static int snapshot_raw_open(struct inode *inode, struct file *filp)
|
||||||
struct ftrace_buffer_info *info;
|
struct ftrace_buffer_info *info;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
/* The following checks for tracefs lockdown */
|
||||||
ret = tracing_buffers_open(inode, filp);
|
ret = tracing_buffers_open(inode, filp);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#define pr_fmt(fmt) fmt
|
#define pr_fmt(fmt) fmt
|
||||||
|
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
|
#include <linux/security.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/kthread.h>
|
#include <linux/kthread.h>
|
||||||
#include <linux/tracefs.h>
|
#include <linux/tracefs.h>
|
||||||
|
@ -1294,6 +1295,8 @@ static int trace_format_open(struct inode *inode, struct file *file)
|
||||||
struct seq_file *m;
|
struct seq_file *m;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
/* Do we want to hide event format files on tracefs lockdown? */
|
||||||
|
|
||||||
ret = seq_open(file, &trace_format_seq_ops);
|
ret = seq_open(file, &trace_format_seq_ops);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1760,6 +1763,10 @@ ftrace_event_open(struct inode *inode, struct file *file,
|
||||||
struct seq_file *m;
|
struct seq_file *m;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
ret = security_locked_down(LOCKDOWN_TRACEFS);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
ret = seq_open(file, seq_ops);
|
ret = seq_open(file, seq_ops);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1784,6 +1791,7 @@ ftrace_event_avail_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
const struct seq_operations *seq_ops = &show_event_seq_ops;
|
const struct seq_operations *seq_ops = &show_event_seq_ops;
|
||||||
|
|
||||||
|
/* Checks for tracefs lockdown */
|
||||||
return ftrace_event_open(inode, file, seq_ops);
|
return ftrace_event_open(inode, file, seq_ops);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/kallsyms.h>
|
#include <linux/kallsyms.h>
|
||||||
|
#include <linux/security.h>
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/stacktrace.h>
|
#include <linux/stacktrace.h>
|
||||||
|
@ -1448,6 +1449,10 @@ static int synth_events_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
ret = security_locked_down(LOCKDOWN_TRACEFS);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
|
if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
|
||||||
ret = dyn_events_release_all(&synth_event_ops);
|
ret = dyn_events_release_all(&synth_event_ops);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@ -5515,6 +5520,12 @@ static int hist_show(struct seq_file *m, void *v)
|
||||||
|
|
||||||
static int event_hist_open(struct inode *inode, struct file *file)
|
static int event_hist_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = security_locked_down(LOCKDOWN_TRACEFS);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
return single_open(file, hist_show, file);
|
return single_open(file, hist_show, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* Copyright (C) 2013 Tom Zanussi <tom.zanussi@linux.intel.com>
|
* Copyright (C) 2013 Tom Zanussi <tom.zanussi@linux.intel.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/security.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/ctype.h>
|
#include <linux/ctype.h>
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
|
@ -173,7 +174,11 @@ static const struct seq_operations event_triggers_seq_ops = {
|
||||||
|
|
||||||
static int event_trigger_regex_open(struct inode *inode, struct file *file)
|
static int event_trigger_regex_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret;
|
||||||
|
|
||||||
|
ret = security_locked_down(LOCKDOWN_TRACEFS);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
mutex_lock(&event_mutex);
|
mutex_lock(&event_mutex);
|
||||||
|
|
||||||
|
@ -292,6 +297,7 @@ event_trigger_write(struct file *filp, const char __user *ubuf,
|
||||||
static int
|
static int
|
||||||
event_trigger_open(struct inode *inode, struct file *filp)
|
event_trigger_open(struct inode *inode, struct file *filp)
|
||||||
{
|
{
|
||||||
|
/* Checks for tracefs lockdown */
|
||||||
return event_trigger_regex_open(inode, filp);
|
return event_trigger_regex_open(inode, filp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,11 +7,11 @@
|
||||||
*/
|
*/
|
||||||
#define pr_fmt(fmt) "trace_kprobe: " fmt
|
#define pr_fmt(fmt) "trace_kprobe: " fmt
|
||||||
|
|
||||||
|
#include <linux/security.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
#include <linux/rculist.h>
|
#include <linux/rculist.h>
|
||||||
#include <linux/error-injection.h>
|
#include <linux/error-injection.h>
|
||||||
#include <linux/security.h>
|
|
||||||
|
|
||||||
#include <asm/setup.h> /* for COMMAND_LINE_SIZE */
|
#include <asm/setup.h> /* for COMMAND_LINE_SIZE */
|
||||||
|
|
||||||
|
@ -936,6 +936,10 @@ static int probes_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
ret = security_locked_down(LOCKDOWN_TRACEFS);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
|
if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
|
||||||
ret = dyn_events_release_all(&trace_kprobe_ops);
|
ret = dyn_events_release_all(&trace_kprobe_ops);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@ -988,6 +992,12 @@ static const struct seq_operations profile_seq_op = {
|
||||||
|
|
||||||
static int profile_open(struct inode *inode, struct file *file)
|
static int profile_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = security_locked_down(LOCKDOWN_TRACEFS);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
return seq_open(file, &profile_seq_op);
|
return seq_open(file, &profile_seq_op);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
|
#include <linux/security.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/ftrace.h>
|
#include <linux/ftrace.h>
|
||||||
|
@ -348,6 +349,12 @@ static const struct seq_operations show_format_seq_ops = {
|
||||||
static int
|
static int
|
||||||
ftrace_formats_open(struct inode *inode, struct file *file)
|
ftrace_formats_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = security_locked_down(LOCKDOWN_TRACEFS);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
return seq_open(file, &show_format_seq_ops);
|
return seq_open(file, &show_format_seq_ops);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
#include <linux/sched/task_stack.h>
|
#include <linux/sched/task_stack.h>
|
||||||
#include <linux/stacktrace.h>
|
#include <linux/stacktrace.h>
|
||||||
|
#include <linux/security.h>
|
||||||
#include <linux/kallsyms.h>
|
#include <linux/kallsyms.h>
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
|
@ -470,6 +471,12 @@ static const struct seq_operations stack_trace_seq_ops = {
|
||||||
|
|
||||||
static int stack_trace_open(struct inode *inode, struct file *file)
|
static int stack_trace_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = security_locked_down(LOCKDOWN_TRACEFS);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
return seq_open(file, &stack_trace_seq_ops);
|
return seq_open(file, &stack_trace_seq_ops);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,6 +494,7 @@ stack_trace_filter_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
struct ftrace_ops *ops = inode->i_private;
|
struct ftrace_ops *ops = inode->i_private;
|
||||||
|
|
||||||
|
/* Checks for tracefs lockdown */
|
||||||
return ftrace_regex_open(ops, FTRACE_ITER_FILTER,
|
return ftrace_regex_open(ops, FTRACE_ITER_FILTER,
|
||||||
inode, file);
|
inode, file);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/security.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/rbtree.h>
|
#include <linux/rbtree.h>
|
||||||
|
@ -238,6 +238,10 @@ static int tracing_stat_open(struct inode *inode, struct file *file)
|
||||||
struct seq_file *m;
|
struct seq_file *m;
|
||||||
struct stat_session *session = inode->i_private;
|
struct stat_session *session = inode->i_private;
|
||||||
|
|
||||||
|
ret = security_locked_down(LOCKDOWN_TRACEFS);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
ret = stat_seq_init(session);
|
ret = stat_seq_init(session);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
*/
|
*/
|
||||||
#define pr_fmt(fmt) "trace_uprobe: " fmt
|
#define pr_fmt(fmt) "trace_uprobe: " fmt
|
||||||
|
|
||||||
|
#include <linux/security.h>
|
||||||
#include <linux/ctype.h>
|
#include <linux/ctype.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
|
@ -769,6 +770,10 @@ static int probes_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
ret = security_locked_down(LOCKDOWN_TRACEFS);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
|
if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
|
||||||
ret = dyn_events_release_all(&trace_uprobe_ops);
|
ret = dyn_events_release_all(&trace_uprobe_ops);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -818,6 +823,12 @@ static const struct seq_operations profile_seq_op = {
|
||||||
|
|
||||||
static int profile_open(struct inode *inode, struct file *file)
|
static int profile_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = security_locked_down(LOCKDOWN_TRACEFS);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
return seq_open(file, &profile_seq_op);
|
return seq_open(file, &profile_seq_op);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче