All of lore.kernel.org
 help / color / mirror / Atom feed
* [LTP] [PATCH v2] mprotect04: get right function entry if system using function descriptors
@ 2018-03-26  6:48 Li Wang
  2018-03-26  6:52 ` Li Wang
  0 siblings, 1 reply; 3+ messages in thread
From: Li Wang @ 2018-03-26  6:48 UTC (permalink / raw)
  To: ltp

On some big endian powerpc64 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>
Suggested-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Li Wang <liwang@redhat.com>
---
 testcases/kernel/syscalls/mprotect/mprotect04.c | 41 ++++++++++++++++++++++---
 1 file changed, 37 insertions(+), 4 deletions(-)

diff --git a/testcases/kernel/syscalls/mprotect/mprotect04.c b/testcases/kernel/syscalls/mprotect/mprotect04.c
index 1173afd..60941a4 100644
--- a/testcases/kernel/syscalls/mprotect/mprotect04.c
+++ b/testcases/kernel/syscalls/mprotect/mprotect04.c
@@ -56,6 +56,7 @@ int TST_TOTAL = ARRAY_SIZE(testfunc);
 static volatile int sig_caught;
 static sigjmp_buf env;
 static unsigned int copy_sz;
+typedef void (*func_ptr_t)(void);
 
 int main(int ac, char **av)
 {
@@ -190,6 +191,22 @@ static void clear_cache(void *start, int len)
 }
 
 /*
+ * To check for the ABI version, because ppc64le can technically use
+ * function descriptors.
+ */
+#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
+
+/*
  * Copy page where &exec_func resides. Also try to copy subsequent page
  * in case exec_func is close to page boundary.
  */
@@ -197,11 +214,21 @@ static void *get_func(void *mem)
 {
 	uintptr_t page_sz = getpagesize();
 	uintptr_t page_mask = ~(page_sz - 1);
-	uintptr_t func_page_offset = (uintptr_t)&exec_func & (page_sz - 1);
-	void *func_copy_start = mem + func_page_offset;
-	void *page_to_copy = (void *)((uintptr_t)&exec_func & page_mask);
+	uintptr_t func_page_offset;
+	void *func_copy_start, *page_to_copy;
 	void *mem_start = mem;
 
+#ifdef USE_FUNCTION_DESCRIPTORS
+	func_descr_t *opd =  (func_descr_t *)&exec_func;
+	func_page_offset = (uintptr_t)opd->entry & (page_sz - 1);
+	func_copy_start = mem + func_page_offset;
+	page_to_copy = (void *)((uintptr_t)opd->entry & page_mask);
+#else
+	func_page_offset = (uintptr_t)&exec_func & (page_sz - 1);
+	func_copy_start = mem + func_page_offset;
+	page_to_copy = (void *)((uintptr_t)&exec_func & page_mask);
+#endif
+
 	/* copy 1st page, if it's not present something is wrong */
 	if (!page_present(page_to_copy)) {
 		tst_resm(TINFO, "exec_func: %p, page_to_copy: %p\n",
@@ -228,7 +255,7 @@ static void *get_func(void *mem)
 
 static void testfunc_protexec(void)
 {
-	void (*func)(void);
+	func_ptr_t func;
 	void *p;
 
 	sig_caught = 0;
@@ -236,7 +263,13 @@ static void testfunc_protexec(void)
 	p = SAFE_MMAP(cleanup, 0, copy_sz, PROT_READ | PROT_WRITE,
 		 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
 
+#ifdef USE_FUNCTION_DESCRIPTORS
+	func_descr_t opd;
+	opd.entry = (uintptr_t)get_func(p);
+	func = (func_ptr_t)&opd;
+#else
 	func = get_func(p);
+#endif
 
 	/* Change the protection to PROT_EXEC. */
 	TEST(mprotect(p, copy_sz, PROT_EXEC));
-- 
2.9.3


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [LTP] [PATCH v2] mprotect04: get right function entry if system using function descriptors
  2018-03-26  6:48 [LTP] [PATCH v2] mprotect04: get right function entry if system using function descriptors Li Wang
@ 2018-03-26  6:52 ` Li Wang
  2018-03-26 13:06   ` Jan Stancek
  0 siblings, 1 reply; 3+ messages in thread
From: Li Wang @ 2018-03-26  6:52 UTC (permalink / raw)
  To: ltp

Add CC'ing Michael Ellerman <mpe@ellerman.id.au>


On Mon, Mar 26, 2018 at 2:48 PM, Li Wang <liwang@redhat.com> wrote:

> On some big endian powerpc64 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>
> Suggested-by: Michael Ellerman <mpe@ellerman.id.au>
> Signed-off-by: Li Wang <liwang@redhat.com>
> ---
>  testcases/kernel/syscalls/mprotect/mprotect04.c | 41
> ++++++++++++++++++++++---
>  1 file changed, 37 insertions(+), 4 deletions(-)
>
> diff --git a/testcases/kernel/syscalls/mprotect/mprotect04.c
> b/testcases/kernel/syscalls/mprotect/mprotect04.c
> index 1173afd..60941a4 100644
> --- a/testcases/kernel/syscalls/mprotect/mprotect04.c
> +++ b/testcases/kernel/syscalls/mprotect/mprotect04.c
> @@ -56,6 +56,7 @@ int TST_TOTAL = ARRAY_SIZE(testfunc);
>  static volatile int sig_caught;
>  static sigjmp_buf env;
>  static unsigned int copy_sz;
> +typedef void (*func_ptr_t)(void);
>
>  int main(int ac, char **av)
>  {
> @@ -190,6 +191,22 @@ static void clear_cache(void *start, int len)
>  }
>
>  /*
> + * To check for the ABI version, because ppc64le can technically use
> + * function descriptors.
> + */
> +#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
> +
> +/*
>   * Copy page where &exec_func resides. Also try to copy subsequent page
>   * in case exec_func is close to page boundary.
>   */
> @@ -197,11 +214,21 @@ static void *get_func(void *mem)
>  {
>         uintptr_t page_sz = getpagesize();
>         uintptr_t page_mask = ~(page_sz - 1);
> -       uintptr_t func_page_offset = (uintptr_t)&exec_func & (page_sz - 1);
> -       void *func_copy_start = mem + func_page_offset;
> -       void *page_to_copy = (void *)((uintptr_t)&exec_func & page_mask);
> +       uintptr_t func_page_offset;
> +       void *func_copy_start, *page_to_copy;
>         void *mem_start = mem;
>
> +#ifdef USE_FUNCTION_DESCRIPTORS
> +       func_descr_t *opd =  (func_descr_t *)&exec_func;
> +       func_page_offset = (uintptr_t)opd->entry & (page_sz - 1);
> +       func_copy_start = mem + func_page_offset;
> +       page_to_copy = (void *)((uintptr_t)opd->entry & page_mask);
> +#else
> +       func_page_offset = (uintptr_t)&exec_func & (page_sz - 1);
> +       func_copy_start = mem + func_page_offset;
> +       page_to_copy = (void *)((uintptr_t)&exec_func & page_mask);
> +#endif
> +
>         /* copy 1st page, if it's not present something is wrong */
>         if (!page_present(page_to_copy)) {
>                 tst_resm(TINFO, "exec_func: %p, page_to_copy: %p\n",
> @@ -228,7 +255,7 @@ static void *get_func(void *mem)
>
>  static void testfunc_protexec(void)
>  {
> -       void (*func)(void);
> +       func_ptr_t func;
>         void *p;
>
>         sig_caught = 0;
> @@ -236,7 +263,13 @@ static void testfunc_protexec(void)
>         p = SAFE_MMAP(cleanup, 0, copy_sz, PROT_READ | PROT_WRITE,
>                  MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
>
> +#ifdef USE_FUNCTION_DESCRIPTORS
> +       func_descr_t opd;
> +       opd.entry = (uintptr_t)get_func(p);
> +       func = (func_ptr_t)&opd;
> +#else
>         func = get_func(p);
> +#endif
>
>         /* Change the protection to PROT_EXEC. */
>         TEST(mprotect(p, copy_sz, PROT_EXEC));
> --
> 2.9.3
>
>
> --
> Mailing list info: https://lists.linux.it/listinfo/ltp
>



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

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [LTP] [PATCH v2] mprotect04: get right function entry if system using function descriptors
  2018-03-26  6:52 ` Li Wang
@ 2018-03-26 13:06   ` Jan Stancek
  0 siblings, 0 replies; 3+ messages in thread
From: Jan Stancek @ 2018-03-26 13:06 UTC (permalink / raw)
  To: ltp



----- Original Message -----
> Add CC'ing Michael Ellerman < mpe@ellerman.id.au >
> 
> 
> On Mon, Mar 26, 2018 at 2:48 PM, Li Wang < liwang@redhat.com > wrote:
> 
> 
> On some big endian powerpc64 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 >
> Suggested-by: Michael Ellerman < mpe@ellerman.id.au >
> Signed-off-by: Li Wang < liwang@redhat.com >

Added indentation to strace output so it doesn't confuse git
and pushed.

Thanks,
Jan

> ---
> testcases/kernel/syscalls/mprotect/mprotect04.c | 41
> ++++++++++++++++++++++---
> 1 file changed, 37 insertions(+), 4 deletions(-)
> 
> diff --git a/testcases/kernel/syscalls/mprotect/mprotect04.c
> b/testcases/kernel/syscalls/mprotect/mprotect04.c
> index 1173afd..60941a4 100644
> --- a/testcases/kernel/syscalls/mprotect/mprotect04.c
> +++ b/testcases/kernel/syscalls/mprotect/mprotect04.c
> @@ -56,6 +56,7 @@ int TST_TOTAL = ARRAY_SIZE(testfunc);
> static volatile int sig_caught;
> static sigjmp_buf env;
> static unsigned int copy_sz;
> +typedef void (*func_ptr_t)(void);
> 
> int main(int ac, char **av)
> {
> @@ -190,6 +191,22 @@ static void clear_cache(void *start, int len)
> }
> 
> /*
> + * To check for the ABI version, because ppc64le can technically use
> + * function descriptors.
> + */
> +#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
> +
> +/*
> * Copy page where &exec_func resides. Also try to copy subsequent page
> * in case exec_func is close to page boundary.
> */
> @@ -197,11 +214,21 @@ static void *get_func(void *mem)
> {
> uintptr_t page_sz = getpagesize();
> uintptr_t page_mask = ~(page_sz - 1);
> - uintptr_t func_page_offset = (uintptr_t)&exec_func & (page_sz - 1);
> - void *func_copy_start = mem + func_page_offset;
> - void *page_to_copy = (void *)((uintptr_t)&exec_func & page_mask);
> + uintptr_t func_page_offset;
> + void *func_copy_start, *page_to_copy;
> void *mem_start = mem;
> 
> +#ifdef USE_FUNCTION_DESCRIPTORS
> + func_descr_t *opd = (func_descr_t *)&exec_func;
> + func_page_offset = (uintptr_t)opd->entry & (page_sz - 1);
> + func_copy_start = mem + func_page_offset;
> + page_to_copy = (void *)((uintptr_t)opd->entry & page_mask);
> +#else
> + func_page_offset = (uintptr_t)&exec_func & (page_sz - 1);
> + func_copy_start = mem + func_page_offset;
> + page_to_copy = (void *)((uintptr_t)&exec_func & page_mask);
> +#endif
> +
> /* copy 1st page, if it's not present something is wrong */
> if (!page_present(page_to_copy)) {
> tst_resm(TINFO, "exec_func: %p, page_to_copy: %p\n",
> @@ -228,7 +255,7 @@ static void *get_func(void *mem)
> 
> static void testfunc_protexec(void)
> {
> - void (*func)(void);
> + func_ptr_t func;
> void *p;
> 
> sig_caught = 0;
> @@ -236,7 +263,13 @@ static void testfunc_protexec(void)
> p = SAFE_MMAP(cleanup, 0, copy_sz, PROT_READ | PROT_WRITE,
> MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
> 
> +#ifdef USE_FUNCTION_DESCRIPTORS
> + func_descr_t opd;
> + opd.entry = (uintptr_t)get_func(p);
> + func = (func_ptr_t)&opd;
> +#else
> func = get_func(p);
> +#endif
> 
> /* Change the protection to PROT_EXEC. */
> TEST(mprotect(p, copy_sz, PROT_EXEC));
> --
> 2.9.3
> 
> 
> --
> Mailing list info: https://lists.linux.it/listinfo/ltp
> 
> 
> 
> --
> Li Wang
> liwang@redhat.com
> 
> 
> --
> Mailing list info: https://lists.linux.it/listinfo/ltp
> 

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2018-03-26 13:06 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-26  6:48 [LTP] [PATCH v2] mprotect04: get right function entry if system using function descriptors Li Wang
2018-03-26  6:52 ` Li Wang
2018-03-26 13:06   ` Jan Stancek

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.