Messages in this thread Patch in this message | | | From | Tejun Heo <> | Subject | [PATCH 17/19] ptrace: don't let PTRACE_SETSIGINFO override __SI_TRAP siginfo | Date | Tue, 24 May 2011 20:37:37 +0200 |
| |
__SI_TRAP siginfo is special in the operation of ptrace. It reports group stop related information and will also interact with notification retraps. Don't let userland mess with it.
Signed-off-by: Tejun Heo <tj@kernel.org> --- kernel/ptrace.c | 31 ++++++++++++++++++++++--------- 1 files changed, 22 insertions(+), 9 deletions(-)
diff --git a/kernel/ptrace.c b/kernel/ptrace.c index a205c98..a9b3c67 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -610,16 +610,29 @@ out_unlock: static int ptrace_setsiginfo(struct task_struct *child, const siginfo_t *info) { unsigned long flags; - int error = -ESRCH; + int error; - if (lock_task_sighand(child, &flags)) { - error = -EINVAL; - if (likely(child->last_siginfo != NULL)) { - *child->last_siginfo = *info; - error = 0; - } - unlock_task_sighand(child, &flags); - } + if (!lock_task_sighand(child, &flags)) + return -ESRCH; + + error = -EINVAL; + if (unlikely(!child->last_siginfo)) + goto out_unlock; + + /* + * If seized, __SI_TRAP siginfo is used to communicate information + * regarding traps and contains dynamic information generated on + * GETSIGINFO. Don't let userland override or fake it. + */ + if ((child->ptrace & PT_SEIZED) && + unlikely((child->last_siginfo->si_code & __SI_MASK) == __SI_TRAP || + (info->si_code & __SI_MASK) == __SI_TRAP)) + goto out_unlock; + + *child->last_siginfo = *info; + error = 0; +out_unlock: + unlock_task_sighand(child, &flags); return error; } -- 1.7.1
| |