summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBeau Belgrave <beaub@linux.microsoft.com>2022-03-08 14:28:07 -0800
committerSteven Rostedt (Google) <rostedt@goodmis.org>2022-03-15 14:33:20 -0400
commit089331d47325d3f55016ed3d1f79ffd2754fb19e (patch)
treebe7460b7e6171017a3a0806cf0d46510d33f0e3f
parentbc47ee4844d6b7d7351536cd99d35848c4449689 (diff)
downloadlinux-089331d47325d3f55016ed3d1f79ffd2754fb19e.tar.bz2
user_events: Add trace event call as root for low permission cases
Tracefs by default is locked down heavily. System operators can open up some files, such as user_events to a broader set of users. These users do not have access within tracefs beyond just the user_event files. Due to this restriction the trace_add_event_call/remove calls will silently fail since the caller does not have permissions to create directories. To fix this trace_add_event_call/remove calls will be issued with override creds of the global root UID. Creds are reverted immediately afterward. Link: https://lkml.kernel.org/r/20220308222807.2040-1-beaub@linux.microsoft.com Signed-off-by: Beau Belgrave <beaub@linux.microsoft.com> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
-rw-r--r--kernel/trace/trace_events_user.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/kernel/trace/trace_events_user.c b/kernel/trace/trace_events_user.c
index e10ad057e797..8b3d241a31c2 100644
--- a/kernel/trace/trace_events_user.c
+++ b/kernel/trace/trace_events_user.c
@@ -562,6 +562,41 @@ static struct trace_event_functions user_event_funcs = {
.trace = user_event_print_trace,
};
+static int user_event_set_call_visible(struct user_event *user, bool visible)
+{
+ int ret;
+ const struct cred *old_cred;
+ struct cred *cred;
+
+ cred = prepare_creds();
+
+ if (!cred)
+ return -ENOMEM;
+
+ /*
+ * While by default tracefs is locked down, systems can be configured
+ * to allow user_event files to be less locked down. The extreme case
+ * being "other" has read/write access to user_events_data/status.
+ *
+ * When not locked down, processes may not have have permissions to
+ * add/remove calls themselves to tracefs. We need to temporarily
+ * switch to root file permission to allow for this scenario.
+ */
+ cred->fsuid = GLOBAL_ROOT_UID;
+
+ old_cred = override_creds(cred);
+
+ if (visible)
+ ret = trace_add_event_call(&user->call);
+ else
+ ret = trace_remove_event_call(&user->call);
+
+ revert_creds(old_cred);
+ put_cred(cred);
+
+ return ret;
+}
+
static int destroy_user_event(struct user_event *user)
{
int ret = 0;
@@ -569,7 +604,7 @@ static int destroy_user_event(struct user_event *user)
/* Must destroy fields before call removal */
user_event_destroy_fields(user);
- ret = trace_remove_event_call(&user->call);
+ ret = user_event_set_call_visible(user, false);
if (ret)
return ret;
@@ -1049,7 +1084,7 @@ static int user_event_trace_register(struct user_event *user)
if (!ret)
return -ENODEV;
- ret = trace_add_event_call(&user->call);
+ ret = user_event_set_call_visible(user, true);
if (ret)
unregister_trace_event(&user->call.event);