diff --git a/fs/proc/array.c b/fs/proc/array.c index 9b45ee84fbccd584144fd942ffe8fcca34c47b50..3a1dafd228d14c5e11b142084305e8b60161f84c 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -172,7 +172,7 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns, task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0; tpid = 0; if (pid_alive(p)) { - struct task_struct *tracer = tracehook_tracer_task(p); + struct task_struct *tracer = ptrace_parent(p); if (tracer) tpid = task_pid_nr_ns(tracer, ns); } diff --git a/fs/proc/base.c b/fs/proc/base.c index 14def991d9dd1cc1ac18faa981f135f138ebb13b..c883dad74b9aef5fa4792cfa3982abf2c1e1d289 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -216,7 +216,7 @@ static struct mm_struct *__check_mem_permission(struct task_struct *task) if (task_is_stopped_or_traced(task)) { int match; rcu_read_lock(); - match = (tracehook_tracer_task(task) == current); + match = (ptrace_parent(task) == current); rcu_read_unlock(); if (match && ptrace_may_access(task, PTRACE_MODE_ATTACH)) return mm; diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h index b546fd6c35068528fc142ea3d155376477a7ef8e..bb157bdd0c55d20ce71d3c66c89e74126b1f6605 100644 --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h @@ -150,6 +150,24 @@ int generic_ptrace_peekdata(struct task_struct *tsk, unsigned long addr, int generic_ptrace_pokedata(struct task_struct *tsk, unsigned long addr, unsigned long data); +/** + * ptrace_parent - return the task that is tracing the given task + * @task: task to consider + * + * Returns %NULL if no one is tracing @task, or the &struct task_struct + * pointer to its tracer. + * + * Must called under rcu_read_lock(). The pointer returned might be kept + * live only by RCU. During exec, this may be called with task_lock() held + * on @task, still held from when check_unsafe_exec() was called. + */ +static inline struct task_struct *ptrace_parent(struct task_struct *task) +{ + if (unlikely(task->ptrace)) + return rcu_dereference(task->parent); + return NULL; +} + /** * ptrace_event_enabled - test whether a ptrace event is enabled * @task: ptracee of interest diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h index bcc4ca762aee55cb0a966465895e76d0c9de4c9c..7a1bd12aeffae53aae2ced2085a0b016bab7bce0 100644 --- a/include/linux/tracehook.h +++ b/include/linux/tracehook.h @@ -129,24 +129,6 @@ static inline void tracehook_report_syscall_exit(struct pt_regs *regs, int step) ptrace_report_syscall(regs); } -/** - * tracehook_tracer_task - return the task that is tracing the given task - * @tsk: task to consider - * - * Returns NULL if no one is tracing @task, or the &struct task_struct - * pointer to its tracer. - * - * Must called under rcu_read_lock(). The pointer returned might be kept - * live only by RCU. During exec, this may be called with task_lock() - * held on @task, still held from when tracehook_unsafe_exec() was called. - */ -static inline struct task_struct *tracehook_tracer_task(struct task_struct *tsk) -{ - if (tsk->ptrace & PT_PTRACED) - return rcu_dereference(tsk->parent); - return NULL; -} - /** * tracehook_signal_handler - signal handler setup is complete * @sig: number of signal being delivered diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c index c825c6e0b636ee985283d3d4a077deaa24343808..7312bf9f7afcb6e6c8f96b68d600b0675f2ee146 100644 --- a/security/apparmor/domain.c +++ b/security/apparmor/domain.c @@ -67,7 +67,7 @@ static int may_change_ptraced_domain(struct task_struct *task, int error = 0; rcu_read_lock(); - tracer = tracehook_tracer_task(task); + tracer = ptrace_parent(task); if (tracer) { /* released below */ cred = get_task_cred(tracer); diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index a0d38459d650af32fe844ca18d4b5ff5ad03be98..fc07d18ed6fc7819c3d2c2fa12e7c1fe59ec6222 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2048,7 +2048,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) u32 ptsid = 0; rcu_read_lock(); - tracer = tracehook_tracer_task(current); + tracer = ptrace_parent(current); if (likely(tracer != NULL)) { sec = __task_cred(tracer)->security; ptsid = sec->sid; @@ -5314,7 +5314,7 @@ static int selinux_setprocattr(struct task_struct *p, Otherwise, leave SID unchanged and fail. */ ptsid = 0; task_lock(p); - tracer = tracehook_tracer_task(p); + tracer = ptrace_parent(p); if (tracer) ptsid = task_sid(tracer); task_unlock(p);