Thread (12 messages) 12 messages, 2 authors, 2024-11-06

Re: [PATCH] tracing: Add task_prctl_unknown tracepoint

From: Marco Elver <elver@google.com>
Date: 2024-11-05 16:54:30
Also in: lkml

On Tue, 5 Nov 2024 at 17:31, Steven Rostedt [off-list ref] wrote:
On Tue,  5 Nov 2024 14:34:05 +0100
Marco Elver [off-list ref] wrote:
quoted
prctl() is a complex syscall which multiplexes its functionality based
on a large set of PR_* options. Currently we count 64 such options. The
return value of unknown options is -EINVAL, and doesn't distinguish from
known options that were passed invalid args that also return -EINVAL.

To understand if programs are attempting to use prctl() options not yet
available on the running kernel, provide the task_prctl_unknown
tracepoint.

Note, this tracepoint is in an unlikely cold path, and would therefore
be suitable for continuous monitoring (e.g. via perf_event_open).

While the above is likely the simplest usecase, additionally this
tracepoint can help unlock some testing scenarios (where probing
sys_enter or sys_exit causes undesirable performance overheads):

  a. unprivileged triggering of a test module: test modules may register a
     probe to be called back on task_prctl_unknown, and pick a very large
     unknown prctl() option upon which they perform a test function for an
     unprivileged user;

  b. unprivileged triggering of an eBPF program function: similar
     as idea (a).

Example trace_pipe output:

  <...>-366     [004] .....   146.439400: task_prctl_unknown: pid=366 comm=a.out option=1234 arg2=101 arg3=102 arg4=103 arg5=104
          ^^^                                                       ^^^
quoted
Signed-off-by: Marco Elver <elver@google.com>
---
 include/trace/events/task.h | 43 +++++++++++++++++++++++++++++++++++++
 kernel/sys.c                |  3 +++
 2 files changed, 46 insertions(+)
diff --git a/include/trace/events/task.h b/include/trace/events/task.h
index 47b527464d1a..ab711e581094 100644
--- a/include/trace/events/task.h
+++ b/include/trace/events/task.h
@@ -56,6 +56,49 @@ TRACE_EVENT(task_rename,
              __entry->newcomm, __entry->oom_score_adj)
 );

+/**
+ * task_prctl_unknown - called on unknown prctl() option
+ * @task:    pointer to the current task
+ * @option:  option passed
+ * @arg2:    arg2 passed
+ * @arg3:    arg3 passed
+ * @arg4:    arg4 passed
+ * @arg5:    arg5 passed
+ *
+ * Called on an unknown prctl() option.
+ */
+TRACE_EVENT(task_prctl_unknown,
+
+     TP_PROTO(struct task_struct *task, int option, unsigned long arg2, unsigned long arg3,
+              unsigned long arg4, unsigned long arg5),
+
+     TP_ARGS(task, option, arg2, arg3, arg4, arg5),
+
+     TP_STRUCT__entry(
+             __field(        pid_t,          pid             )
Why record the pid that is already recorded by the event header?
To keep in style with the other "task" tracepoints above. I can
certainly do without - it does seem unnecessary.

To cleanup, do we want to remove "pid=" from the other tracepoints in
this file as well (in another patch). Or does this potentially break
existing users?
quoted
+             __string(       comm,           task->comm      )
I'm also surprised that the comm didn't show in the trace_pipe.
Any config options or tweaks needed to get it to show more reliably?
I've
updated the code so that it should usually find it. But saving it here may
not be a big deal.
Thanks,
-- Marco
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help