PowerPC arch_ptrace() writes beyond thread_struct/task_struct

Christophe Leroy christophe.leroy at c-s.fr
Thu Jun 6 15:15:46 AEST 2019



Le 05/06/2019 à 23:45, Radu Rendec a écrit :
> Hi Everyone,
> 
> I'm seeing some weird memory corruption that I have been able to isolate
> to arch_ptrace() [arch/powerpc/kernel/ptrace.c] and PTRACE_POKEUSR. I am
> on PowerPC 32 (MPC8378), kernel 4.9.179.
> 
> It's not very easy for me to test on the latest kernel, but I guess
> little has changed since 4.9 in either the architecture specific ptrace
> code or PowerPC register data structures.
> 
> What happens is that gdb calls ptrace(PTRACE_POKEUSER) with addr=0x158.
> This goes down to arch_ptrace() [arch/powerpc/kernel/ptrace.c], inside
> `case PTRACE_POKEUSR`, on the branch that does this:
> 
>      memcpy(&child->thread.TS_FPR(fpidx), &data,
>              sizeof(long));
> 
> where:
>      index = addr >> 2 = 0x56 = 86
>      fpidx = index - PT_FPR0 = 86 - 48 = 38

In struct thread_fp_state, fpr field is u64, so I guess we should have 
the following on PPC32:

fpidx = (index - PT_FPR0) >> 1;

Christophe

>      &child->thread.TS_FPR(fpidx) = (void *)child + 1296
> 
>      offsetof(struct task_struct, thread) = 960
>      sizeof(struct thread_struct) = 336
>      sizeof(struct task_struct) = 1296
> 
> In other words, the memcpy() call writes just beyond thread_struct
> (which is also beyond task_struct, for that matter).
> 
> This should never get past the bounds checks for `index`, so perhaps
> there is a mismatch between ptrace macros and the actual register data
> structures layout.
> 
> I will continue to investigate, but I'm not familiar with the PowerPC
> registers so it will take a while before I make sense of all the data
> structures and macros. Hopefully this rings a bell to someone who is
> already familiar with those and could figure out quickly what the
> problem is.
> 
> Best regards,
> Radu Rendec
> 


More information about the Linuxppc-dev mailing list