Merge branch 'v3.10/topic/misc' into linux-linaro-lsk-v3.10
[firefly-linux-kernel-4.4.55.git] / include / linux / ptrace.h
index 89573a33ab3c43ee84cf629d84e5ff3d7f091206..bb980ae6d9d3601524b1270c9f27880766e6d722 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/sched.h>               /* For struct task_struct.  */
 #include <linux/err.h>                 /* for IS_ERR_VALUE */
 #include <linux/bug.h>                 /* For BUG_ON.  */
+#include <linux/pid_namespace.h>       /* For task_active_pid_ns.  */
 #include <uapi/linux/ptrace.h>
 
 /*
@@ -128,6 +129,37 @@ static inline void ptrace_event(int event, unsigned long message)
        }
 }
 
+/**
+ * ptrace_event_pid - possibly stop for a ptrace event notification
+ * @event:     %PTRACE_EVENT_* value to report
+ * @pid:       process identifier for %PTRACE_GETEVENTMSG to return
+ *
+ * Check whether @event is enabled and, if so, report @event and @pid
+ * to the ptrace parent.  @pid is reported as the pid_t seen from the
+ * the ptrace parent's pid namespace.
+ *
+ * Called without locks.
+ */
+static inline void ptrace_event_pid(int event, struct pid *pid)
+{
+       /*
+        * FIXME: There's a potential race if a ptracer in a different pid
+        * namespace than parent attaches between computing message below and
+        * when we acquire tasklist_lock in ptrace_stop().  If this happens,
+        * the ptracer will get a bogus pid from PTRACE_GETEVENTMSG.
+        */
+       unsigned long message = 0;
+       struct pid_namespace *ns;
+
+       rcu_read_lock();
+       ns = task_active_pid_ns(rcu_dereference(current->parent));
+       if (ns)
+               message = pid_nr_ns(pid, ns);
+       rcu_read_unlock();
+
+       ptrace_event(event, message);
+}
+
 /**
  * ptrace_init_task - initialize ptrace state for a new child
  * @child:             new child task
@@ -305,6 +337,9 @@ static inline void user_single_step_siginfo(struct task_struct *tsk,
  * calling arch_ptrace_stop() when it would be superfluous.  For example,
  * if the thread has not been back to user mode since the last stop, the
  * thread state might indicate that nothing needs to be done.
+ *
+ * This is guaranteed to be invoked once before a task stops for ptrace and
+ * may include arch-specific operations necessary prior to a ptrace stop.
  */
 #define arch_ptrace_stop_needed(code, info)    (0)
 #endif