tracing: Add locked_down checks to the open calls of files created for tracefs
authorSteven Rostedt (VMware) <rostedt@goodmis.org>
Fri, 11 Oct 2019 21:22:50 +0000 (17:22 -0400)
committerSteven Rostedt (VMware) <rostedt@goodmis.org>
Sun, 13 Oct 2019 00:48:06 +0000 (20:48 -0400)
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>
kernel/trace/ftrace.c
kernel/trace/trace.c
kernel/trace/trace_events.c
kernel/trace/trace_events_hist.c
kernel/trace/trace_events_trigger.c
kernel/trace/trace_kprobe.c
kernel/trace/trace_printk.c
kernel/trace/trace_stack.c
kernel/trace/trace_stat.c
kernel/trace/trace_uprobe.c

index 8b765a55e01cfcd415a2b50ad603319f1736bc71..f296d89be757974861953602ba933859ed8d7cb7 100644 (file)
@@ -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>
@@ -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;
@@ -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;
@@ -3625,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);
@@ -3635,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);
 }
@@ -5203,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;
 
index 26ee280f852b17e0b8890b64e51afdc683249853..2b4eff383505cafeba1fc432c7c3602cc0486909 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/stacktrace.h>
 #include <linux/writeback.h>
 #include <linux/kallsyms.h>
+#include <linux/security.h>
 #include <linux/seq_file.h>
 #include <linux/notifier.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 ret;
+
+       ret = security_locked_down(LOCKDOWN_TRACEFS);
+       if (ret)
+               return ret;
+
        if (tracing_disabled)
                return -ENODEV;
 
@@ -6813,6 +6820,7 @@ static int snapshot_raw_open(struct inode *inode, struct file *filp)
        struct ftrace_buffer_info *info;
        int ret;
 
+       /* The following checks for tracefs lockdown */
        ret = tracing_buffers_open(inode, filp);
        if (ret < 0)
                return ret;
index 71ab0a3660f4b521d3b13056e2afde766bf55100..fba87d10f0c1af1ab9367a981667cc452efd4707 100644 (file)
@@ -12,6 +12,7 @@
 #define pr_fmt(fmt) fmt
 
 #include <linux/workqueue.h>
+#include <linux/security.h>
 #include <linux/spinlock.h>
 #include <linux/kthread.h>
 #include <linux/tracefs.h>
@@ -1294,6 +1295,8 @@ static int trace_format_open(struct inode *inode, struct file *file)
        struct seq_file *m;
        int ret;
 
+       /* Do we want to hide event format files on tracefs lockdown? */
+
        ret = seq_open(file, &trace_format_seq_ops);
        if (ret < 0)
                return ret;
@@ -1760,6 +1763,10 @@ ftrace_event_open(struct inode *inode, struct file *file,
        struct seq_file *m;
        int ret;
 
+       ret = security_locked_down(LOCKDOWN_TRACEFS);
+       if (ret)
+               return ret;
+
        ret = seq_open(file, seq_ops);
        if (ret < 0)
                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;
 
+       /* Checks for tracefs lockdown */
        return ftrace_event_open(inode, file, seq_ops);
 }
 
index dd18d76bf1bd00beea7b29f5b37f58773df57442..57648c5aa6797767781f3d9464eed32f426c1b40 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <linux/module.h>
 #include <linux/kallsyms.h>
+#include <linux/security.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
 #include <linux/stacktrace.h>
@@ -1448,6 +1449,10 @@ static int synth_events_open(struct inode *inode, struct file *file)
 {
        int ret;
 
+       ret = security_locked_down(LOCKDOWN_TRACEFS);
+       if (ret)
+               return ret;
+
        if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
                ret = dyn_events_release_all(&synth_event_ops);
                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)
 {
+       int ret;
+
+       ret = security_locked_down(LOCKDOWN_TRACEFS);
+       if (ret)
+               return ret;
+
        return single_open(file, hist_show, file);
 }
 
index 2a2912cb4533fef2ba7170c7f8ddbf25676bc40d..2cd53ca21b515f620873572845a8e591ae44a968 100644 (file)
@@ -5,6 +5,7 @@
  * Copyright (C) 2013 Tom Zanussi <tom.zanussi@linux.intel.com>
  */
 
+#include <linux/security.h>
 #include <linux/module.h>
 #include <linux/ctype.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)
 {
-       int ret = 0;
+       int ret;
+
+       ret = security_locked_down(LOCKDOWN_TRACEFS);
+       if (ret)
+               return ret;
 
        mutex_lock(&event_mutex);
 
@@ -292,6 +297,7 @@ event_trigger_write(struct file *filp, const char __user *ubuf,
 static int
 event_trigger_open(struct inode *inode, struct file *filp)
 {
+       /* Checks for tracefs lockdown */
        return event_trigger_regex_open(inode, filp);
 }
 
index 324ffbea35567d5167511bac40aefbfa51b1268c..1552a95c743bfbbc70451501cdd3b4763036ede3 100644 (file)
@@ -7,11 +7,11 @@
  */
 #define pr_fmt(fmt)    "trace_kprobe: " fmt
 
+#include <linux/security.h>
 #include <linux/module.h>
 #include <linux/uaccess.h>
 #include <linux/rculist.h>
 #include <linux/error-injection.h>
-#include <linux/security.h>
 
 #include <asm/setup.h>  /* for COMMAND_LINE_SIZE */
 
@@ -936,6 +936,10 @@ static int probes_open(struct inode *inode, struct file *file)
 {
        int ret;
 
+       ret = security_locked_down(LOCKDOWN_TRACEFS);
+       if (ret)
+               return ret;
+
        if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
                ret = dyn_events_release_all(&trace_kprobe_ops);
                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)
 {
+       int ret;
+
+       ret = security_locked_down(LOCKDOWN_TRACEFS);
+       if (ret)
+               return ret;
+
        return seq_open(file, &profile_seq_op);
 }
 
index c3fd849d4a8f93c27d18713ae1e492faa5d24ec9..d4e31e96920650fef131562dda2ff5cc52b39fbb 100644 (file)
@@ -6,6 +6,7 @@
  *
  */
 #include <linux/seq_file.h>
+#include <linux/security.h>
 #include <linux/uaccess.h>
 #include <linux/kernel.h>
 #include <linux/ftrace.h>
@@ -348,6 +349,12 @@ static const struct seq_operations show_format_seq_ops = {
 static int
 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);
 }
 
index ec9a34a97129230e5dea84f88b583871f993f6ea..4df9a209f7caf2aaf213c7a45e317dd0c79338f2 100644 (file)
@@ -5,6 +5,7 @@
  */
 #include <linux/sched/task_stack.h>
 #include <linux/stacktrace.h>
+#include <linux/security.h>
 #include <linux/kallsyms.h>
 #include <linux/seq_file.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)
 {
+       int ret;
+
+       ret = security_locked_down(LOCKDOWN_TRACEFS);
+       if (ret)
+               return ret;
+
        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;
 
+       /* Checks for tracefs lockdown */
        return ftrace_regex_open(ops, FTRACE_ITER_FILTER,
                                 inode, file);
 }
index 75bf1bcb4a8a56164641549f51bbec41584afe24..9ab0a1a7ad5ee042dff2e25b3485204cea2e844d 100644 (file)
@@ -9,7 +9,7 @@
  *
  */
 
-
+#include <linux/security.h>
 #include <linux/list.h>
 #include <linux/slab.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 stat_session *session = inode->i_private;
 
+       ret = security_locked_down(LOCKDOWN_TRACEFS);
+       if (ret)
+               return ret;
+
        ret = stat_seq_init(session);
        if (ret)
                return ret;
index dd884341f5c57aec35dbc54e7649044a7a19eb24..352073d36585ade088c3610725a1af273f4fb5a8 100644 (file)
@@ -7,6 +7,7 @@
  */
 #define pr_fmt(fmt)    "trace_uprobe: " fmt
 
+#include <linux/security.h>
 #include <linux/ctype.h>
 #include <linux/module.h>
 #include <linux/uaccess.h>
@@ -769,6 +770,10 @@ static int probes_open(struct inode *inode, struct file *file)
 {
        int ret;
 
+       ret = security_locked_down(LOCKDOWN_TRACEFS);
+       if (ret)
+               return ret;
+
        if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
                ret = dyn_events_release_all(&trace_uprobe_ops);
                if (ret)
@@ -818,6 +823,12 @@ static const struct seq_operations profile_seq_op = {
 
 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);
 }