From: Tejun Heo <tj@kernel.org>
To: linux-kernel@vger.kernel.org, oleg@redhat.com
Cc: akpm@linux-foundation.org, torvalds@linux-foundation.org,
hch@infradead.org, Tejun Heo <tj@kernel.org>
Subject: [PATCH 2/7] ptrace: introduce ptrace_event_enabled() and simplify ptrace_event() and tracehook_prepare_clone()
Date: Fri, 17 Jun 2011 16:50:35 +0200 [thread overview]
Message-ID: <1308322240-8247-3-git-send-email-tj@kernel.org> (raw)
In-Reply-To: <1308322240-8247-1-git-send-email-tj@kernel.org>
This patch implements ptrace_event_enabled() which tests whether a
given PTRACE_EVENT_* is enabled and use it to simplify ptrace_event()
and tracehook_prepare_clone().
PT_EVENT_FLAG() macro is added which calculates PT_TRACE_* flag from
PTRACE_EVENT_*. This is used to define PT_TRACE_* flags and by
ptrace_event_enabled() to find the matching flag.
This is used to make ptrace_event() and tracehook_prepare_clone()
simpler.
* ptrace_event() callers were responsible for providing mask to test
whether the event was enabled. This patch implements
ptrace_event_enabled() and make ptrace_event() drop @mask and
determine whether the event is enabled from @event. Note that
@event is constant and this conversion doesn't add runtime overhead.
All conversions except tracehook_report_clone_complete() are
trivial. tracehook_report_clone_complete() used to use 0 for @mask
(always enabled) but now tests whether the specified event is
enabled. This doesn't cause any behavior difference as it's
guaranteed that the event specified by @trace is enabled.
* tracehook_prepare_clone() now only determines which event is
applicable and use ptrace_event_enabled() for enable test.
This doesn't introduce any behavior change.
Signed-off-by: Tejun Heo <tj@kernel.org>
---
include/linux/ptrace.h | 46 +++++++++++++++++++++++++++++++-------------
include/linux/tracehook.h | 26 ++++++++++++------------
2 files changed, 45 insertions(+), 27 deletions(-)
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
index 3ff20b3..18feac6 100644
--- a/include/linux/ptrace.h
+++ b/include/linux/ptrace.h
@@ -90,12 +90,17 @@
#define PT_DTRACE 0x00000002 /* delayed trace (used on m68k, i386) */
#define PT_TRACESYSGOOD 0x00000004
#define PT_PTRACE_CAP 0x00000008 /* ptracer can follow suid-exec */
-#define PT_TRACE_FORK 0x00000010
-#define PT_TRACE_VFORK 0x00000020
-#define PT_TRACE_CLONE 0x00000040
-#define PT_TRACE_EXEC 0x00000080
-#define PT_TRACE_VFORK_DONE 0x00000100
-#define PT_TRACE_EXIT 0x00000200
+
+/* PT_TRACE_* event enable flags */
+#define PT_EVENT_FLAG_SHIFT 4
+#define PT_EVENT_FLAG(event) (1 << (PT_EVENT_FLAG_SHIFT + (event) - 1))
+
+#define PT_TRACE_FORK PT_EVENT_FLAG(PTRACE_EVENT_FORK)
+#define PT_TRACE_VFORK PT_EVENT_FLAG(PTRACE_EVENT_VFORK)
+#define PT_TRACE_CLONE PT_EVENT_FLAG(PTRACE_EVENT_CLONE)
+#define PT_TRACE_EXEC PT_EVENT_FLAG(PTRACE_EVENT_EXEC)
+#define PT_TRACE_VFORK_DONE PT_EVENT_FLAG(PTRACE_EVENT_VFORK_DONE)
+#define PT_TRACE_EXIT PT_EVENT_FLAG(PTRACE_EVENT_EXIT)
#define PT_TRACE_MASK 0x000003f4
@@ -146,25 +151,38 @@ int generic_ptrace_pokedata(struct task_struct *tsk, unsigned long addr,
unsigned long data);
/**
+ * ptrace_event_enabled - test whether a ptrace event is enabled
+ * @task: ptracee of interest
+ * @event: %PTRACE_EVENT_* to test
+ *
+ * Test whether @event is enabled for ptracee @task.
+ *
+ * Returns %true if @event is enabled, %false otherwise.
+ */
+static inline bool ptrace_event_enabled(struct task_struct *task, int event)
+{
+ return task->ptrace & PT_EVENT_FLAG(event);
+}
+
+/**
* ptrace_event - possibly stop for a ptrace event notification
- * @mask: %PT_* bit to check in @current->ptrace
- * @event: %PTRACE_EVENT_* value to report if @mask is set
+ * @event: %PTRACE_EVENT_* value to report
* @message: value for %PTRACE_GETEVENTMSG to return
*
- * This checks the @mask bit to see if ptrace wants stops for this event.
- * If so we stop, reporting @event and @message to the ptrace parent.
+ * Check whether @event is enabled and, if so, report @event and @message
+ * to the ptrace parent.
*
* Returns nonzero if we did a ptrace notification, zero if not.
*
* Called without locks.
*/
-static inline int ptrace_event(int mask, int event, unsigned long message)
+static inline int ptrace_event(int event, unsigned long message)
{
- if (mask && likely(!(current->ptrace & mask)))
- return 0;
+ if (likely(!ptrace_event_enabled(current, event)))
+ return false;
current->ptrace_message = message;
ptrace_notify((event << 8) | SIGTRAP);
- return 1;
+ return true;
}
/**
diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h
index a3e8387..7d38571 100644
--- a/include/linux/tracehook.h
+++ b/include/linux/tracehook.h
@@ -201,7 +201,7 @@ static inline void tracehook_report_exec(struct linux_binfmt *fmt,
struct linux_binprm *bprm,
struct pt_regs *regs)
{
- if (!ptrace_event(PT_TRACE_EXEC, PTRACE_EVENT_EXEC, 0) &&
+ if (!ptrace_event(PTRACE_EVENT_EXEC, 0) &&
unlikely(current->ptrace & PT_PTRACED))
send_sig(SIGTRAP, current, 0);
}
@@ -218,7 +218,7 @@ static inline void tracehook_report_exec(struct linux_binfmt *fmt,
*/
static inline void tracehook_report_exit(long *exit_code)
{
- ptrace_event(PT_TRACE_EXIT, PTRACE_EVENT_EXIT, *exit_code);
+ ptrace_event(PTRACE_EVENT_EXIT, *exit_code);
}
/**
@@ -232,19 +232,19 @@ static inline void tracehook_report_exit(long *exit_code)
*/
static inline int tracehook_prepare_clone(unsigned clone_flags)
{
+ int event = 0;
+
if (clone_flags & CLONE_UNTRACED)
return 0;
- if (clone_flags & CLONE_VFORK) {
- if (current->ptrace & PT_TRACE_VFORK)
- return PTRACE_EVENT_VFORK;
- } else if ((clone_flags & CSIGNAL) != SIGCHLD) {
- if (current->ptrace & PT_TRACE_CLONE)
- return PTRACE_EVENT_CLONE;
- } else if (current->ptrace & PT_TRACE_FORK)
- return PTRACE_EVENT_FORK;
+ if (clone_flags & CLONE_VFORK)
+ event = PTRACE_EVENT_VFORK;
+ else if ((clone_flags & CSIGNAL) != SIGCHLD)
+ event = PTRACE_EVENT_CLONE;
+ else
+ event = PTRACE_EVENT_FORK;
- return 0;
+ return ptrace_event_enabled(current, event) ? event : 0;
}
/**
@@ -318,7 +318,7 @@ static inline void tracehook_report_clone_complete(int trace,
struct task_struct *child)
{
if (unlikely(trace))
- ptrace_event(0, trace, pid);
+ ptrace_event(trace, pid);
}
/**
@@ -336,7 +336,7 @@ static inline void tracehook_report_clone_complete(int trace,
static inline void tracehook_report_vfork_done(struct task_struct *child,
pid_t pid)
{
- ptrace_event(PT_TRACE_VFORK_DONE, PTRACE_EVENT_VFORK_DONE, pid);
+ ptrace_event(PTRACE_EVENT_VFORK_DONE, pid);
}
/**
--
1.7.5.4
next prev parent reply other threads:[~2011-06-17 14:51 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-06-17 14:50 [PATCHSET] ptrace: kill most tracehooks Tejun Heo
2011-06-17 14:50 ` [PATCH 1/7] ptrace: kill task_ptrace() Tejun Heo
2011-06-17 14:50 ` Tejun Heo [this message]
2011-06-17 14:50 ` [PATCH 3/7] ptrace: move SIGTRAP on exec(2) logic to ptrace_event() Tejun Heo
2011-06-20 20:25 ` Oleg Nesterov
2011-06-21 7:21 ` Tejun Heo
2011-06-21 20:40 ` Oleg Nesterov
2011-06-23 8:58 ` Tejun Heo
2011-06-17 14:50 ` [PATCH 4/7] ptrace: kill trivial tracehooks Tejun Heo
2011-06-17 14:50 ` [PATCH 5/7] ptrace: kill clone/exec tracehooks Tejun Heo
2011-06-20 20:33 ` Oleg Nesterov
2011-06-21 7:24 ` Tejun Heo
2011-06-17 14:50 ` [PATCH 6/7] ptrace: kill detah tracehooks Tejun Heo
2011-06-20 19:39 ` Oleg Nesterov
2011-06-21 20:23 ` Oleg Nesterov
2011-06-23 9:24 ` Tejun Heo
2011-06-22 21:07 ` [PATCH 0/8] kill task_detached() (Was: ptrace: kill detah tracehooks) Oleg Nesterov
2011-06-22 21:08 ` [PATCH 1/8] make do_notify_parent() return bool Oleg Nesterov
2011-06-23 9:52 ` Tejun Heo
2011-06-22 21:08 ` [PATCH 2/8] kill tracehook_notify_death() Oleg Nesterov
2011-06-23 12:22 ` Tejun Heo
2011-06-23 13:21 ` Oleg Nesterov
2011-06-23 13:27 ` Tejun Heo
2011-06-23 13:28 ` Oleg Nesterov
2011-06-23 17:06 ` Oleg Nesterov
2011-06-25 14:15 ` Tejun Heo
2011-06-26 20:51 ` Oleg Nesterov
2011-06-27 8:24 ` Tejun Heo
2011-06-27 14:21 ` Oleg Nesterov
2011-06-27 14:36 ` Tejun Heo
2011-06-22 21:08 ` [PATCH 3/8] __ptrace_detach: avoid task_detached(), check do_notify_parent() Oleg Nesterov
2011-06-23 13:25 ` Tejun Heo
2011-06-22 21:09 ` [PATCH 4/8] make do_notify_parent() __must_check, update the callers Oleg Nesterov
2011-06-23 13:38 ` Tejun Heo
2011-06-22 21:09 ` [PATCH 5/8] reparent_leader: check EXIT_DEAD instead of task_detached() Oleg Nesterov
2011-06-22 21:09 ` [PATCH 6/8] kill task_detached() Oleg Nesterov
2011-06-22 21:10 ` [PATCH 7/8] do not change dead_task->exit_signal Oleg Nesterov
2011-06-22 21:10 ` [PATCH 8/8] redefine thread_group_leader() as exit_signal >= 0 Oleg Nesterov
2011-06-23 13:56 ` Tejun Heo
2011-06-17 14:50 ` [PATCH 7/7] ptrace: s/tracehook_tracer_task()/ptrace_parent()/ Tejun Heo
2011-06-20 20:16 ` Oleg Nesterov
2011-06-21 11:44 ` John Johansen
2011-06-23 9:14 ` Tejun Heo
2011-06-20 11:16 ` [PATCHSET] ptrace: kill most tracehooks Christoph Hellwig
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1308322240-8247-3-git-send-email-tj@kernel.org \
--to=tj@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=hch@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=oleg@redhat.com \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome