From patchwork Sun Mar 25 03:40:24 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Li Wang X-Patchwork-Id: 890605 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=lists.linux.it (client-ip=213.254.12.146; helo=picard.linux.it; envelope-from=ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from picard.linux.it (picard.linux.it [213.254.12.146]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40832h3cczz9s0W for ; Sun, 25 Mar 2018 14:40:41 +1100 (AEDT) Received: from picard.linux.it (localhost [IPv6:::1]) by picard.linux.it (Postfix) with ESMTP id 261043E65AE for ; Sun, 25 Mar 2018 05:40:35 +0200 (CEST) X-Original-To: ltp@lists.linux.it Delivered-To: ltp@picard.linux.it Received: from in-4.smtp.seeweb.it (in-4.smtp.seeweb.it [217.194.8.4]) by picard.linux.it (Postfix) with ESMTP id 38FB13E64F9 for ; Sun, 25 Mar 2018 05:40:33 +0200 (CEST) Received: from mx1.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by in-4.smtp.seeweb.it (Postfix) with ESMTPS id 266391000965 for ; Sun, 25 Mar 2018 05:40:30 +0200 (CEST) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id DF832A1BD4; Sun, 25 Mar 2018 03:40:28 +0000 (UTC) Received: from dhcp-12-102.nay.redhat.com (unknown [10.66.12.102]) by smtp.corp.redhat.com (Postfix) with ESMTP id E96A72023233; Sun, 25 Mar 2018 03:40:26 +0000 (UTC) From: Li Wang To: ltp@lists.linux.it Date: Sun, 25 Mar 2018 11:40:24 +0800 Message-Id: <20180325034024.31743-1-liwang@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Sun, 25 Mar 2018 03:40:28 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Sun, 25 Mar 2018 03:40:28 +0000 (UTC) for IP:'10.11.54.4' DOMAIN:'int-mx04.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'liwang@redhat.com' RCPT:'' X-Virus-Scanned: clamav-milter 0.99.2 at in-4.smtp.seeweb.it X-Virus-Status: Clean X-Spam-Status: No, score=-0.0 required=7.0 tests=SPF_PASS, T_RP_MATCHES_RCVD autolearn=disabled version=3.4.0 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on in-4.smtp.seeweb.it Cc: Michael Ellerman , Ram Pai Subject: [LTP] [PATCH] mprotect04: get the right function entry of big endian powerpc system X-BeenThere: ltp@lists.linux.it X-Mailman-Version: 2.1.18 Precedence: list List-Id: Linux Test Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it Sender: "ltp" 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 Signed-off-by: Ram Pai Signed-off-by: Li Wang CC: Michael Ellerman --- testcases/kernel/syscalls/mprotect/mprotect04.c | 34 ++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) 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 @@ -35,6 +35,7 @@ #include #include #include +#include #include "test.h" #include "safe_macros.h" @@ -56,6 +57,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) { @@ -189,6 +191,14 @@ static void clear_cache(void *start, int len) #endif } +#if (defined (__powerpc__) || (__powerpc64__)) && __BYTE_ORDER == __BIG_ENDIAN +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 +207,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; +#if (defined (__powerpc__) || (__powerpc64__)) && __BYTE_ORDER == __BIG_ENDIAN + 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 +248,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 +256,13 @@ static void testfunc_protexec(void) p = SAFE_MMAP(cleanup, 0, copy_sz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); +#if (defined (__powerpc__) || (__powerpc64__)) && __BYTE_ORDER == __BIG_ENDIAN + 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));