[LTP] [PATCH] mprotect04: get the right function entry of big endian powerpc system

Li Wang liwang@redhat.com
Mon Mar 26 08:40:14 CEST 2018


On Mon, Mar 26, 2018 at 8:27 AM, Michael Ellerman <mpe@ellerman.id.au>
wrote:

> Li Wang <liwang@redhat.com> writes:
>
> > On Big endian powerpc ABI, function ptrs are basically pointers to
> > function descriptors. The testcase copies functions which results
> > in function descriptors getting copied. So easily the access was
> > denied by memory protection key in that address when performing it.
> >
> > 10000000-10020000 r-xp 00000000 fd:00 167223           mprotect04
> > 10020000-10030000 r--p 00010000 fd:00 167223           mprotect04
> > 10030000-10040000 rw-p 00020000 fd:00 167223           mprotect04
> > 1001a380000-1001a3b0000 rw-p 00000000 00:00 0          [heap]
> > 7fffa6c60000-7fffa6c80000 --xp 00000000 00:00 0
> >
> > &exec_func = 0x10030170
> > &func = 0x7fffa6c60170
> >
> > While perform the (*func)(); we get segmentation fault.
> >
> > strace log:
> > -----------
> > mprotect(0x7fffaed00000, 131072, PROT_EXEC) = 0
> > rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
> > --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_PKUERR,
> si_addr=0x7fffaed00170} ---
> >
> > Reported-and-tested-by: Li Wang <liwang@redhat.com>
> > Signed-off-by: Ram Pai <linuxram@us.ibm.com>
> > Signed-off-by: Li Wang <liwang@redhat.com>
> > CC: Michael Ellerman <mpe@ellerman.id.au>
>
> Thanks for fixing this.
>
> Some comments below ...
>
> > diff --git a/testcases/kernel/syscalls/mprotect/mprotect04.c
> b/testcases/kernel/syscalls/mprotect/mprotect04.c
> > index 1173afd..5705cb0 100644
> > --- a/testcases/kernel/syscalls/mprotect/mprotect04.c
> > +++ b/testcases/kernel/syscalls/mprotect/mprotect04.c
> > @@ -189,6 +191,14 @@ static void clear_cache(void *start, int len)
> >  #endif
> >  }
> >
> > +#if (defined (__powerpc__) || (__powerpc64__)) && __BYTE_ORDER ==
> __BIG_ENDIAN
>
> That's not quite the right condition.
>
> 32-bit powerpc big endian doesn't use function descriptors, but your
> check for __powerpc__ will match on 32-bit.


> Also the check for __powerpc64__ is missing defined().
>
> So this would work:
>
>   #if defined(__powerpc64__) && __BYTE_ORDER == __BIG_ENDIAN
>
> More correct would be to check for the ABI version, because ppc64le can
> technically use function descriptors (it just doesn't in any
> configuration you're likely to see).
>

​
​Thanks for your correction, very detail and clear. I'd like to take use of
it in PATCH V2 directly.​
​


>
> That would be:
>
>   #if defined(__powerpc64__) && (!defined(_CALL_ELF) || _CALL_ELF < 2)
>
> Given you need that in a few places you should probably make it a
> define, eg:
>
>   #if defined(__powerpc64__) && (!defined(_CALL_ELF) || _CALL_ELF < 2)
>   #define USE_FUNCTION_DESCRIPTORS
>   #endif
>
>   #ifdef USE_FUNCTION_DESCRIPTORS
>   typedef struct {
>         uintptr_t entry;
>         uintptr_t toc;
>         uintptr_t env;
>   } func_descr_t;
>   #endif
>
>
> cheers
>
>


-- 
Li Wang
liwang@redhat.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linux.it/pipermail/ltp/attachments/20180326/6e9b40f7/attachment.html>


More information about the ltp mailing list